commit e4c030b0c09d674098238f6e9c80056e050517e8 Author: ekko.bao Date: Tue May 13 22:00:58 2025 +0800 初始提交 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1fbbfdc --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +*.a +*.so +*.bin +output +bootloader +libs_url +open_source +temp +utils +ws63-liteos_all +tools +services +ace_engine +kernel +protocol +interim_binary +middleware +include +drivers diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..4e0ce4e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,123 @@ +#=============================================================================== +# @brief cmake entry +# Copyright (c) CompanyNameMagicTag 2022-2022. All rights reserved. +#=============================================================================== +cmake_minimum_required(VERSION 3.14.1) +set(CMAKE_SYSTEM_NAME "Generic") + +if(NOT DEFINED CHIP) + message(FATAL_ERROR "Chip is not defined ") +endif() + +set(Python3_EXECUTABLE ${PY_PATH}) +find_program(CCACHE_FOUND ccache) +if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) +endif(CCACHE_FOUND) + +# default hso module_name & AUTO_DEF_FILE_ID & AUTO_DEF_MODULE_ID, redefine these var in sub cmake file will +# override these value just in sub directory but not others +set(MODULE_NAME "pf") +set(AUTO_DEF_FILE_ID TRUE) +set(AUTO_DEF_MODULE_ID TRUE) + +set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) +get_filename_component(ROOT_DIR "${PROJECT_SOURCE_DIR}" ABSOLUTE) +set(CMAKE_DIR "${ROOT_DIR}/build/cmake") +set(BIN_DIR "${ROOT_DIR}/interim_binary") + +include("${CMAKE_DIR}/build_function.cmake") +include("${CMAKE_DIR}/global_variable.cmake") +include("${CMAKE_DIR}/build_script.cmake") +include("${CMAKE_DIR}/build_command.cmake") +include("${CMAKE_DIR}/build_hso_database.cmake") +include("${CMAKE_DIR}/build_component.cmake") +include("${CMAKE_DIR}/build_sdk.cmake") + +if(${BUILD_TYPE} STREQUAL "UT") + KCONFIG_GET_PARAMS("${ROOT_DIR}/build/menuconfig/test/platform/ut.config") + include("${CMAKE_DIR}/build_ut.cmake") + return() +endif() + +if(${BUILD_TYPE} STREQUAL "FUZZ") + KCONFIG_GET_PARAMS("${ROOT_DIR}/build/menuconfig/test/platform/ut.config") + include("${CMAKE_DIR}/build_fuzz.cmake") + return() +endif() + +project(${CHIP}_CFBB C ASM CXX) +set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "") + +if(EXISTS ${CMAKE_BINARY_DIR}/auto_gen_libfunc.lds) + file(REMOVE ${CMAKE_BINARY_DIR}/auto_gen_libfunc.lds) +endif() + +set(TARGET_COMPONENT "${RAM_COMPONENT}" "${ROM_COMPONENT}") +set(TARGET_NAME ${BIN_NAME}) +file(WRITE ${PROJECT_BINARY_DIR}/temp/__null___.c "int __null___(void) {return 0;}") +add_executable(${BIN_NAME} ${PROJECT_BINARY_DIR}/temp/__null___.c) +set_target_properties(${BIN_NAME} PROPERTIES RUNTIME_OUTPUT_NAME ${BIN_NAME}.elf) +target_compile_options(${BIN_NAME} PRIVATE "${CCFLAGS}") + +include("${CMAKE_DIR}/build_rom_callback.cmake") +if(${BUILD_ROM_CALLBACK}) + build_rom_callback() +endif() + +set(KCONFIG_PATH "${ROOT_DIR}/build/config/target_config/${CHIP}/menuconfig/${CORE}/${BUILD_TARGET_NAME}.config") +if(EXISTS ${KCONFIG_PATH}) + KCONFIG_GET_PARAMS(${KCONFIG_PATH}) + set(USE_KCONFIG True) +endif() + +add_subdirectory_if_exist(application) +add_subdirectory_if_exist(bt) +add_subdirectory_if_exist(bootloader) +add_subdirectory_if_exist(kernel) +add_subdirectory_if_exist(drivers) +add_subdirectory_if_exist(middleware) +add_subdirectory_if_exist(open_source) +add_subdirectory_if_exist(protocol) +add_subdirectory_if_exist(test) +add_subdirectory_if_exist(include) +add_subdirectory_if_exist(vendor) + +include("${CMAKE_DIR}/open_source.cmake") +include("${CMAKE_DIR}/build_linker.cmake") + +if (NOT DEFINED ROM_COMPONENT) +add_custom_target(GENERAT_BIN ALL + COMMAND ${CMAKE_OBJCOPY} --gap-fill 0xFF -O binary -R .fls_loader_ram -R .logstr -R .ARM -R .ARM ${BIN_NAME}.elf ${BIN_NAME}.bin + COMMENT "post_build:gen bin file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${TARGET_NAME} +) +else() +add_custom_target(GENERAT_BIN ALL + COMMAND ${CMAKE_OBJCOPY} --gap-fill 0xFF -O binary -R .logstr -R .ARM.exidx -R .ARM.extab -R .*_romtext ${TARGET_NAME}.elf ${TARGET_NAME}.bin + COMMAND ${CMAKE_OBJCOPY} --gap-fill 0xFF -O binary -j .*_romtext ${TARGET_NAME}.elf ${TARGET_NAME}_rom.bin + COMMENT "post_build:gen rom and ram bin file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${TARGET_NAME} +) +endif() + +if(DEFINED CONFIG_SFC_SUPPORT_RWE_INDEPENDENT) +add_custom_target(GENERAT_FLASH_DRIVER_BIN ALL + COMMAND ${CMAKE_OBJCOPY} -O srec --srec-len=0x20 --srec-forceS3 -S -j .fls_loader_ram ${BIN_NAME}.elf BOOTLOADERFlsDrv.signed.s19 + COMMENT "post_build:gen flash driver bin file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${TARGET_NAME} +) +endif() + +include("${CMAKE_DIR}/build_ssb.cmake") +include("${CMAKE_DIR}/build_elf_info.cmake") +include("${CMAKE_DIR}/build_sign.cmake") +include("${CMAKE_DIR}/build_nv_bin.cmake") +include("${CMAKE_DIR}/build_partition_bin.cmake") +include("${CMAKE_DIR}/build_boot_bin_cp.cmake") + +create_hso_db() +generate_project_file() diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt new file mode 100755 index 0000000..481d086 --- /dev/null +++ b/application/CMakeLists.txt @@ -0,0 +1,26 @@ +#=============================================================================== +# @brief cmake make file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(battery) +add_subdirectory_if_exist(brandy_demo) +add_subdirectory_if_exist(charger) +add_subdirectory_if_exist(dut) +add_subdirectory_if_exist(monitor) +add_subdirectory_if_exist(ota) +add_subdirectory_if_exist(samples) +add_subdirectory_if_exist(ux) +add_subdirectory_if_exist(wstp) +add_subdirectory_if_exist(cfbb) + +if("${CHIP}" STREQUAL "socmn1") + add_subdirectory_if_exist(melody) +else() + add_subdirectory_if_exist(${CHIP}) +endif() + +if("${CHIP}" STREQUAL "socmn1" OR "${CHIP}" STREQUAL "brandy") + add_subdirectory_if_exist(audio) +endif() + +add_subdirectory_if_exist(wearable) diff --git a/application/Kconfig b/application/Kconfig new file mode 100755 index 0000000..5e74d70 --- /dev/null +++ b/application/Kconfig @@ -0,0 +1,15 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + +config SAMPLE_ENABLE + bool + prompt "Enable Sample." + default n + help + This option means support Samples. + +if SAMPLE_ENABLE +osource "application/samples/Kconfig" +endif diff --git a/application/samples/CMakeLists.txt b/application/samples/CMakeLists.txt new file mode 100755 index 0000000..d770661 --- /dev/null +++ b/application/samples/CMakeLists.txt @@ -0,0 +1,71 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "samples") + +set(SOURCES +) + +set(PUBLIC_HEADER +) + +if(DEFINED CONFIG_ENABLE_BT_SAMPLE) + add_subdirectory_if_exist(bt) +endif() +if(DEFINED CONFIG_ENABLE_PERIPHERAL_SAMPLE) + add_subdirectory_if_exist(peripheral) +endif() +if(DEFINED CONFIG_ENABLE_WIFI_SAMPLE) + add_subdirectory_if_exist(wifi) +endif() +if(DEFINED CONFIG_ENABLE_PRODUCTS_SAMPLE) + add_subdirectory_if_exist(products) +endif() +if(DEFINED CONFIG_ENABLE_RADAR_SAMPLE) + add_subdirectory_if_exist(radar) +endif() +if(DEFINED CONFIG_ENABLE_NFC_SAMPLE) + add_subdirectory_if_exist(nfc) +endif() + +add_subdirectory_if_exist(custom) + +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES +) + +set(PUBLIC_DEFINES +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + false +) + +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/peripheral" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/products" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/wifi/sta_sample" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/wifi/alilink_sample" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/wifi/softap_sample" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/wifi/ohos_connect" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/wifi/hilink_indie_upgrade" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/wifi/ble_wifi_cfg_sample" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/radar" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/nfc" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/bt/ble" "*") +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}/bt/sle" "*") + +build_component() diff --git a/application/samples/Kconfig b/application/samples/Kconfig new file mode 100755 index 0000000..88d9a8b --- /dev/null +++ b/application/samples/Kconfig @@ -0,0 +1,76 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + +config ENABLE_BT_SAMPLE + bool + prompt "Enable the Sample of BT." + default n + depends on SAMPLE_ENABLE + help + This option means enable the sample of BT. + +if ENABLE_BT_SAMPLE +osource "application/samples/bt/Kconfig" +endif + +config ENABLE_PERIPHERAL_SAMPLE + bool + prompt "Enable the Sample of peripheral." + default n + depends on SAMPLE_ENABLE + help + This option means enable the sample of peripheral. + +if ENABLE_PERIPHERAL_SAMPLE +osource "application/samples/peripheral/Kconfig" +endif + +config ENABLE_WIFI_SAMPLE + bool + prompt "Enable the Sample of WIFI." + default n + depends on SAMPLE_ENABLE + help + This option means enable the sample of WIFI. + +if ENABLE_WIFI_SAMPLE +osource "application/samples/wifi/Kconfig" +endif + +config ENABLE_PRODUCTS_SAMPLE + bool + prompt "Enable the Sample of products." + default n + depends on SAMPLE_ENABLE + help + This option means enable the sample of products. + +if ENABLE_PRODUCTS_SAMPLE +osource "application/samples/products/Kconfig" +endif + +config ENABLE_RADAR_SAMPLE + bool + prompt "Enable the Sample of RADAR." + default n + depends on SAMPLE_ENABLE + help + This option means enable the sample of RADAR. + +if ENABLE_RADAR_SAMPLE +osource "application/samples/radar/Kconfig" +endif + +config ENABLE_NFC_SAMPLE + bool + prompt "Enable the Sample of NFC." + default n + depends on SAMPLE_ENABLE + help + This option means enable the sample of NFC. + +if ENABLE_NFC_SAMPLE +osource "application/samples/nfc/Kconfig" +endif diff --git a/application/samples/bt/CMakeLists.txt b/application/samples/bt/CMakeLists.txt new file mode 100755 index 0000000..28ecd9f --- /dev/null +++ b/application/samples/bt/CMakeLists.txt @@ -0,0 +1,13 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_SAMPLE) + add_subdirectory_if_exist(ble) +endif() +if(DEFINED CONFIG_SAMPLE_SUPPORT_SLE_SAMPLE) + add_subdirectory_if_exist(sle) +endif() + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/Kconfig b/application/samples/bt/Kconfig new file mode 100755 index 0000000..85305f0 --- /dev/null +++ b/application/samples/bt/Kconfig @@ -0,0 +1,21 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +choice + prompt "Sample" + +config SAMPLE_SUPPORT_BLE_SAMPLE + bool "Support BLE Sample." + +if SAMPLE_SUPPORT_BLE_SAMPLE +osource "application/samples/bt/ble/Kconfig" +endif + +config SAMPLE_SUPPORT_SLE_SAMPLE + bool "Support SLE Sample." + +if SAMPLE_SUPPORT_SLE_SAMPLE +osource "application/samples/bt/sle/Kconfig" +endif +endchoice \ No newline at end of file diff --git a/application/samples/bt/ble/CMakeLists.txt b/application/samples/bt/ble/CMakeLists.txt new file mode 100755 index 0000000..5a2249d --- /dev/null +++ b/application/samples/bt/ble/CMakeLists.txt @@ -0,0 +1,27 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_GATT_CLIENT_SAMPLE) + add_subdirectory_if_exist(ble_gatt_client) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_GATT_SERVER_SAMPLE) + add_subdirectory_if_exist(ble_gatt_server) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_SPEED_SERVER_SAMPLE) + add_subdirectory_if_exist(ble_speed_server) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_SPEED_CLIENT_SAMPLE) + add_subdirectory_if_exist(ble_speed_client) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_CFG_SAMPLE) + add_subdirectory_if_exist(ble_wifi_cfg_client) + add_subdirectory_if_exist(ble_wifi_cfg_server) +endif() + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/ble/Kconfig b/application/samples/bt/ble/Kconfig new file mode 100755 index 0000000..37b21b9 --- /dev/null +++ b/application/samples/bt/ble/Kconfig @@ -0,0 +1,24 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + +choice + prompt "BLE Sample" + +config SAMPLE_SUPPORT_BLE_GATT_CLIENT_SAMPLE + bool "Support BLE GATT Client Sample." + +config SAMPLE_SUPPORT_BLE_GATT_SERVER_SAMPLE + bool "Support BLE GATT Server Sample." + +config SAMPLE_SUPPORT_BLE_SPEED_SERVER_SAMPLE + bool "Support BLE Throughput Server Sample." + +config SAMPLE_SUPPORT_BLE_SPEED_CLIENT_SAMPLE + bool "Support BLE Throughput Client Sample" + +config SAMPLE_SUPPORT_BLE_CFG_SAMPLE + bool "Support BLE WIFI CFG Sample" + +endchoice \ No newline at end of file diff --git a/application/samples/bt/ble/ble_gatt_client/CMakeLists.txt b/application/samples/bt/ble/ble_gatt_client/CMakeLists.txt new file mode 100755 index 0000000..be2e0bc --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_client/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/ble/ble_gatt_client/inc/ble_gatt_client.h b/application/samples/bt/ble/ble_gatt_client/inc/ble_gatt_client.h new file mode 100755 index 0000000..2dbb792 --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_client/inc/ble_gatt_client.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * + * Description: BT GATT Client Moudle. + */ + +/** + * @defgroup bluetooth_bts_hid_server HID SERVER API + * @ingroup + * @{ + */ +#ifndef BLE_GATT_CLIENT_H +#define BLE_GATT_CLIENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @if Eng + * @brief Use this funtion to init gatt client. + * @par Description:init gatt client. + * @attention NULL + * @param NULL + * @retval error code. + * @else + * @brief 初始化gatt 客户端。 + * @par 说明:初始化gatt 客户端。 + * @attention NULL + * @param NULL + * @retval 执行结果错误码。 + * @endif + */ +errcode_t ble_gatt_client_init(void); + +/** + * @if Eng + * @brief discover all service, character and descriptor of remote device. + * @par Description:discover all service of remote device. + * @attention NULL + * @param conn_id connection ID + * @retval error code. + * @else + * @brief 发现对端设备所有服务、特征和描述符。 + * @par 说明:发现对端设备所有服务、特征和描述符。 + * @attention NULL + * @param conn_id 连接 ID + * @retval 执行结果错误码。 + * @endif + */ +errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id); + +/** + * @} + */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/application/samples/bt/ble/ble_gatt_client/src/CMakeLists.txt b/application/samples/bt/ble/ble_gatt_client/src/CMakeLists.txt new file mode 100755 index 0000000..d54b6a0 --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_client/src/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/ble_gatt_client.c" PARENT_SCOPE) diff --git a/application/samples/bt/ble/ble_gatt_client/src/ble_gatt_client.c b/application/samples/bt/ble/ble_gatt_client/src/ble_gatt_client.c new file mode 100755 index 0000000..1776ef5 --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_client/src/ble_gatt_client.c @@ -0,0 +1,277 @@ +#include "osal_list.h" +#include "bts_le_gap.h" +#include "bts_gatt_client.h" +#include "soc_osal.h" +#include "app_init.h" +#include "securec.h" +#include "common_def.h" + +#define UUID16_LEN 2 +#define DEFAULT_SCAN_INTERVAL 0x48 + +/* client id, invalid client id is "0" */ +uint8_t g_client_id = 0; +/* client app uuid for test */ +static bt_uuid_t g_client_app_uuid = {UUID16_LEN, {0}}; + +errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id); + +static void ble_gatt_client_discover_service_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_service_result_t *service, errcode_t status) +{ + gattc_discovery_character_param_t param = {0}; + osal_printk("[GATTClient]Discovery service----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" start handle:%d end handle:%d uuid_len:%d\n uuid:", + service->start_hdl, service->end_hdl, service->uuid.uuid_len); + for (uint8_t i = 0; i < service->uuid.uuid_len; i++) { + osal_printk("%02x", service->uuid.uuid[i]); + } + osal_printk("\n status:%d\n", status); + param.service_handle = service->start_hdl; + param.uuid.uuid_len = 0; /* uuid length is zero, discover all character */ + gattc_discovery_character(g_client_id, conn_id, ¶m); +} + +static void ble_gatt_client_discover_character_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_character_result_t *character, errcode_t status) +{ + osal_printk("[GATTClient]Discovery character----client:%d conn_id:%d uuid_len:%d\n uuid:", + client_id, conn_id, character->uuid.uuid_len); + for (uint8_t i = 0; i < character->uuid.uuid_len; i++) { + osal_printk("%02x", character->uuid.uuid[i]); + } + osal_printk("\n declare handle:%d value handle:%d properties:%x\n", character->declare_handle, + character->value_handle, character->properties); + osal_printk(" status:%d\n", status); + gattc_discovery_descriptor(g_client_id, conn_id, character->declare_handle); +} + +static void ble_gatt_client_discover_descriptor_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_descriptor_result_t *descriptor, errcode_t status) +{ + osal_printk("[GATTClient]Discovery descriptor----client:%d conn_id:%d uuid len:%d\n uuid:", + client_id, conn_id, descriptor->uuid.uuid_len); + for (uint8_t i = 0; i < descriptor->uuid.uuid_len; i++) { + osal_printk("%02x", descriptor->uuid.uuid[i]); + } + osal_printk("\n descriptor handle:%d\n", descriptor->descriptor_hdl); + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_discover_service_compl_cbk(uint8_t client_id, uint16_t conn_id, bt_uuid_t *uuid, + errcode_t status) +{ + osal_printk( + "[GATTClient]Discovery service complete----client:%d conn_id:%d uuid len:%d\n uuid:", + client_id, conn_id, uuid->uuid_len); + for (uint8_t i = 0; i < uuid->uuid_len; i++) { + osal_printk("%02x", uuid->uuid[i]); + } + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_discover_character_compl_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_character_param_t *param, errcode_t status) +{ + osal_printk( + "[GATTClient]Discovery character complete----client:%d conn_id:%d uuid len:%d\n uuid:", + client_id, conn_id, param->uuid.uuid_len); + for (uint8_t i = 0; i < param->uuid.uuid_len; i++) { + osal_printk("%02x", param->uuid.uuid[i]); + } + osal_printk("\n service handle:%d\n", param->service_handle); + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_discover_descriptor_compl_cbk(uint8_t client_id, uint16_t conn_id, + uint16_t character_handle, errcode_t status) +{ + osal_printk("[GATTClient]Discovery descriptor complete----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" charatcer handle:%d\n", character_handle); + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *read_result, + gatt_status_t status) +{ + osal_printk("[GATTClient]Read result----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" handle:%d data_len:%d\ndata:", read_result->handle, read_result->data_len); + for (uint8_t i = 0; i < read_result->data_len; i++) { + osal_printk("%02x", read_result->data[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_gatt_client_read_compl_cbk(uint8_t client_id, uint16_t conn_id, gattc_read_req_by_uuid_param_t *param, + errcode_t status) +{ + osal_printk("[GATTClient]Read by uuid complete----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk("start handle:%d end handle:%d uuid len:%d\n uuid:", + param->start_hdl, param->end_hdl, param->uuid.uuid_len); + for (uint8_t i = 0; i < param->uuid.uuid_len; i++) { + osal_printk("%02x", param->uuid.uuid[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_gatt_client_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, uint16_t handle, gatt_status_t status) +{ + osal_printk("[GATTClient]Write result----client:%d conn_id:%d handle:%d\n", client_id, conn_id, handle); + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_mtu_changed_cbk(uint8_t client_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status) +{ + osal_printk("[GATTClient]Mtu changed----client:%d conn_id:%d mtu size:%d\n", client_id, conn_id, + mtu_size); + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_notification_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data, + errcode_t status) +{ + osal_printk("[GATTClient]Receive notification----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk("handle:%d data_len:%d\ndata:", data->handle, data->data_len); + for (uint8_t i = 0; i < data->data_len; i++) { + osal_printk("%02x", data->data[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_gatt_client_indication_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data, + errcode_t status) +{ + osal_printk("[GATTClient]Receive indication----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" handle:%d data_len:%d\ndata:", data->handle, data->data_len); + for (uint8_t i = 0; i < data->data_len; i++) { + osal_printk("%02x", data->data[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_gatt_client_scan_result_cbk(gap_scan_result_data_t *scan_result_data) +{ + uint8_t ble_mac[BD_ADDR_LEN] = {0x63, 0x38, 0xce, 0xad, 0x38, 0x63}; + if (memcmp(scan_result_data->addr.addr, ble_mac, BD_ADDR_LEN) == 0) { + osal_printk("Find The Target Device.\n"); + gap_ble_stop_scan(); + bd_addr_t client_addr = { 0 }; + client_addr.type = scan_result_data->addr.type; + if (memcpy_s(client_addr.addr, BD_ADDR_LEN, scan_result_data->addr.addr, BD_ADDR_LEN) != EOK) { + osal_printk("%s add server app addr memcpy failed\r\n", __FUNCTION__); + return; + } + gap_ble_connect_remote_device(&client_addr); + } else { + osal_printk("\naddr:"); + for (uint8_t i = 0; i < BD_ADDR_LEN; i++) { + osal_printk(" %02x:", scan_result_data->addr.addr[i]); + } + } +} + +static void ble_gatt_client_conn_state_change_cbk(uint16_t conn_id, bd_addr_t *addr, + gap_ble_conn_state_t conn_state, gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason) +{ + osal_printk("%s connect state change conn_id: %d, status: %d, pair_status:%d, disc_reason %x\n", + __FUNCTION__, conn_id, conn_state, pair_state, disc_reason); + + if (conn_state == GAP_BLE_STATE_CONNECTED) { + gap_ble_pair_remote_device(addr); + } +} + +static void ble_gatt_client_pair_result_cbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status) +{ + unused(addr); + osal_printk("%s pair result conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status); + + ble_gatt_client_discover_all_service(conn_id); +} + +static void ble_gatt_client_conn_param_update_cbk(uint16_t conn_id, errcode_t status, + const gap_ble_conn_param_update_t *param) +{ + osal_printk("%s conn_param_update conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status); + osal_printk("interval:%d latency:%d timeout:%d.\n", param->interval, param->latency, param->timeout); +} + +errcode_t ble_gatt_client_callback_register(void) +{ + errcode_t ret = ERRCODE_BT_UNHANDLED; + gap_ble_callbacks_t gap_cb = {0}; + gap_cb.scan_result_cb = ble_gatt_client_scan_result_cbk; + gap_cb.conn_state_change_cb = ble_gatt_client_conn_state_change_cbk; + gap_cb.pair_result_cb = ble_gatt_client_pair_result_cbk; + gap_cb.conn_param_update_cb = ble_gatt_client_conn_param_update_cbk; + ret |= gap_ble_register_callbacks(&gap_cb); + + gattc_callbacks_t cb = {0}; + cb.discovery_svc_cb = ble_gatt_client_discover_service_cbk; + cb.discovery_svc_cmp_cb = ble_gatt_client_discover_service_compl_cbk; + cb.discovery_chara_cb = ble_gatt_client_discover_character_cbk; + cb.discovery_chara_cmp_cb = ble_gatt_client_discover_character_compl_cbk; + cb.discovery_desc_cb = ble_gatt_client_discover_descriptor_cbk; + cb.discovery_desc_cmp_cb = ble_gatt_client_discover_descriptor_compl_cbk; + cb.read_cb = ble_gatt_client_read_cfm_cbk; + cb.read_cmp_cb = ble_gatt_client_read_compl_cbk; + cb.write_cb = ble_gatt_client_write_cfm_cbk; + cb.mtu_changed_cb = ble_gatt_client_mtu_changed_cbk; + cb.notification_cb = ble_gatt_client_notification_cbk; + cb.indication_cb = ble_gatt_client_indication_cbk; + ret |= gattc_register_callbacks(&cb); + return ret; +} + +errcode_t ble_cliant_start_scan(void) +{ + errcode_t ret = ERRCODE_BT_SUCCESS; + gap_ble_scan_params_t ble_device_scan_params = { 0 }; + ble_device_scan_params.scan_interval = DEFAULT_SCAN_INTERVAL; + ble_device_scan_params.scan_window = DEFAULT_SCAN_INTERVAL; + ble_device_scan_params.scan_type = 0x00; + ble_device_scan_params.scan_phy = GAP_BLE_PHY_2M; + ble_device_scan_params.scan_filter_policy = 0x00; + ret |= gap_ble_set_scan_parameters(&ble_device_scan_params); + ret |= gap_ble_start_scan(); + return ret; +} + +errcode_t ble_gatt_client_init(void) +{ + errcode_t ret = ERRCODE_BT_SUCCESS; + ret |= enable_ble(); + ret |= ble_gatt_client_callback_register(); + ret |= gattc_register_client(&g_client_app_uuid, &g_client_id); + printf("ble_gatt_client_init, ret:%x.\n", ret); + ret |= ble_cliant_start_scan(); + printf("ble_cliant_start_scan, ret:%x.\n", ret); + return ret; +} + +errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id) +{ + errcode_t ret = ERRCODE_BT_SUCCESS; + bt_uuid_t service_uuid = {0}; /* uuid length is zero, discover all service */ + ret |= gattc_discovery_service(g_client_id, conn_id, &service_uuid); + return ret; +} + +#define BLE_UUID_CLIENT_TASK_PRIO 24 +#define BLE_UUID_CLIENT_STACK_SIZE 0x2000 + +static void ble_uuid_client_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle= osal_kthread_create((osal_kthread_handler)ble_gatt_client_init, 0, "ble_gatt_client", + BLE_UUID_CLIENT_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, BLE_UUID_CLIENT_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the app entry. */ +app_run(ble_uuid_client_entry); \ No newline at end of file diff --git a/application/samples/bt/ble/ble_gatt_server/CMakeLists.txt b/application/samples/bt/ble/ble_gatt_server/CMakeLists.txt new file mode 100755 index 0000000..be2e0bc --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_server/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/ble/ble_gatt_server/inc/ble_gatt_server.h b/application/samples/bt/ble/ble_gatt_server/inc/ble_gatt_server.h new file mode 100755 index 0000000..aab7931 --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_server/inc/ble_gatt_server.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * + * Description: BLE UUID Server module. + */ + +/** + * @defgroup bluetooth_bts_hid_server HID SERVER API + * @ingroup + * @{ + */ +#ifndef BLE_UUID_SERVER_H +#define BLE_UUID_SERVER_H + +#include "bts_def.h" + +/* Service UUID */ +#define BLE_UUID_UUID_SERVER_SERVICE 0xABCD +/* Characteristic UUID */ +#define BLE_UUID_UUID_SERVER_REPORT 0xCDEF +/* Client Characteristic Configuration UUID */ +#define BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION 0x2902 +/* Server ID */ +#define BLE_UUID_SERVER_ID 1 + +/* Characteristic Property */ +#define UUID_SERVER_PROPERTIES (GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY) + +/** + * @if Eng + * @brief BLE uuid server inir. + * @attention NULL + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief BLE UUID服务器初始化。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +errcode_t ble_uuid_server_init(void); + +/** + * @if Eng + * @brief send data to peer device by uuid on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +errcode_t ble_uuid_server_send_report_by_uuid(const uint8_t *data, uint8_t len); + +/** + * @if Eng + * @brief send data to peer device by handle on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +errcode_t ble_uuid_server_send_report_by_handle(uint16_t attr_handle, const uint8_t *data, uint8_t len); + +#endif + diff --git a/application/samples/bt/ble/ble_gatt_server/inc/ble_server_adv.h b/application/samples/bt/ble/ble_gatt_server/inc/ble_server_adv.h new file mode 100755 index 0000000..052a6d3 --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_server/inc/ble_server_adv.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * + * Description: BLE ADV Config. + */ + +/** + * @defgroup bluetooth_bts_ble_adv API + * @ingroup + * @{ + */ +#ifndef BLE_SERVER_ADV_H +#define BLE_SERVER_ADV_H + +#include "bts_def.h" + +/* Ble Adv type Flag length */ +#define BLE_ADV_FLAG_LEN 0x03 +/* Ble Adv data length */ +#define BLE_GENERAL_BYTE_1 1 +/* Ble Adv appearance length */ +#define BLE_ADV_APPEARANCE_LENGTH 4 +/* Ble Adv appearance type */ +#define BLE_ADV_APPEARANCE_DATA_TYPE 0x19 +/* Ble keyboard appearance type */ +#define BLE_ADV_CATEGORY_KEYBOARD_VALUE 0x0080 +/* Ble keyboard categorylength */ +#define BLE_ADV_CATEGORY_LEN 2 +/* Ble name adv param type length */ +#define BLE_ADV_PARAM_DATATYPE_LENGTH 1 +/* Ble name adv name type */ +#define BLE_ADV_LOCAL_NAME_DATA_TYPE 0x09 +/* Ble name adv tx power type */ +#define BLE_ADV_TX_POWER_LEVEL 0x0A +/* Ble name adv tx power response type */ +#define BLE_SCAN_RSP_TX_POWER_LEVEL_LEN 0x03 +/* Ble adv flag data */ +#define BLE_ADV_FLAG_DATA 0x05 + +/** + * @if Eng + * @brief Definitaion of BLE ADV data flag. + * @else + * @brief BLE 广播数据类型定义。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv data flag length. + @else 广播数据类型长度 */ + uint8_t adv_data_type; /*!< @if Eng adv data type. + @else 广播数据类型 */ + uint8_t flags; /*!< @if Eng adv data flag. + @else 广播数据标志 */ +} ble_adv_flag; + +/** + * @if Eng + * @brief Definitaion of BLE device appearance struct. + * @else + * @brief BLE 广播设备外观结构。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv appearance data length. + @else 设备外观数据类型长度 */ + uint8_t adv_data_type; /*!< @if Eng adv appearance data type. + @else 设备外观数据类型 */ + uint8_t catogory_id[BLE_ADV_CATEGORY_LEN]; /*!< @if Eng adv appearance data. + @else 设备外观数据 */ +} ble_appearance_st; + +/** + * @if Eng + * @brief Definitaion of BLE device name. + * @else + * @brief BLE 广播设备名称。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv device name length. + @else 广播设备名称类型长度 */ + uint8_t adv_data_type; /*!< @if Eng adv name data type. + @else 设备名称类型 */ + int8_t *name; /*!< @if Eng adv name data. + @else 设备名称数据指针 */ +} ble_local_name_st; + +/** + * @if Eng + * @brief Definitaion of BLE Tx power. + * @else + * @brief BLE 广播发送功率。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv tx power length. + @else 广播发送功率长度 */ + uint8_t adv_data_type; /*!< @if Eng adv tx power type. + @else 广播发送数据类型 */ + uint8_t tx_power_value; /*!< @if Eng adv tx power value. + @else 广播发送数据 */ +} ble_tx_power_level_st; + +/** + * @if Eng + * @brief Definitaion value range for typedef struct ble_adv_para.adv_filter_policy. + * @else + * @brief Ble adv filter policy定义值范围。 + * @endif + */ +typedef enum ble_adv_filter_policy { + BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_ANY = 0x00, + BLE_ADV_FILTER_POLICY_SCAN_WHITE_LIST_CONNECT_ANY = 0x01, + BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_WHITE_LIST = 0x02, + BLE_ADV_FILTER_POLICY_SCAN_WHITE_LIST_CONNECT_WHITE_LIST = 0x03 +} ble_adv_filter_policy_t; + +/** + * @if Eng + * @brief Definitaion value range for adv type. + * @else + * @brief Ble adv 类型范围。 + * @endif + */ +typedef enum ble_adverting_type { + BLE_ADV_TYPE_CONNECTABLE_UNDIRECTED = 0x00, + BLE_ADV_TYPE_CONNECTABLE_HIGH_DUTY_CYCLE_DIRECTED = 0x01, + BLE_ADV_TYPE_SCANNABLE_UNDIRECTED = 0x02, + BLE_ADV_TYPE_NON_CONNECTABLE_UNDIRECTED = 0x03, + BLE_ADV_TYPE_CONNECTABLE_LOW_DUTY_CYCLE_DIRECTED = 0x04 +} ble_adverting_type_t; + + +/** + * @if Eng + * @brief Definitaion value range for adv channel map. + * @else + * @brief Ble 广播信道范围。 + * @endif + */ +typedef enum ble_adv_channel_map { + BLE_ADV_CHANNEL_MAP_CH_37 = 0x01, + BLE_ADV_CHANNEL_MAP_CH_38 = 0x02, + BLE_ADV_CHANNEL_MAP_CH_39 = 0x04, + BLE_ADV_CHANNEL_MAP_CH_37_CH_38 = 0x03, + BLE_ADV_CHANNEL_MAP_CH_37_CH_39 = 0x05, + BLE_ADV_CHANNEL_MAP_CH_38_CH_39 = 0x06, + BLE_ADV_CHANNEL_MAP_CH_DEFAULT = 0x07 +} ble_adv_channel_map_t; + +/** + * @if Eng + * @brief Definitaion value range for adv addr type. + * @else + * @brief Ble 广播地址类型。 + * @endif + */ +typedef enum { + BLE_PUBLIC_DEVICE_ADDRESS = 0x00, + BLE_RANDOM_DEVICE_ADDRESS = 0x01, + BLE_PUBLIC_IDENTITY_ADDRESS = 0x02, + BLE_RANDOM_STATIC_IDENTITY_ADDRESS = 0x03 +} ble_address_type; + +/* Ble adv min interval */ +#define BLE_ADV_MIN_INTERVAL 0x30 +/* Ble adv max interval */ +#define BLE_ADV_MAX_INTERVAL 0x60 +/* Ble adv handle */ +#define BTH_GAP_BLE_ADV_HANDLE_DEFAULT 0x01 +/* Ble adv duration */ +#define BTH_GAP_BLE_ADV_FOREVER_DURATION 0 + +/** + * @if Eng + * @brief Enable BLE adv. + * @attention NULL + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief 使能BLE广播。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +uint8_t ble_start_adv(void); + +/** + * @if Eng + * @brief BLE adv data config. + * @attention NULL + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief BLE广播数据配置。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +uint8_t ble_set_adv_data(void); +#endif + diff --git a/application/samples/bt/ble/ble_gatt_server/src/CMakeLists.txt b/application/samples/bt/ble/ble_gatt_server/src/CMakeLists.txt new file mode 100755 index 0000000..29ed99f --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_server/src/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/ble_server_adv.c" + "${CMAKE_CURRENT_SOURCE_DIR}/ble_gatt_server.c" + PARENT_SCOPE) diff --git a/application/samples/bt/ble/ble_gatt_server/src/ble_gatt_server.c b/application/samples/bt/ble/ble_gatt_server/src/ble_gatt_server.c new file mode 100755 index 0000000..2bbc214 --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_server/src/ble_gatt_server.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * Description: ble uuid server sample. + */ + +#include +#include +#include +#include +#include "osal_addr.h" +#include "bts_def.h" +#include "securec.h" +#include "errcode.h" +#include "bts_def.h" +#include "bts_le_gap.h" +#include "bts_gatt_stru.h" +#include "bts_gatt_server.h" +#include "soc_osal.h" +#include "app_init.h" +#include "ble_server_adv.h" +#include "ble_gatt_server.h" + +/* server app uuid for test */ +char g_uuid_app_uuid[] = {0x0, 0x0}; + +/* ble indication att handle */ +uint16_t g_indication_characteristic_att_hdl = 0; + +/* ble notification att handle */ +uint16_t g_notification_characteristic_att_hdl = 0; + +/* ble connect handle */ +uint16_t g_conn_hdl = 0; + +/* ble server id */ +uint8_t g_server_id = 0; + +#define OCTET_BIT_LEN 8 +#define UUID_LEN_2 2 + +/* 将uint16的uuid数字转化为bt_uuid_t */ +void stream_data_to_uuid(uint16_t uuid_data, bt_uuid_t *out_uuid) +{ + char uuid[] = {(uint8_t)(uuid_data >> OCTET_BIT_LEN), (uint8_t)uuid_data}; + out_uuid->uuid_len = UUID_LEN_2; + if (memcpy_s(out_uuid->uuid, out_uuid->uuid_len, uuid, UUID_LEN_2) != EOK) { + return; + } +} + +errcode_t compare_service_uuid(bt_uuid_t *uuid1, bt_uuid_t *uuid2) +{ + if (uuid1->uuid_len != uuid2->uuid_len) { + return ERRCODE_BT_FAIL; + } + if (memcmp(uuid1->uuid, uuid2->uuid, uuid1->uuid_len) != 0) { + return ERRCODE_BT_FAIL; + } + return ERRCODE_BT_SUCCESS; +} + +/* 添加描述符:客户端特性配置 */ +static void ble_uuid_server_add_descriptor_ccc(uint32_t server_id, uint32_t srvc_handle) +{ + bt_uuid_t ccc_uuid = {0}; + uint8_t ccc_data_val[] = {0x00, 0x00}; + + osal_printk("[uuid server] beginning add descriptors\r\n"); + stream_data_to_uuid(BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION, &ccc_uuid); + gatts_add_desc_info_t descriptor; + descriptor.desc_uuid = ccc_uuid; + descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; + descriptor.value_len = sizeof(ccc_data_val); + descriptor.value = ccc_data_val; + gatts_add_descriptor(server_id, srvc_handle, &descriptor); + osal_vfree(ccc_uuid.uuid); +} + +/* 添加HID服务的所有特征和描述符 */ +static void ble_uuid_server_add_characters_and_descriptors(uint32_t server_id, uint32_t srvc_handle) +{ + bt_uuid_t server_uuid = {0}; + uint8_t server_value[] = {0x12, 0x34}; + osal_printk("[uuid server] beginning add characteristic\r\n"); + stream_data_to_uuid(BLE_UUID_UUID_SERVER_REPORT, &server_uuid); + gatts_add_chara_info_t character; + character.chara_uuid = server_uuid; + character.properties = UUID_SERVER_PROPERTIES; + character.permissions = 0; + character.value_len = sizeof(server_value); + character.value = server_value; + gatts_add_characteristic(server_id, srvc_handle, &character); + ble_uuid_server_add_descriptor_ccc(server_id, srvc_handle); +} + +/* 服务添加回调 */ +static void ble_uuid_server_service_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t handle, errcode_t status) +{ + bt_uuid_t service_uuid = {0}; + osal_printk("[uuid server] add service cbk: server: %d, status: %d, srv_handle: %d, uuid_len: %d,uuid:", + server_id, status, handle, uuid->uuid_len); + for (int8_t i = 0; i < uuid->uuid_len ; i++) { + osal_printk("%02x", (uint8_t)uuid->uuid[i]); + } + osal_printk("\n"); + stream_data_to_uuid(BLE_UUID_UUID_SERVER_SERVICE, &service_uuid); + if (compare_service_uuid(uuid, &service_uuid) == ERRCODE_BT_SUCCESS) { + ble_uuid_server_add_characters_and_descriptors(server_id, handle); + osal_printk("[uuid server] start service\r\n"); + gatts_start_service(server_id, handle); + } else { + osal_printk("[uuid server] unknown service uuid\r\n"); + return; + } +} + +/* 特征添加回调 */ +static void ble_uuid_server_characteristic_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t service_handle, + gatts_add_character_result_t *result, errcode_t status) +{ + int8_t i = 0; + osal_printk("[uuid server] add characteristic cbk: server: %d, status: %d, srv_hdl: %d "\ + "char_hdl: %x, char_val_hdl: %x, uuid_len: %d, uuid: ", + server_id, status, service_handle, result->handle, result->value_handle, uuid->uuid_len); + for (i = 0; i < uuid->uuid_len ; i++) { + osal_printk("%02x", (uint8_t)uuid->uuid[i]); + } + osal_printk("\n"); + g_notification_characteristic_att_hdl = result->value_handle; +} + +/* 描述符添加回调 */ +static void ble_uuid_server_descriptor_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t service_handle, + uint16_t handle, errcode_t status) +{ + int8_t i = 0; + osal_printk("[uuid server] add descriptor cbk : server: %d, status: %d, srv_hdl: %d, desc_hdl: %x ,"\ + "uuid_len:%d, uuid: ", server_id, status, service_handle, handle, uuid->uuid_len); + for (i = 0; i < uuid->uuid_len ; i++) { + osal_printk("%02x", (uint8_t)uuid->uuid[i]); + } + osal_printk("\n"); +} + +/* 开始服务回调 */ +static void ble_uuid_server_service_start_cbk(uint8_t server_id, uint16_t handle, errcode_t status) +{ + osal_printk("[uuid server] start service cbk : server: %d status: %d srv_hdl: %d\n", + server_id, status, handle); +} + +static void ble_uuid_server_receive_write_req_cbk(uint8_t server_id, uint16_t conn_id, + gatts_req_write_cb_t *write_cb_para, errcode_t status) +{ + osal_printk("[uuid server]ReceiveWriteReqCallback--server_id:%d conn_id:%d\n", server_id, conn_id); + osal_printk("request_id:%d att_handle:%d offset:%d need_rsp:%d need_authorize:%d is_prep:%d\n", + write_cb_para->request_id, write_cb_para->handle, write_cb_para->offset, write_cb_para->need_rsp, + write_cb_para->need_authorize, write_cb_para->is_prep); + osal_printk("data_len:%d data:\n", write_cb_para->length); + for (uint8_t i = 0; i < write_cb_para->length; i++) { + osal_printk("%02x ", write_cb_para->value[i]); + } + osal_printk("\n"); + osal_printk("status:%d\n", status); +} + +static void ble_uuid_server_receive_read_req_cbk(uint8_t server_id, uint16_t conn_id, + gatts_req_read_cb_t *read_cb_para, errcode_t status) +{ + osal_printk("[uuid server]ReceiveReadReq--server_id:%d conn_id:%d\n", server_id, conn_id); + osal_printk("request_id:%d att_handle:%d offset:%d need_rsp:%d need_authorize:%d is_long:%d\n", + read_cb_para->request_id, read_cb_para->handle, read_cb_para->offset, read_cb_para->need_rsp, + read_cb_para->need_authorize, read_cb_para->is_long); + osal_printk("status:%d\n", status); +} + +static void ble_uuid_server_adv_enable_cbk(uint8_t adv_id, adv_status_t status) +{ + osal_printk("adv enable adv_id: %d, status:%d\n", adv_id, status); +} + +static void ble_uuid_server_adv_disable_cbk(uint8_t adv_id, adv_status_t status) +{ + osal_printk("adv disable adv_id: %d, status:%d\n", + adv_id, status); +} + + +void ble_uuid_server_connect_change_cbk(uint16_t conn_id, bd_addr_t *addr, gap_ble_conn_state_t conn_state, + gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason) +{ + osal_printk("connect state change conn_id: %d, status: %d, pair_status:%d, addr %x disc_reason %x\n", + conn_id, conn_state, pair_state, addr[0], disc_reason); + g_conn_hdl = conn_id; + + if (conn_state == GAP_BLE_STATE_DISCONNECTED) { + gap_ble_start_adv(BTH_GAP_BLE_ADV_HANDLE_DEFAULT); + } +} + +void ble_uuid_server_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status) +{ + osal_printk("mtu change change server_id: %d, conn_id: %d, mtu_size: %d, status:%d \n", + server_id, conn_id, mtu_size, status); +} + +void ble_uuid_server_enable_cbk(errcode_t status) +{ + osal_printk("enable status: %d\n", status); +} + +static errcode_t ble_uuid_server_register_callbacks(void) +{ + errcode_t ret; + gap_ble_callbacks_t gap_cb = {0}; + gatts_callbacks_t service_cb = {0}; + + gap_cb.start_adv_cb = ble_uuid_server_adv_enable_cbk; + gap_cb.stop_adv_cb = ble_uuid_server_adv_disable_cbk; + gap_cb.conn_state_change_cb = ble_uuid_server_connect_change_cbk; + gap_cb.ble_enable_cb = ble_uuid_server_enable_cbk; + ret = gap_ble_register_callbacks(&gap_cb); + if (ret != ERRCODE_BT_SUCCESS) { + osal_printk("[uuid server] reg gap cbk failed\r\n"); + return ERRCODE_BT_FAIL; + } + + service_cb.add_service_cb = ble_uuid_server_service_add_cbk; + service_cb.add_characteristic_cb = ble_uuid_server_characteristic_add_cbk; + service_cb.add_descriptor_cb = ble_uuid_server_descriptor_add_cbk; + service_cb.start_service_cb = ble_uuid_server_service_start_cbk; + service_cb.read_request_cb = ble_uuid_server_receive_read_req_cbk; + service_cb.write_request_cb = ble_uuid_server_receive_write_req_cbk; + service_cb.mtu_changed_cb = ble_uuid_server_mtu_changed_cbk; + ret = gatts_register_callbacks(&service_cb); + if (ret != ERRCODE_BT_SUCCESS) { + osal_printk("[uuid server] reg service cbk failed\r\n"); + return ERRCODE_BT_FAIL; + } + return ret; +} + +uint8_t ble_uuid_add_service(void) +{ + osal_printk("[uuid server] ble uuid add service in\r\n"); + bt_uuid_t service_uuid = {0}; + stream_data_to_uuid(BLE_UUID_UUID_SERVER_SERVICE, &service_uuid); + gatts_add_service(g_server_id, &service_uuid, true); + osal_printk("[uuid server] ble uuid add service out\r\n"); + return ERRCODE_BT_SUCCESS; +} + +/* 初始化uuid server service */ +errcode_t ble_uuid_server_init(void) +{ + enable_ble(); + ble_uuid_server_register_callbacks(); + bt_uuid_t app_uuid = {0}; + app_uuid.uuid_len = sizeof(g_uuid_app_uuid); + if (memcpy_s(app_uuid.uuid, app_uuid.uuid_len, g_uuid_app_uuid, sizeof(g_uuid_app_uuid)) != EOK) { + return ERRCODE_BT_FAIL; + } + gatts_register_server(&app_uuid, &g_server_id); + ble_uuid_add_service(); + osal_printk("[uuid server] init ok\r\n"); + ble_start_adv(); + return ERRCODE_BT_SUCCESS; +} + +/* device通过uuid向host发送数据:report */ +errcode_t ble_uuid_server_send_report_by_uuid(const uint8_t *data, uint8_t len) +{ + gatts_ntf_ind_by_uuid_t param = {0}; + uint16_t conn_id = g_conn_hdl; + param.start_handle = 0; + param.end_handle = 0xffff; + stream_data_to_uuid(BLE_UUID_UUID_SERVER_REPORT, ¶m.chara_uuid); + param.value_len = len; + param.value = osal_vmalloc(len); + if (param.value == NULL) { + osal_printk("[hid][ERROR]send report new fail\r\n"); + return ERRCODE_BT_FAIL; + } + if (memcpy_s(param.value, param.value_len, data, len) != EOK) { + osal_printk("[hid][ERROR]send input report memcpy fail\r\n"); + osal_vfree(param.value); + return ERRCODE_BT_FAIL; + } + gatts_notify_indicate_by_uuid(g_server_id, conn_id, ¶m); + osal_vfree(param.value); + return ERRCODE_BT_SUCCESS; +} + +/* device通过handle向host发送数据:report */ +errcode_t ble_uuid_server_send_report_by_handle(uint16_t attr_handle, const uint8_t *data, uint8_t len) +{ + gatts_ntf_ind_t param = {0}; + uint16_t conn_id = g_conn_hdl; + + param.attr_handle = attr_handle; + param.value = osal_vmalloc(len); + param.value_len = len; + + if (param.value == NULL) { + osal_printk("[hid][ERROR]send report new fail\r\n"); + return ERRCODE_BT_FAIL; + } + if (memcpy_s(param.value, param.value_len, data, len) != EOK) { + osal_printk("[hid][ERROR]send input report memcpy fail\r\n"); + osal_vfree(param.value); + return ERRCODE_BT_FAIL; + } + gatts_notify_indicate(g_server_id, conn_id, ¶m); + osal_vfree(param.value); + return ERRCODE_BT_SUCCESS; +} + +#define BLE_UUID_SERVER_TASK_PRIO 24 +#define BLE_UUID_SERVER_STACK_SIZE 0x2000 + +static void ble_uuid_server_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle= osal_kthread_create((osal_kthread_handler)ble_uuid_server_init, 0, "ble_uuid_server", + BLE_UUID_SERVER_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, BLE_UUID_SERVER_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the app entry. */ +app_run(ble_uuid_server_entry); \ No newline at end of file diff --git a/application/samples/bt/ble/ble_gatt_server/src/ble_server_adv.c b/application/samples/bt/ble/ble_gatt_server/src/ble_server_adv.c new file mode 100755 index 0000000..92fc782 --- /dev/null +++ b/application/samples/bt/ble/ble_gatt_server/src/ble_server_adv.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: adv config for ble uuid server. + */ +#include +#include +#include +#include +#include "osal_addr.h" +#include "securec.h" +#include "errcode.h" +#include "bts_def.h" +#include "bts_le_gap.h" +#include "ble_server_adv.h" + +#define NAME_MAX_LENGTH 15 +#define EXT_ADV_OR_SCAN_RSP_DATA_LEN 251 +#define u16_low_u8(val) ((uint8_t)((uint16_t)(val) & 0xff)) +#define u16_high_u8(val) ((uint8_t)(((uint16_t)(val) >> 8) & 0xff)) + +uint8_t g_local_name[ NAME_MAX_LENGTH] = { 'b', 'l', 'e', '_', 'u', 'u', 'i', 'd', '_', 's', + 'e', 'r', 'v', 'e', 'r' }; + +static uint8_t ble_set_adv_flag_data(uint8_t *set_adv_data_position, uint8_t max_len) +{ + errno_t n_ret; + + ble_adv_flag adv_flags = { + .length = BLE_ADV_FLAG_LEN - BLE_GENERAL_BYTE_1, + .adv_data_type = 1, + .flags = BLE_ADV_FLAG_DATA, + }; + n_ret = memcpy_s(set_adv_data_position, max_len, &adv_flags, BLE_ADV_FLAG_LEN); + if (n_ret != EOK) { + return 0; + } + return BLE_ADV_FLAG_LEN; +} + +static uint8_t ble_set_adv_appearance(uint8_t *set_adv_data_position, uint8_t max_len) +{ + errno_t n_ret; + ble_appearance_st adv_appearance_data = { + .length = BLE_ADV_APPEARANCE_LENGTH - BLE_GENERAL_BYTE_1, + .adv_data_type = BLE_ADV_APPEARANCE_DATA_TYPE, + .catogory_id = { u16_low_u8(BLE_ADV_CATEGORY_KEYBOARD_VALUE), u16_high_u8(BLE_ADV_CATEGORY_KEYBOARD_VALUE) }, + }; + n_ret = memcpy_s(set_adv_data_position, max_len, &adv_appearance_data, BLE_ADV_APPEARANCE_LENGTH); + if (n_ret != EOK) { + return 0; + } + return BLE_ADV_APPEARANCE_LENGTH; +} + +static uint8_t ble_set_adv_name(uint8_t *set_adv_data_position, uint8_t max_len) +{ + errno_t n_ret; + uint8_t len; + ble_local_name_st adv_local_name_data = { 0 }; + adv_local_name_data.length = (uint8_t)(BLE_ADV_PARAM_DATATYPE_LENGTH + sizeof(g_local_name)); + adv_local_name_data.adv_data_type = BLE_ADV_LOCAL_NAME_DATA_TYPE; + len = BLE_ADV_PARAM_DATATYPE_LENGTH + BLE_ADV_PARAM_DATATYPE_LENGTH; + n_ret = memcpy_s(set_adv_data_position, max_len, &adv_local_name_data, len); + if (n_ret != EOK) { + return 0; + } + n_ret = memcpy_s((set_adv_data_position + len), (size_t)(max_len - len), g_local_name, sizeof(g_local_name)); + if (n_ret != EOK) { + return 0; + } + len = (uint8_t)(len + sizeof(g_local_name)); + return len; +} + +static uint8_t ble_set_adv_appearance_data(uint8_t *set_adv_data_position, uint8_t max_len) +{ + uint8_t idx = 0; + idx += ble_set_adv_appearance(set_adv_data_position, max_len); + idx += ble_set_adv_name(set_adv_data_position + idx, (max_len - idx)); + return idx; +} + +static uint16_t ble_uuid_server_set_adv_data(uint8_t *set_adv_data, uint8_t adv_data_max_len) +{ + uint8_t idx = 0; + + if ((set_adv_data == NULL) || (adv_data_max_len == 0)) { + return 0; + } + idx += ble_set_adv_flag_data(set_adv_data, adv_data_max_len); + idx += ble_set_adv_appearance_data(&set_adv_data[idx], adv_data_max_len - idx); + return idx; +} + +static uint16_t ble_set_scan_response_data(uint8_t *scan_rsp_data, uint8_t scan_rsp_data_max_len) +{ + uint8_t idx = 0; + errno_t n_ret; + + if (scan_rsp_data == NULL) { + return 0; + } + if (scan_rsp_data_max_len == 0) { + return 0; + } + + /* tx power level */ + ble_tx_power_level_st tx_power_level = { + .length = BLE_SCAN_RSP_TX_POWER_LEVEL_LEN - BLE_GENERAL_BYTE_1, + .adv_data_type = BLE_ADV_TX_POWER_LEVEL, + .tx_power_value = 0, + }; + + n_ret = memcpy_s(scan_rsp_data, scan_rsp_data_max_len, &tx_power_level, sizeof(ble_tx_power_level_st)); + if (n_ret != EOK) { + return 0; + } + idx += BLE_SCAN_RSP_TX_POWER_LEVEL_LEN; + + /* set local name */ + scan_rsp_data[idx++] = sizeof(g_local_name) + BLE_GENERAL_BYTE_1; + scan_rsp_data[idx++] = BLE_ADV_LOCAL_NAME_DATA_TYPE; + if ((idx + sizeof(g_local_name)) > scan_rsp_data_max_len) { + return 0; + } + n_ret = memcpy_s(&scan_rsp_data[idx], scan_rsp_data_max_len - idx, g_local_name, sizeof(g_local_name)); + if (n_ret != EOK) { + return 0; + } + idx += sizeof(g_local_name); + return idx; +} + +uint8_t ble_set_adv_data(void) +{ + errcode_t n_ret = 0; + uint16_t adv_data_len; + uint16_t scan_rsp_data_len; + uint8_t set_adv_data[EXT_ADV_OR_SCAN_RSP_DATA_LEN] = { 0 }; + uint8_t set_scan_rsp_data[EXT_ADV_OR_SCAN_RSP_DATA_LEN] = { 0 }; + gap_ble_config_adv_data_t cfg_adv_data; + + /* set adv data */ + adv_data_len = ble_uuid_server_set_adv_data(set_adv_data, EXT_ADV_OR_SCAN_RSP_DATA_LEN); + if ((adv_data_len > EXT_ADV_OR_SCAN_RSP_DATA_LEN) || (adv_data_len == 0)) { + return 0; + } + /* set scan response data */ + scan_rsp_data_len = ble_set_scan_response_data(set_scan_rsp_data, EXT_ADV_OR_SCAN_RSP_DATA_LEN); + if ((scan_rsp_data_len > EXT_ADV_OR_SCAN_RSP_DATA_LEN) || (scan_rsp_data_len == 0)) { + return 0; + } + cfg_adv_data.adv_data = set_adv_data; + cfg_adv_data.adv_length = adv_data_len; + + cfg_adv_data.scan_rsp_data = set_scan_rsp_data; + cfg_adv_data.scan_rsp_length = scan_rsp_data_len; + n_ret = gap_ble_set_adv_data(BTH_GAP_BLE_ADV_HANDLE_DEFAULT, &cfg_adv_data); + if (n_ret != 0) { + return 0; + } + return 0; +} + +uint8_t ble_start_adv(void) +{ + errcode_t n_ret = 0; + gap_ble_adv_params_t adv_para = {0}; + + ble_set_adv_data(); + + int adv_id = BTH_GAP_BLE_ADV_HANDLE_DEFAULT; + + adv_para.min_interval = BLE_ADV_MIN_INTERVAL; + adv_para.max_interval = BLE_ADV_MAX_INTERVAL; + adv_para.duration = BTH_GAP_BLE_ADV_FOREVER_DURATION; + adv_para.peer_addr.type = BLE_PUBLIC_DEVICE_ADDRESS; + /* 广播通道选择bitMap, 可参考BleAdvChannelMap */ + adv_para.channel_map = BLE_ADV_CHANNEL_MAP_CH_DEFAULT; + adv_para.adv_type = BLE_ADV_TYPE_CONNECTABLE_UNDIRECTED; + adv_para.adv_filter_policy = BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_ANY; + (void)memset_s(&adv_para.peer_addr.addr, BD_ADDR_LEN, 0, BD_ADDR_LEN); + n_ret = gap_ble_set_adv_param(adv_id, &adv_para); + if (n_ret != 0) { + return 0; + } + n_ret = gap_ble_start_adv(adv_id); + if (n_ret != 0) { + return 0; + } + return 0; +} diff --git a/application/samples/bt/ble/ble_speed_client/CMakeLists.txt b/application/samples/bt/ble/ble_speed_client/CMakeLists.txt new file mode 100755 index 0000000..be2e0bc --- /dev/null +++ b/application/samples/bt/ble/ble_speed_client/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/ble/ble_speed_client/inc/ble_speed_client.h b/application/samples/bt/ble/ble_speed_client/inc/ble_speed_client.h new file mode 100755 index 0000000..f42eeae --- /dev/null +++ b/application/samples/bt/ble/ble_speed_client/inc/ble_speed_client.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * + * Description: BLE SPEED Server module. + */ + +#ifndef BLE_SPEED_CLIENT_H +#define BLE_SPEED_CLIENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEFAULT_SCAN_INTERVAL 0x48 +#define DEFAULT_SCAN_INTERVAL 0x48 + +/** + * @if Eng + * @brief Use this funtion to init gatt client. + * @par Description:init gatt client. + * @attention NULL + * @param NULL + * @retval error code. + * @else + * @brief 初始化gatt 客户端。 + * @par 说明:初始化gatt 客户端。 + * @attention NULL + * @param NULL + * @retval 执行结果错误码。 + * @endif + */ +errcode_t ble_gatt_client_init(void); + +/** + * @if Eng + * @brief discover all service, character and descriptor of remote device. + * @par Description:discover all service of remote device. + * @attention NULL + * @param conn_id connection ID + * @retval error code. + * @else + * @brief 发现对端设备所有服务、特征和描述符。 + * @par 说明:发现对端设备所有服务、特征和描述符。 + * @attention NULL + * @param conn_id 连接 ID + * @retval 执行结果错误码。 + * @endif + */ +errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id); + +/** + * @} + */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/application/samples/bt/ble/ble_speed_client/src/CMakeLists.txt b/application/samples/bt/ble/ble_speed_client/src/CMakeLists.txt new file mode 100755 index 0000000..d7b5ddf --- /dev/null +++ b/application/samples/bt/ble/ble_speed_client/src/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/ble_speed_client.c" PARENT_SCOPE) diff --git a/application/samples/bt/ble/ble_speed_client/src/ble_speed_client.c b/application/samples/bt/ble/ble_speed_client/src/ble_speed_client.c new file mode 100755 index 0000000..46170c9 --- /dev/null +++ b/application/samples/bt/ble/ble_speed_client/src/ble_speed_client.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * Description: ble speed client sample. + */ + +#include +#include +#include +#include +#include "securec.h" +#include "app_init.h" +#include "systick.h" +#include "soc_osal.h" +#include "osal_list.h" +#include "common_def.h" + +#include "bts_le_gap.h" +#include "bts_gatt_client.h" +#include "ble_speed_client.h" + +#define UUID16_LEN 2 +#define TEMP_LINE_LEN 32 +static int g_recv_pkt_num = 0; +static uint64_t g_count_before_get_us; +static uint64_t g_count_after_get_us; +#define RECV_PKT_CNT 100 + +/* client id, invalid client id is "0" */ +static uint8_t g_client_id = 0; +/* client app uuid for test */ +static bt_uuid_t g_client_app_uuid = {UUID16_LEN, {0}}; + +bd_addr_t g_ble_speed_addr = { + .type = 0, + .addr = {0x11, 0x22, 0x33, 0x63, 0x88, 0x63}, +}; + +extern errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id); + +static void ble_gatt_client_discover_service_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_service_result_t *service, errcode_t status) +{ + gattc_discovery_character_param_t param = {0}; + osal_printk("[GATTClient]Discovery service----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" start handle:%d end handle:%d uuid_len:%d\n uuid:", + service->start_hdl, service->end_hdl, service->uuid.uuid_len); + for (uint8_t i = 0; i < service->uuid.uuid_len; i++) { + osal_printk("%02x", service->uuid.uuid[i]); + } + osal_printk("\n status:%d\n", status); + param.service_handle = service->start_hdl; + param.uuid.uuid_len = 0; /* uuid length is zero, discover all character */ + gattc_discovery_character(g_client_id, conn_id, ¶m); +} + +static void ble_gatt_client_discover_character_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_character_result_t *character, errcode_t status) +{ + osal_printk("[GATTClient]Discovery character----client:%d conn_id:%d uuid_len:%d\n uuid:", + client_id, conn_id, character->uuid.uuid_len); + for (uint8_t i = 0; i < character->uuid.uuid_len; i++) { + osal_printk("%02x", character->uuid.uuid[i]); + } + osal_printk("\n declare handle:%d value handle:%d properties:%x\n", character->declare_handle, + character->value_handle, character->properties); + osal_printk(" status:%d\n", status); + gattc_discovery_descriptor(g_client_id, conn_id, character->declare_handle); +} + +static void ble_gatt_client_discover_descriptor_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_descriptor_result_t *descriptor, errcode_t status) +{ + osal_printk("[GATTClient]Discovery descriptor----client:%d conn_id:%d uuid len:%d\n uuid:", + client_id, conn_id, descriptor->uuid.uuid_len); + for (uint8_t i = 0; i < descriptor->uuid.uuid_len; i++) { + osal_printk("%02x", descriptor->uuid.uuid[i]); + } + osal_printk("\n descriptor handle:%d\n", descriptor->descriptor_hdl); + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_discover_service_compl_cbk(uint8_t client_id, uint16_t conn_id, bt_uuid_t *uuid, + errcode_t status) +{ + osal_printk( + "[GATTClient]Discovery service complete----client:%d conn_id:%d uuid len:%d\n uuid:", + client_id, conn_id, uuid->uuid_len); + for (uint8_t i = 0; i < uuid->uuid_len; i++) { + osal_printk("%02x", uuid->uuid[i]); + } + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_discover_character_compl_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_character_param_t *param, errcode_t status) +{ + osal_printk( + "[GATTClient]Discovery character complete----client:%d conn_id:%d uuid len:%d\n uuid:", + client_id, conn_id, param->uuid.uuid_len); + for (uint8_t i = 0; i < param->uuid.uuid_len; i++) { + osal_printk("%02x", param->uuid.uuid[i]); + } + osal_printk("\n service handle:%d\n", param->service_handle); + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_discover_descriptor_compl_cbk(uint8_t client_id, uint16_t conn_id, + uint16_t character_handle, errcode_t status) +{ + osal_printk("[GATTClient]Discovery descriptor complete----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" charatcer handle:%d\n", character_handle); + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *read_result, + gatt_status_t status) +{ + osal_printk("[GATTClient]Read result----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" handle:%d data_len:%d\ndata:", read_result->handle, read_result->data_len); + for (uint8_t i = 0; i < read_result->data_len; i++) { + osal_printk("%02x", read_result->data[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_gatt_client_read_compl_cbk(uint8_t client_id, uint16_t conn_id, gattc_read_req_by_uuid_param_t *param, + errcode_t status) +{ + osal_printk("[GATTClient]Read by uuid complete----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk("start handle:%d end handle:%d uuid len:%d\n uuid:", + param->start_hdl, param->end_hdl, param->uuid.uuid_len); + for (uint8_t i = 0; i < param->uuid.uuid_len; i++) { + osal_printk("%02x", param->uuid.uuid[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_gatt_client_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, uint16_t handle, gatt_status_t status) +{ + osal_printk("[GATTClient]Write result----client:%d conn_id:%d handle:%d\n", client_id, conn_id, handle); + osal_printk(" status:%d\n", status); +} + +static void ble_gatt_client_mtu_changed_cbk(uint8_t client_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status) +{ + osal_printk("[GATTClient]Mtu changed----client:%d conn_id:%d mtu size:%d\n", client_id, conn_id, + mtu_size); + osal_printk(" status:%d\n", status); +} + +#define BLE_SPEED_HUNDRED 100 +static uint32_t get_float_int(float in) +{ + return (uint32_t)(((uint64_t)(in * BLE_SPEED_HUNDRED)) / BLE_SPEED_HUNDRED); +} + +static uint32_t get_float_dec(float in) +{ + return (uint32_t)(((uint64_t)(in * BLE_SPEED_HUNDRED)) % BLE_SPEED_HUNDRED); +} + +static void ble_gatt_client_notification_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data, + errcode_t status) +{ + unused(status); + unused(conn_id); + unused(client_id); + + g_recv_pkt_num++; + if (g_recv_pkt_num == 1) { + g_count_before_get_us = uapi_systick_get_us(); + } else if (g_recv_pkt_num == RECV_PKT_CNT) { + g_count_after_get_us = uapi_systick_get_us(); + printf("count_us = %llu, recv %d pkt.\r\n", + g_count_after_get_us - g_count_before_get_us, RECV_PKT_CNT); + float time = (float)(g_count_after_get_us - g_count_before_get_us) / 1000000.0; /* 1s = 1000000.0us */ + printf("time = %d.%d s\r\n", get_float_int(time), get_float_dec(time)); + float speed = (data->data_len) * RECV_PKT_CNT * 8 / time; /* 1B = 8bits */ + printf("speed = %d.%d bps\r\n", get_float_int(speed), get_float_dec(speed)); + g_recv_pkt_num = 0; + } +} + +static void ble_gatt_client_indication_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data, + errcode_t status) +{ + osal_printk("[GATTClient]Receive indication----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" handle:%d data_len:%d\ndata:", data->handle, data->data_len); + for (uint8_t i = 0; i < data->data_len; i++) { + osal_printk("%02x", data->data[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_gatt_client_enable_cbk(errcode_t status) +{ + status = status; +} + +static int convert_ble_mac(uint8_t *dest_mac, uint16_t dest_len, uint8_t *src_mac, uint16_t src_len) +{ + if (dest_len != src_len) { + return -1; + } + for (uint8_t i = 0; i < src_len; i++) { + dest_mac[i] = src_mac[src_len - 1 - i]; + } + return 0; +} + +static void ble_gatt_client_scan_result_cbk(gap_scan_result_data_t *scan_result_data) +{ + uint8_t ble_mac[BD_ADDR_LEN] = {0}; + convert_ble_mac(ble_mac, BD_ADDR_LEN, g_ble_speed_addr.addr, BD_ADDR_LEN); + if (memcmp(scan_result_data->addr.addr, ble_mac, BD_ADDR_LEN) == 0) { + osal_printk("Find The Target Device.\n"); + gap_ble_stop_scan(); + bd_addr_t client_addr = { 0 }; + client_addr.type = scan_result_data->addr.type; + if (memcpy_s(client_addr.addr, BD_ADDR_LEN, scan_result_data->addr.addr, BD_ADDR_LEN) != EOK) { + osal_printk("%s add server app addr memcpy failed\r\n", __FUNCTION__); + return; + } + gap_ble_connect_remote_device(&client_addr); + } else { + osal_printk("\naddr:"); + for (uint8_t i = 0; i < BD_ADDR_LEN; i++) { + osal_printk(" %02x:", scan_result_data->addr.addr[i]); + } + } +} + +static void ble_gatt_client_conn_state_change_cbk(uint16_t conn_id, bd_addr_t *addr, + gap_ble_conn_state_t conn_state, gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason) +{ + osal_printk("%s connect state change conn_id: %d, status: %d, pair_status:%d, disc_reason %x\n", + __FUNCTION__, conn_id, conn_state, pair_state, disc_reason); + + if (conn_state == GAP_BLE_STATE_CONNECTED) { + gap_ble_pair_remote_device(addr); + } +} + +static void ble_gatt_client_pair_result_cbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status) +{ + unused(addr); + osal_printk("%s pair result conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status); + + ble_gatt_client_discover_all_service(conn_id); +} + +static void ble_gatt_client_conn_param_update_cbk(uint16_t conn_id, errcode_t status, + const gap_ble_conn_param_update_t *param) +{ + osal_printk("%s conn_param_update conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status); + osal_printk("interval:%d latency:%d timeout:%d.\n", param->interval, param->latency, param->timeout); +} + +errcode_t ble_gatt_client_callback_register(void) +{ + errcode_t ret = ERRCODE_BT_UNHANDLED; + gap_ble_callbacks_t gap_cb = {0}; + gap_cb.ble_enable_cb = ble_gatt_client_enable_cbk; + gap_cb.scan_result_cb = ble_gatt_client_scan_result_cbk; + gap_cb.conn_state_change_cb = ble_gatt_client_conn_state_change_cbk; + gap_cb.pair_result_cb = ble_gatt_client_pair_result_cbk; + gap_cb.conn_param_update_cb = ble_gatt_client_conn_param_update_cbk; + ret |= gap_ble_register_callbacks(&gap_cb); + + gattc_callbacks_t cb = {0}; + cb.discovery_svc_cb = ble_gatt_client_discover_service_cbk; + cb.discovery_svc_cmp_cb = ble_gatt_client_discover_service_compl_cbk; + cb.discovery_chara_cb = ble_gatt_client_discover_character_cbk; + cb.discovery_chara_cmp_cb = ble_gatt_client_discover_character_compl_cbk; + cb.discovery_desc_cb = ble_gatt_client_discover_descriptor_cbk; + cb.discovery_desc_cmp_cb = ble_gatt_client_discover_descriptor_compl_cbk; + cb.read_cb = ble_gatt_client_read_cfm_cbk; + cb.read_cmp_cb = ble_gatt_client_read_compl_cbk; + cb.write_cb = ble_gatt_client_write_cfm_cbk; + cb.mtu_changed_cb = ble_gatt_client_mtu_changed_cbk; + cb.notification_cb = ble_gatt_client_notification_cbk; + cb.indication_cb = ble_gatt_client_indication_cbk; + ret |= gattc_register_callbacks(&cb); + return ret; +} + +void ble_speed_start_scan(void) +{ + gap_ble_scan_params_t ble_device_scan_params = { 0 }; + ble_device_scan_params.scan_interval = DEFAULT_SCAN_INTERVAL; + ble_device_scan_params.scan_window = DEFAULT_SCAN_INTERVAL; + ble_device_scan_params.scan_type = 0x00; + ble_device_scan_params.scan_phy = GAP_BLE_PHY_2M; + ble_device_scan_params.scan_filter_policy = 0x00; + gap_ble_set_scan_parameters(&ble_device_scan_params); + gap_ble_start_scan(); +} + +errcode_t ble_gatt_client_init(void) +{ + errcode_t ret = ERRCODE_BT_SUCCESS; + ret |= enable_ble(); + ret |= ble_gatt_client_callback_register(); + ret |= gattc_register_client(&g_client_app_uuid, &g_client_id); + osal_printk("[BLE Client] init ok.\n"); + ble_speed_start_scan(); + return ret; +} + +errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id) +{ + errcode_t ret = ERRCODE_BT_SUCCESS; + bt_uuid_t service_uuid = {0}; /* uuid length is zero, discover all service */ + ret |= gattc_discovery_service(g_client_id, conn_id, &service_uuid); + return ret; +} + +#define BLE_SPEED_TASK_PRIO 26 +#define BLE_SPEED_STACK_SIZE 0x2000 + +static void ble_speed_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle= osal_kthread_create((osal_kthread_handler)ble_gatt_client_init, 0, "ble_speed", + BLE_SPEED_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, BLE_SPEED_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the app entry. */ +app_run(ble_speed_entry); \ No newline at end of file diff --git a/application/samples/bt/ble/ble_speed_server/CMakeLists.txt b/application/samples/bt/ble/ble_speed_server/CMakeLists.txt new file mode 100755 index 0000000..be2e0bc --- /dev/null +++ b/application/samples/bt/ble/ble_speed_server/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/ble/ble_speed_server/inc/ble_speed_server.h b/application/samples/bt/ble/ble_speed_server/inc/ble_speed_server.h new file mode 100755 index 0000000..632f9a1 --- /dev/null +++ b/application/samples/bt/ble/ble_speed_server/inc/ble_speed_server.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * + * Description: BLE SPEED Server module. + */ + +/** + * @defgroup bluetooth_bts_hid_server HID SERVER API + * @ingroup + * @{ + */ +#ifndef BLE_SPEED_SERVER_H +#define BLE_SPEED_SERVER_H + +#include "bts_def.h" + +/* Service UUID */ +#define BLE_UUID_UUID_SERVER_SERVICE 0xABCD +/* Characteristic UUID */ +#define BLE_UUID_UUID_SERVER_REPORT 0xCDEF +/* Client Characteristic Configuration UUID */ +#define BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION 0x2902 +/* Server ID */ +#define BLE_UUID_SERVER_ID 1 + +/* Characteristic Property */ +#define UUID_SERVER_PROPERTIES (GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY) + +/** + * @if Eng + * @brief BLE server init. + * @attention NULL + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief BLE UUID服务器初始化。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +errcode_t ble_uuid_server_init(void); + +/** + * @if Eng + * @brief send data to peer device by uuid on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +errcode_t ble_uuid_server_send_report_by_uuid(uint8_t *data, uint16_t len); + +/** + * @if Eng + * @brief send data to peer device by handle on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +errcode_t ble_uuid_server_send_report_by_handle(uint16_t attr_handle, const uint8_t *data, uint8_t len); + +#endif + diff --git a/application/samples/bt/ble/ble_speed_server/inc/ble_speed_server_adv.h b/application/samples/bt/ble/ble_speed_server/inc/ble_speed_server_adv.h new file mode 100755 index 0000000..052a6d3 --- /dev/null +++ b/application/samples/bt/ble/ble_speed_server/inc/ble_speed_server_adv.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * + * Description: BLE ADV Config. + */ + +/** + * @defgroup bluetooth_bts_ble_adv API + * @ingroup + * @{ + */ +#ifndef BLE_SERVER_ADV_H +#define BLE_SERVER_ADV_H + +#include "bts_def.h" + +/* Ble Adv type Flag length */ +#define BLE_ADV_FLAG_LEN 0x03 +/* Ble Adv data length */ +#define BLE_GENERAL_BYTE_1 1 +/* Ble Adv appearance length */ +#define BLE_ADV_APPEARANCE_LENGTH 4 +/* Ble Adv appearance type */ +#define BLE_ADV_APPEARANCE_DATA_TYPE 0x19 +/* Ble keyboard appearance type */ +#define BLE_ADV_CATEGORY_KEYBOARD_VALUE 0x0080 +/* Ble keyboard categorylength */ +#define BLE_ADV_CATEGORY_LEN 2 +/* Ble name adv param type length */ +#define BLE_ADV_PARAM_DATATYPE_LENGTH 1 +/* Ble name adv name type */ +#define BLE_ADV_LOCAL_NAME_DATA_TYPE 0x09 +/* Ble name adv tx power type */ +#define BLE_ADV_TX_POWER_LEVEL 0x0A +/* Ble name adv tx power response type */ +#define BLE_SCAN_RSP_TX_POWER_LEVEL_LEN 0x03 +/* Ble adv flag data */ +#define BLE_ADV_FLAG_DATA 0x05 + +/** + * @if Eng + * @brief Definitaion of BLE ADV data flag. + * @else + * @brief BLE 广播数据类型定义。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv data flag length. + @else 广播数据类型长度 */ + uint8_t adv_data_type; /*!< @if Eng adv data type. + @else 广播数据类型 */ + uint8_t flags; /*!< @if Eng adv data flag. + @else 广播数据标志 */ +} ble_adv_flag; + +/** + * @if Eng + * @brief Definitaion of BLE device appearance struct. + * @else + * @brief BLE 广播设备外观结构。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv appearance data length. + @else 设备外观数据类型长度 */ + uint8_t adv_data_type; /*!< @if Eng adv appearance data type. + @else 设备外观数据类型 */ + uint8_t catogory_id[BLE_ADV_CATEGORY_LEN]; /*!< @if Eng adv appearance data. + @else 设备外观数据 */ +} ble_appearance_st; + +/** + * @if Eng + * @brief Definitaion of BLE device name. + * @else + * @brief BLE 广播设备名称。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv device name length. + @else 广播设备名称类型长度 */ + uint8_t adv_data_type; /*!< @if Eng adv name data type. + @else 设备名称类型 */ + int8_t *name; /*!< @if Eng adv name data. + @else 设备名称数据指针 */ +} ble_local_name_st; + +/** + * @if Eng + * @brief Definitaion of BLE Tx power. + * @else + * @brief BLE 广播发送功率。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv tx power length. + @else 广播发送功率长度 */ + uint8_t adv_data_type; /*!< @if Eng adv tx power type. + @else 广播发送数据类型 */ + uint8_t tx_power_value; /*!< @if Eng adv tx power value. + @else 广播发送数据 */ +} ble_tx_power_level_st; + +/** + * @if Eng + * @brief Definitaion value range for typedef struct ble_adv_para.adv_filter_policy. + * @else + * @brief Ble adv filter policy定义值范围。 + * @endif + */ +typedef enum ble_adv_filter_policy { + BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_ANY = 0x00, + BLE_ADV_FILTER_POLICY_SCAN_WHITE_LIST_CONNECT_ANY = 0x01, + BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_WHITE_LIST = 0x02, + BLE_ADV_FILTER_POLICY_SCAN_WHITE_LIST_CONNECT_WHITE_LIST = 0x03 +} ble_adv_filter_policy_t; + +/** + * @if Eng + * @brief Definitaion value range for adv type. + * @else + * @brief Ble adv 类型范围。 + * @endif + */ +typedef enum ble_adverting_type { + BLE_ADV_TYPE_CONNECTABLE_UNDIRECTED = 0x00, + BLE_ADV_TYPE_CONNECTABLE_HIGH_DUTY_CYCLE_DIRECTED = 0x01, + BLE_ADV_TYPE_SCANNABLE_UNDIRECTED = 0x02, + BLE_ADV_TYPE_NON_CONNECTABLE_UNDIRECTED = 0x03, + BLE_ADV_TYPE_CONNECTABLE_LOW_DUTY_CYCLE_DIRECTED = 0x04 +} ble_adverting_type_t; + + +/** + * @if Eng + * @brief Definitaion value range for adv channel map. + * @else + * @brief Ble 广播信道范围。 + * @endif + */ +typedef enum ble_adv_channel_map { + BLE_ADV_CHANNEL_MAP_CH_37 = 0x01, + BLE_ADV_CHANNEL_MAP_CH_38 = 0x02, + BLE_ADV_CHANNEL_MAP_CH_39 = 0x04, + BLE_ADV_CHANNEL_MAP_CH_37_CH_38 = 0x03, + BLE_ADV_CHANNEL_MAP_CH_37_CH_39 = 0x05, + BLE_ADV_CHANNEL_MAP_CH_38_CH_39 = 0x06, + BLE_ADV_CHANNEL_MAP_CH_DEFAULT = 0x07 +} ble_adv_channel_map_t; + +/** + * @if Eng + * @brief Definitaion value range for adv addr type. + * @else + * @brief Ble 广播地址类型。 + * @endif + */ +typedef enum { + BLE_PUBLIC_DEVICE_ADDRESS = 0x00, + BLE_RANDOM_DEVICE_ADDRESS = 0x01, + BLE_PUBLIC_IDENTITY_ADDRESS = 0x02, + BLE_RANDOM_STATIC_IDENTITY_ADDRESS = 0x03 +} ble_address_type; + +/* Ble adv min interval */ +#define BLE_ADV_MIN_INTERVAL 0x30 +/* Ble adv max interval */ +#define BLE_ADV_MAX_INTERVAL 0x60 +/* Ble adv handle */ +#define BTH_GAP_BLE_ADV_HANDLE_DEFAULT 0x01 +/* Ble adv duration */ +#define BTH_GAP_BLE_ADV_FOREVER_DURATION 0 + +/** + * @if Eng + * @brief Enable BLE adv. + * @attention NULL + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief 使能BLE广播。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +uint8_t ble_start_adv(void); + +/** + * @if Eng + * @brief BLE adv data config. + * @attention NULL + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief BLE广播数据配置。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +uint8_t ble_set_adv_data(void); +#endif + diff --git a/application/samples/bt/ble/ble_speed_server/src/CMakeLists.txt b/application/samples/bt/ble/ble_speed_server/src/CMakeLists.txt new file mode 100755 index 0000000..d5be614 --- /dev/null +++ b/application/samples/bt/ble/ble_speed_server/src/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/ble_speed_server_adv.c" + "${CMAKE_CURRENT_SOURCE_DIR}/ble_speed_server.c" + PARENT_SCOPE) diff --git a/application/samples/bt/ble/ble_speed_server/src/ble_speed_server.c b/application/samples/bt/ble/ble_speed_server/src/ble_speed_server.c new file mode 100755 index 0000000..992de51 --- /dev/null +++ b/application/samples/bt/ble/ble_speed_server/src/ble_speed_server.c @@ -0,0 +1,426 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * Description: ble speed server sample. + */ + +#include +#include +#include +#include +#include +#include "app_init.h" +#include "systick.h" +#include "soc_osal.h" +#include "cmsis_os2.h" +#include "securec.h" +#include "errcode.h" + +#include "osal_addr.h" +#include "bts_def.h" +#include "bts_def.h" +#include "bts_le_gap.h" +#include "bts_gatt_stru.h" +#include "bts_gatt_server.h" +#include "bts_gatt_client.h" +#include "ble_speed_server_adv.h" +#include "ble_speed_server.h" + +uint8_t g_server_id = 0; + +/* server app uuid for test */ +char g_uuid_app_uuid[] = {0x0, 0x0}; + +/* ble indication att handle */ +uint16_t g_indication_characteristic_att_hdl = 0; + +/* ble notification att handle */ +uint16_t g_notification_characteristic_att_hdl = 0; + +/* ble connect handle */ +uint16_t g_conn_hdl = 0; + +#define OCTET_BIT_LEN 8 +#define UUID_LEN_2 2 + +bd_addr_t g_ble_speed_addr = { + .type = 0, + .addr = {0x11, 0x22, 0x33, 0x63, 0x88, 0x63}, +}; + +#define DATA_LEN 236 +unsigned char data[DATA_LEN]; +uint64_t g_count_before_get_us; +uint64_t g_count_after_get_us; +#define SEND_PKT_TIMES 8 +#define SEND_PKT_CNT 100 +#define DEFAULT_BLE_SPEED_MTU_SIZE 250 +#define GAP_MAX_TX_OCTETS 251 +#define GAP_MAX_TX_TIME 2000 +#define SPEED_DEFAULT_CONN_INTERVAL 0xA +#define SPPED_DEFAULT_SLAVE_LATENCY 0 +#define SPEED_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4 + +#define BLE_SPEED_TASK_PRIO 26 +#define BLE_SPEED_STACK_SIZE 0x2000 + +void send_data_thread_function(void) +{ + printf("start send notify info.\n"); + gap_le_set_phy_t phy_param = { + .conn_handle = g_conn_hdl, + .all_phys = 0, + .tx_phys = 1, + .rx_phys = 1, + .phy_options = 0, + }; + gap_ble_set_phy(&phy_param); + + gap_le_set_data_length_t data_param = { + .conn_handle = g_conn_hdl, + .maxtxoctets = GAP_MAX_TX_OCTETS, + .maxtxtime = GAP_MAX_TX_TIME, + }; + gap_ble_set_data_length(&data_param); + + int i = 0; + g_count_before_get_us = uapi_systick_get_us(); + while (1) { + i++; + data[0] = (i >> 8) & 0xFF; /* offset 8bits */ + data[1] = i & 0xFF; + ble_uuid_server_send_report_by_uuid(data, DATA_LEN); + osal_msleep(1); /* 延时1ms 可使用BLE流控机制替换 */ + if (i == SEND_PKT_CNT) { + i = 0; + printf("[SYS INFO] send %d pkt: ", SEND_PKT_CNT); + LOS_MEM_POOL_STATUS status; + LOS_MemInfoGet(m_aucSysMem0, &status); + osal_printk(" mem: used:%u, free:%u.\r\n", status.uwTotalUsedSize, status.uwTotalFreeSize); + } + } +} + +/* 将uint16的uuid数字转化为bt_uuid_t */ +void stream_data_to_uuid(uint16_t uuid_data, bt_uuid_t *out_uuid) +{ + char uuid[] = {(uint8_t)(uuid_data >> OCTET_BIT_LEN), (uint8_t)uuid_data}; + out_uuid->uuid_len = UUID_LEN_2; + if (memcpy_s(out_uuid->uuid, out_uuid->uuid_len, uuid, UUID_LEN_2) != EOK) { + return; + } +} + +errcode_t compare_service_uuid(bt_uuid_t *uuid1, bt_uuid_t *uuid2) +{ + if (uuid1->uuid_len != uuid2->uuid_len) { + return ERRCODE_BT_FAIL; + } + if (memcmp(uuid1->uuid, uuid2->uuid, uuid1->uuid_len) != 0) { + return ERRCODE_BT_FAIL; + } + return ERRCODE_BT_SUCCESS; +} + +/* 添加描述符:客户端特性配置 */ +static void ble_uuid_server_add_descriptor_ccc(uint32_t server_id, uint32_t srvc_handle) +{ + bt_uuid_t ccc_uuid = {0}; + uint8_t ccc_data_val[] = {0x00, 0x00}; + + osal_printk("[uuid server] beginning add descriptors\r\n"); + stream_data_to_uuid(BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION, &ccc_uuid); + gatts_add_desc_info_t descriptor; + descriptor.desc_uuid = ccc_uuid; + descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE; + descriptor.value_len = sizeof(ccc_data_val); + descriptor.value = ccc_data_val; + gatts_add_descriptor(server_id, srvc_handle, &descriptor); + osal_vfree(ccc_uuid.uuid); +} + +/* 添加HID服务的所有特征和描述符 */ +static void ble_uuid_server_add_characters_and_descriptors(uint32_t server_id, uint32_t srvc_handle) +{ + bt_uuid_t server_uuid = {0}; + uint8_t server_value[] = {0x12, 0x34}; + osal_printk("[uuid server] beginning add characteristic\r\n"); + stream_data_to_uuid(BLE_UUID_UUID_SERVER_REPORT, &server_uuid); + gatts_add_chara_info_t character; + character.chara_uuid = server_uuid; + character.properties = UUID_SERVER_PROPERTIES; + character.permissions = 0; + character.value_len = sizeof(server_value); + character.value = server_value; + gatts_add_characteristic(server_id, srvc_handle, &character); + ble_uuid_server_add_descriptor_ccc(server_id, srvc_handle); +} + +/* 服务添加回调 */ +static void ble_uuid_server_service_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t handle, errcode_t status) +{ + bt_uuid_t service_uuid = {0}; + osal_printk("[uuid server] add service cbk: server: %d, status: %d, srv_handle: %d, uuid_len: %d,uuid:", + server_id, status, handle, uuid->uuid_len); + for (int8_t i = 0; i < uuid->uuid_len ; i++) { + osal_printk("%02x", (uint8_t)uuid->uuid[i]); + } + osal_printk("\n"); + stream_data_to_uuid(BLE_UUID_UUID_SERVER_SERVICE, &service_uuid); + if (compare_service_uuid(uuid, &service_uuid) == ERRCODE_BT_SUCCESS) { + ble_uuid_server_add_characters_and_descriptors(server_id, handle); + osal_printk("[uuid server] start service\r\n"); + gatts_start_service(server_id, handle); + } else { + osal_printk("[uuid server] unknown service uuid\r\n"); + return; + } +} + +/* 特征添加回调 */ +static void ble_uuid_server_characteristic_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t service_handle, + gatts_add_character_result_t *result, errcode_t status) +{ + int8_t i = 0; + osal_printk("[uuid server] add characteristic cbk: server: %d, status: %d, srv_hdl: %d "\ + "char_hdl: %x, char_val_hdl: %x, uuid_len: %d, uuid: ", + server_id, status, service_handle, result->handle, result->value_handle, uuid->uuid_len); + for (i = 0; i < uuid->uuid_len ; i++) { + osal_printk("%02x", (uint8_t)uuid->uuid[i]); + } + osal_printk("\n"); + g_notification_characteristic_att_hdl = result->value_handle; +} + +/* 描述符添加回调 */ +static void ble_uuid_server_descriptor_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t service_handle, + uint16_t handle, errcode_t status) +{ + int8_t i = 0; + osal_printk("[uuid server] add descriptor cbk : server: %d, status: %d, srv_hdl: %d, desc_hdl: %x ,"\ + "uuid_len:%d, uuid: ", server_id, status, service_handle, handle, uuid->uuid_len); + for (i = 0; i < uuid->uuid_len ; i++) { + osal_printk("%02x", (uint8_t)uuid->uuid[i]); + } + osal_printk("\n"); +} + +/* 开始服务回调 */ +static void ble_uuid_server_service_start_cbk(uint8_t server_id, uint16_t handle, errcode_t status) +{ + osal_printk("[uuid server] start service cbk : server: %d status: %d srv_hdl: %d\n", + server_id, status, handle); +} + +static void ble_uuid_server_receive_write_req_cbk(uint8_t server_id, uint16_t conn_id, + gatts_req_write_cb_t *write_cb_para, errcode_t status) +{ + osal_printk("[uuid server]ReceiveWriteReqCallback--server_id:%d conn_id:%d\n", server_id, conn_id); + osal_printk("request_id:%d att_handle:%d offset:%d need_rsp:%d need_authorize:%d is_prep:%d\n", + write_cb_para->request_id, write_cb_para->handle, write_cb_para->offset, write_cb_para->need_rsp, + write_cb_para->need_authorize, write_cb_para->is_prep); + osal_printk("data_len:%d data:\n", write_cb_para->length); + for (uint8_t i = 0; i < write_cb_para->length; i++) { + osal_printk("%02x ", write_cb_para->value[i]); + } + osal_printk("\n"); + osal_printk("status:%d\n", status); +} + +static void ble_uuid_server_receive_read_req_cbk(uint8_t server_id, uint16_t conn_id, + gatts_req_read_cb_t *read_cb_para, errcode_t status) +{ + osal_printk("[uuid server]ReceiveReadReq--server_id:%d conn_id:%d\n", server_id, conn_id); + osal_printk("request_id:%d att_handle:%d offset:%d need_rsp:%d need_authorize:%d is_long:%d\n", + read_cb_para->request_id, read_cb_para->handle, read_cb_para->offset, read_cb_para->need_rsp, + read_cb_para->need_authorize, read_cb_para->is_long); + osal_printk("status:%d\n", status); +} + +static void ble_uuid_server_adv_enable_cbk(uint8_t adv_id, adv_status_t status) +{ + osal_printk("adv enable adv_id: %d, status:%d\n", adv_id, status); +} + +static void ble_uuid_server_adv_disable_cbk(uint8_t adv_id, adv_status_t status) +{ + osal_printk("adv disable adv_id: %d, status:%d\n", + adv_id, status); +} + +void ble_uuid_server_connect_change_cbk(uint16_t conn_id, bd_addr_t *addr, gap_ble_conn_state_t conn_state, + gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason) +{ + osal_printk("connect state change conn_id: %d, status: %d, pair_status:%d, addr %x disc_reason %x\n", + conn_id, conn_state, pair_state, addr[0], disc_reason); + g_conn_hdl = conn_id; + + if (conn_state == GAP_BLE_STATE_CONNECTED) { + gattc_exchange_mtu_req(g_server_id, conn_id, DEFAULT_BLE_SPEED_MTU_SIZE); + + gap_conn_param_update_t conn_param = {0}; + conn_param.conn_handle = conn_id; + conn_param.interval_min = SPEED_DEFAULT_CONN_INTERVAL; + conn_param.interval_max = SPEED_DEFAULT_CONN_INTERVAL; + conn_param.slave_latency = SPPED_DEFAULT_SLAVE_LATENCY; + conn_param.timeout_multiplier = SPEED_DEFAULT_TIMEOUT_MULTIPLIER; + gap_ble_connect_param_update(&conn_param); + } else if (conn_state == GAP_BLE_STATE_DISCONNECTED) { + gap_ble_start_adv(BTH_GAP_BLE_ADV_HANDLE_DEFAULT); + } +} + +void ble_uuid_server_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status) +{ + osal_printk("mtu change change server_id: %d, conn_id: %d, mtu_size: %d, status:%d \n", + server_id, conn_id, mtu_size, status); +} + +void ble_uuid_server_pair_result_cbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status) +{ + osal_printk("pair state change conn_id: %d, status: %d, addr %x \n", + conn_id, status, addr[0]); + + if (status == 0) { + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)send_data_thread_function, 0, + "SpeedTask", BLE_SPEED_STACK_SIZE); + osal_kthread_set_priority(task_handle, BLE_SPEED_TASK_PRIO + 1); + if (task_handle != NULL) { + osal_kfree(task_handle); + } + osal_kthread_unlock(); + } +} + +static void ble_uuid_server_conn_param_update_cbk(uint16_t conn_id, errcode_t status, + const gap_ble_conn_param_update_t *param) +{ + osal_printk("%s conn_param_update conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status); + osal_printk("interval:%d latency:%d timeout:%d.\n", param->interval, param->latency, param->timeout); +} + +static errcode_t ble_uuid_server_register_callbacks(void) +{ + errcode_t ret = 0; + + gap_ble_callbacks_t gap_cb = {0}; + gap_cb.start_adv_cb = ble_uuid_server_adv_enable_cbk; + gap_cb.stop_adv_cb = ble_uuid_server_adv_disable_cbk; + gap_cb.conn_state_change_cb = ble_uuid_server_connect_change_cbk; + gap_cb.pair_result_cb = ble_uuid_server_pair_result_cbk; + gap_cb.conn_param_update_cb = ble_uuid_server_conn_param_update_cbk; + ret |= gap_ble_register_callbacks(&gap_cb); + if (ret != ERRCODE_BT_SUCCESS) { + osal_printk("[uuid server] reg gap cbk failed\r\n"); + return ERRCODE_BT_FAIL; + } + + gatts_callbacks_t service_cb = {0}; + service_cb.add_service_cb = ble_uuid_server_service_add_cbk; + service_cb.add_characteristic_cb = ble_uuid_server_characteristic_add_cbk; + service_cb.add_descriptor_cb = ble_uuid_server_descriptor_add_cbk; + service_cb.start_service_cb = ble_uuid_server_service_start_cbk; + service_cb.read_request_cb = ble_uuid_server_receive_read_req_cbk; + service_cb.write_request_cb = ble_uuid_server_receive_write_req_cbk; + service_cb.mtu_changed_cb = ble_uuid_server_mtu_changed_cbk; + ret |= gatts_register_callbacks(&service_cb); + if (ret != ERRCODE_BT_SUCCESS) { + osal_printk("[uuid server] reg service cbk failed\r\n"); + return ERRCODE_BT_FAIL; + } + return ret; +} + +uint8_t ble_uuid_add_service(void) +{ + osal_printk("[uuid server] ble uuid add service in\r\n"); + bt_uuid_t service_uuid = {0}; + stream_data_to_uuid(BLE_UUID_UUID_SERVER_SERVICE, &service_uuid); + gatts_add_service(BLE_UUID_SERVER_ID, &service_uuid, true); + osal_printk("[uuid server] ble uuid add service out\r\n"); + return ERRCODE_BT_SUCCESS; +} + +static errcode_t ble_uuid_gatts_register_server(void) +{ + bt_uuid_t app_uuid = {0}; + app_uuid.uuid_len = sizeof(g_uuid_app_uuid); + if (memcpy_s(app_uuid.uuid, app_uuid.uuid_len, g_uuid_app_uuid, sizeof(g_uuid_app_uuid)) != EOK) { + return ERRCODE_BT_FAIL; + } + return gatts_register_server(&app_uuid, &g_server_id); +} + +/* 初始化uuid server service */ +errcode_t ble_uuid_server_init(void) +{ + (void)osal_msleep(1000); /* 延时1000ms,等待BLE初始化完毕 */ + enable_ble(); + ble_uuid_server_register_callbacks(); + ble_uuid_gatts_register_server(); + ble_uuid_add_service(); + gap_ble_set_local_addr(&g_ble_speed_addr); + osal_printk("[uuid server] init ok\r\n"); + ble_start_adv(); + osal_printk("[uuid server] adv ok\r\n"); + return ERRCODE_BT_SUCCESS; +} + +/* device通过uuid向host发送数据:report */ +errcode_t ble_uuid_server_send_report_by_uuid(uint8_t *data, uint16_t len) +{ + gatts_ntf_ind_by_uuid_t param = {0}; + uint16_t conn_id = g_conn_hdl; + param.start_handle = 0; + param.end_handle = 0xffff; + stream_data_to_uuid(BLE_UUID_UUID_SERVER_REPORT, ¶m.chara_uuid); + param.value_len = len; + param.value = data; + if (param.value == NULL) { + osal_printk("[hid][ERROR]send report new fail\r\n"); + return ERRCODE_BT_FAIL; + } + gatts_notify_indicate_by_uuid(BLE_UUID_SERVER_ID, conn_id, ¶m); + return ERRCODE_BT_SUCCESS; +} + +/* device通过handle向host发送数据:report */ +errcode_t ble_uuid_server_send_report_by_handle(uint16_t attr_handle, const uint8_t *data, uint8_t len) +{ + gatts_ntf_ind_t param = {0}; + uint16_t conn_id = g_conn_hdl; + + param.attr_handle = attr_handle; + param.value = osal_vmalloc(len); + param.value_len = len; + + if (param.value == NULL) { + osal_printk("[hid][ERROR]send report new fail\r\n"); + return ERRCODE_BT_FAIL; + } + if (memcpy_s(param.value, param.value_len, data, len) != EOK) { + osal_printk("[hid][ERROR]send input report memcpy fail\r\n"); + osal_vfree(param.value); + return ERRCODE_BT_FAIL; + } + gatts_notify_indicate(BLE_UUID_SERVER_ID, conn_id, ¶m); + osal_vfree(param.value); + return ERRCODE_BT_SUCCESS; +} + +static void ble_speed_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle= osal_kthread_create((osal_kthread_handler)ble_uuid_server_init, 0, "ble_speed", + BLE_SPEED_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, BLE_SPEED_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the app entry. */ +app_run(ble_speed_entry); \ No newline at end of file diff --git a/application/samples/bt/ble/ble_speed_server/src/ble_speed_server_adv.c b/application/samples/bt/ble/ble_speed_server/src/ble_speed_server_adv.c new file mode 100755 index 0000000..77ac010 --- /dev/null +++ b/application/samples/bt/ble/ble_speed_server/src/ble_speed_server_adv.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: adv config for ble uuid server. + */ +#include +#include +#include +#include +#include "osal_addr.h" +#include "securec.h" +#include "errcode.h" +#include "bts_def.h" +#include "bts_le_gap.h" +#include "ble_speed_server_adv.h" + +#define NAME_MAX_LENGTH 15 +#define EXT_ADV_OR_SCAN_RSP_DATA_LEN 251 +static uint8_t u16_low_u8(uint16_t val) +{ + return (uint8_t)(val & 0xff); +} + +static uint8_t u16_high_u8(uint16_t val) +{ + return (uint8_t)((val >> 8) & 0xff); /* offset 8bits */ +} + +uint8_t g_local_name[ NAME_MAX_LENGTH] = { 'b', 'l', 'e', '_', 'u', 'u', 'i', 'd', '_', 's', + 'e', 'r', 'v', 'e', 'r' }; + +static uint8_t ble_set_adv_flag_data(uint8_t *set_adv_data_position, uint8_t max_len) +{ + errno_t n_ret; + + ble_adv_flag adv_flags = { + .length = BLE_ADV_FLAG_LEN - BLE_GENERAL_BYTE_1, + .adv_data_type = 1, + .flags = BLE_ADV_FLAG_DATA, + }; + n_ret = memcpy_s(set_adv_data_position, max_len, &adv_flags, BLE_ADV_FLAG_LEN); + if (n_ret != EOK) { + return 0; + } + return BLE_ADV_FLAG_LEN; +} + +static uint8_t ble_set_adv_appearance(uint8_t *set_adv_data_position, uint8_t max_len) +{ + errno_t n_ret; + ble_appearance_st adv_appearance_data = { + .length = BLE_ADV_APPEARANCE_LENGTH - BLE_GENERAL_BYTE_1, + .adv_data_type = BLE_ADV_APPEARANCE_DATA_TYPE, + .catogory_id = { u16_low_u8(BLE_ADV_CATEGORY_KEYBOARD_VALUE), u16_high_u8(BLE_ADV_CATEGORY_KEYBOARD_VALUE) }, + }; + n_ret = memcpy_s(set_adv_data_position, max_len, &adv_appearance_data, BLE_ADV_APPEARANCE_LENGTH); + if (n_ret != EOK) { + return 0; + } + return BLE_ADV_APPEARANCE_LENGTH; +} + +static uint8_t ble_set_adv_name(uint8_t *set_adv_data_position, uint8_t max_len) +{ + errno_t n_ret; + uint8_t len; + ble_local_name_st adv_local_name_data = { 0 }; + adv_local_name_data.length = (uint8_t)(BLE_ADV_PARAM_DATATYPE_LENGTH + sizeof(g_local_name)); + adv_local_name_data.adv_data_type = BLE_ADV_LOCAL_NAME_DATA_TYPE; + len = BLE_ADV_PARAM_DATATYPE_LENGTH + BLE_ADV_PARAM_DATATYPE_LENGTH; + n_ret = memcpy_s(set_adv_data_position, max_len, &adv_local_name_data, len); + if (n_ret != EOK) { + return 0; + } + n_ret = memcpy_s((set_adv_data_position + len), (size_t)(max_len - len), g_local_name, sizeof(g_local_name)); + if (n_ret != EOK) { + return 0; + } + len = (uint8_t)(len + sizeof(g_local_name)); + return len; +} + +static uint8_t ble_set_adv_appearance_data(uint8_t *set_adv_data_position, uint8_t max_len) +{ + uint8_t idx = 0; + idx += ble_set_adv_appearance(set_adv_data_position, max_len); + idx += ble_set_adv_name(set_adv_data_position + idx, (max_len - idx)); + return idx; +} + +static uint16_t ble_uuid_server_set_adv_data(uint8_t *set_adv_data, uint8_t adv_data_max_len) +{ + uint8_t idx = 0; + + if ((set_adv_data == NULL) || (adv_data_max_len == 0)) { + return 0; + } + idx += ble_set_adv_flag_data(set_adv_data, adv_data_max_len); + idx += ble_set_adv_appearance_data(&set_adv_data[idx], adv_data_max_len - idx); + return idx; +} + +static uint16_t ble_set_scan_response_data(uint8_t *scan_rsp_data, uint8_t scan_rsp_data_max_len) +{ + uint8_t idx = 0; + errno_t n_ret; + + if (scan_rsp_data == NULL) { + return 0; + } + if (scan_rsp_data_max_len == 0) { + return 0; + } + + /* tx power level */ + ble_tx_power_level_st tx_power_level = { + .length = BLE_SCAN_RSP_TX_POWER_LEVEL_LEN - BLE_GENERAL_BYTE_1, + .adv_data_type = BLE_ADV_TX_POWER_LEVEL, + .tx_power_value = 0, + }; + + n_ret = memcpy_s(scan_rsp_data, scan_rsp_data_max_len, &tx_power_level, sizeof(ble_tx_power_level_st)); + if (n_ret != EOK) { + return 0; + } + idx += BLE_SCAN_RSP_TX_POWER_LEVEL_LEN; + + /* set local name */ + scan_rsp_data[idx++] = sizeof(g_local_name) + BLE_GENERAL_BYTE_1; + scan_rsp_data[idx++] = BLE_ADV_LOCAL_NAME_DATA_TYPE; + if ((idx + sizeof(g_local_name)) > scan_rsp_data_max_len) { + return 0; + } + n_ret = memcpy_s(&scan_rsp_data[idx], scan_rsp_data_max_len - idx, g_local_name, sizeof(g_local_name)); + if (n_ret != EOK) { + return 0; + } + idx += sizeof(g_local_name); + return idx; +} + +uint8_t ble_set_adv_data(void) +{ + errcode_t n_ret = 0; + uint16_t adv_data_len; + uint16_t scan_rsp_data_len; + uint8_t set_adv_data[EXT_ADV_OR_SCAN_RSP_DATA_LEN] = { 0 }; + uint8_t set_scan_rsp_data[EXT_ADV_OR_SCAN_RSP_DATA_LEN] = { 0 }; + gap_ble_config_adv_data_t cfg_adv_data; + + /* set adv data */ + adv_data_len = ble_uuid_server_set_adv_data(set_adv_data, EXT_ADV_OR_SCAN_RSP_DATA_LEN); + if ((adv_data_len > EXT_ADV_OR_SCAN_RSP_DATA_LEN) || (adv_data_len == 0)) { + return 0; + } + /* set scan response data */ + scan_rsp_data_len = ble_set_scan_response_data(set_scan_rsp_data, EXT_ADV_OR_SCAN_RSP_DATA_LEN); + if ((scan_rsp_data_len > EXT_ADV_OR_SCAN_RSP_DATA_LEN) || (scan_rsp_data_len == 0)) { + return 0; + } + cfg_adv_data.adv_data = set_adv_data; + cfg_adv_data.adv_length = adv_data_len; + + cfg_adv_data.scan_rsp_data = set_scan_rsp_data; + cfg_adv_data.scan_rsp_length = scan_rsp_data_len; + n_ret = gap_ble_set_adv_data(BTH_GAP_BLE_ADV_HANDLE_DEFAULT, &cfg_adv_data); + if (n_ret != 0) { + return 0; + } + return 0; +} + +uint8_t ble_start_adv(void) +{ + errcode_t n_ret = 0; + gap_ble_adv_params_t adv_para = {0}; + int adv_id = BTH_GAP_BLE_ADV_HANDLE_DEFAULT; + + adv_para.min_interval = BLE_ADV_MIN_INTERVAL; + adv_para.max_interval = BLE_ADV_MAX_INTERVAL; + adv_para.duration = BTH_GAP_BLE_ADV_FOREVER_DURATION; + adv_para.peer_addr.type = BLE_PUBLIC_DEVICE_ADDRESS; + /* 广播通道选择bitMap, 可参考BleAdvChannelMap */ + adv_para.channel_map = BLE_ADV_CHANNEL_MAP_CH_DEFAULT; + adv_para.adv_type = BLE_ADV_TYPE_CONNECTABLE_UNDIRECTED; + adv_para.adv_filter_policy = BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_ANY; + (void)memset_s(&adv_para.peer_addr.addr, BD_ADDR_LEN, 0, BD_ADDR_LEN); + n_ret = gap_ble_set_adv_param(adv_id, &adv_para); + if (n_ret != 0) { + return 0; + } + n_ret = gap_ble_start_adv(adv_id); + if (n_ret != 0) { + return 0; + } + return 0; +} diff --git a/application/samples/bt/ble/ble_wifi_cfg_client/CMakeLists.txt b/application/samples/bt/ble/ble_wifi_cfg_client/CMakeLists.txt new file mode 100755 index 0000000..6924cde --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_client/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. +#=============================================================================== + +add_subdirectory_if_exist(src) +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_client.h b/application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_client.h new file mode 100755 index 0000000..fae2fd4 --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_client.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: BT config wifi Service client module. + */ +#ifndef BLE_WIFI_CFG_CLIENT_H +#define BLE_WIFI_CFG_CLIENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @if Eng + * @brief Use this funtion to init gatt client. + * @par Description:init gatt client. + * @attention NULL + * @param NULL + * @retval error code. + * @else + * @brief 初始化gatt 客户端。 + * @par 说明:初始化gatt 客户端。 + * @attention NULL + * @param NULL + * @retval 执行结果错误码。 + * @endif + */ +errcode_t ble_wifi_cfg_client_init(void); + +/** + * @if Eng + * @brief discover all service, character and descriptor of remote device. + * @par Description:discover all service of remote device. + * @attention NULL + * @param conn_id connection ID + * @retval error code. + * @else + * @brief 发现对端设备所有服务、特征和描述符。 + * @par 说明:发现对端设备所有服务、特征和描述符。 + * @attention NULL + * @param conn_id 连接 ID + * @retval 执行结果错误码。 + * @endif + */ +errcode_t ble_wifi_cfg_client_discover_all_service(uint16_t conn_id); + +/** + * @} + */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_scan.h b/application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_scan.h new file mode 100755 index 0000000..49d3842 --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_scan.h @@ -0,0 +1,25 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: BLE config wifi client scan. + */ +#ifndef BLE_WIFI_CFG_SCAN_H +#define BLE_WIFI_CFG_SCAN_H + +#include "errcode.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +errcode_t ble_wifi_device_start_scan(void); + +errcode_t ble_wifi_set_scan_parameters(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ +#endif \ No newline at end of file diff --git a/application/samples/bt/ble/ble_wifi_cfg_client/src/CMakeLists.txt b/application/samples/bt/ble/ble_wifi_cfg_client/src/CMakeLists.txt new file mode 100755 index 0000000..61a09cf --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_client/src/CMakeLists.txt @@ -0,0 +1,11 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. +#=============================================================================== + +set( + ble_wifi_cfg_src_list + ${CMAKE_CURRENT_SOURCE_DIR}/ble_wifi_cfg_client.c + ${CMAKE_CURRENT_SOURCE_DIR}/ble_wifi_cfg_scan.c +) +set(SOURCES "${SOURCES}" "${ble_wifi_cfg_src_list}" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_client.c b/application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_client.c new file mode 100755 index 0000000..6ae1a0c --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_client.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: BT config wifi Service client module. + */ +#include "securec.h" +#include "osal_list.h" +#include "osal_debug.h" +#include "bts_le_gap.h" +#include "bts_gatt_client.h" +#include "ble_wifi_cfg_scan.h" + +#define UUID16_LEN 2 + +#define BLE_WIFI_CFG_CLIENT_LOG "[ble wifi cfg client]" +#define BLE_WIFI_CFG_CLIENT_ERROR "[ble wifi cfg error]" + +/* client id, invalid client id is "0" */ +uint8_t g_ble_wifi_cfg_client_id = 0; + +static uint16_t g_ble_wifi_cfg_conn_id = 0; + +/* max transport unit, default is 100 */ +static uint16_t g_ble_wifi_cfg_mtu = 100; + +/* client app uuid for test */ +static bt_uuid_t g_ble_wifi_cfg_client_app = {UUID16_LEN, {0}}; + + +uint8_t ble_wifi_adv_data[31] = {0x02, 0x01, 0x02, 0x13, 0xFF, 0x7D, 0x02, 0x0E, 0x70, 0x80, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x01, 0x06, 0xCA, 0x2D, 0x28, 0xA0, 0x9D, 0xA3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define HW_ADV_DATA_LEN 0x17 + +static void ble_wifi_cfg_client_discover_service_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_service_result_t *service, errcode_t status) +{ + gattc_discovery_character_param_t param = {0}; + osal_printk("[GATTClient]Discovery service----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk("start handle:%d end handle:%d uuid_len:%d\n uuid:", + service->start_hdl, service->end_hdl, service->uuid.uuid_len); + for (uint8_t i = 0; i < service->uuid.uuid_len; i++) { + osal_printk("%02x", service->uuid.uuid[i]); + } + osal_printk("\n status:%d\n", status); + param.service_handle = service->start_hdl; + param.uuid.uuid_len = 0; /* uuid length is zero, discover all character */ + gattc_discovery_character(g_ble_wifi_cfg_client_id, conn_id, ¶m); +} + +static void ble_wifi_cfg_client_discover_character_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_character_result_t *character, errcode_t status) +{ + osal_printk("[GATTClient]Discovery character----client:%d conn_id:%d uuid_len:%d\n uuid:", + client_id, conn_id, character->uuid.uuid_len); + for (uint8_t i = 0; i < character->uuid.uuid_len; i++) { + osal_printk("%02x", character->uuid.uuid[i]); + } + osal_printk("\n declare handle:%d value handle:%d properties:%x\n", character->declare_handle, + character->value_handle, character->properties); + osal_printk(" status:%d\n", status); + gattc_discovery_descriptor(g_ble_wifi_cfg_client_id, conn_id, character->declare_handle); +} + +static void ble_wifi_cfg_client_discover_descriptor_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_descriptor_result_t *descriptor, errcode_t status) +{ + osal_printk("[GATTClient]Discovery descriptor----client:%d conn_id:%d uuid len:%d\n uuid:", + client_id, conn_id, descriptor->uuid.uuid_len); + for (uint8_t i = 0; i < descriptor->uuid.uuid_len; i++) { + osal_printk("%02x", descriptor->uuid.uuid[i]); + } + osal_printk("\n descriptor handle:%d\n", descriptor->descriptor_hdl); + osal_printk(" status:%d\n", status); +} + +static void ble_wifi_cfg_client_discover_service_compl_cbk(uint8_t client_id, uint16_t conn_id, bt_uuid_t *uuid, + errcode_t status) +{ + osal_printk( + "[GATTClient]Discovery service complete----client:%d conn_id:%d uuid len:%d\n uuid:", + client_id, conn_id, uuid->uuid_len); + for (uint8_t i = 0; i < uuid->uuid_len; i++) { + osal_printk("%02x", uuid->uuid[i]); + } + osal_printk("status:%d\n", status); +} + +static void ble_wifi_cfg_client_discover_character_compl_cbk(uint8_t client_id, uint16_t conn_id, + gattc_discovery_character_param_t *param, errcode_t status) +{ + osal_printk( + "[GATTClient]Discovery character complete----client:%d conn_id:%d uuid len:%d\n uuid:", + client_id, conn_id, param->uuid.uuid_len); + for (uint8_t i = 0; i < param->uuid.uuid_len; i++) { + osal_printk("%02x", param->uuid.uuid[i]); + } + osal_printk("\n service handle:%d\n", param->service_handle); + osal_printk(" status:%d\n", status); +} + +static void ble_wifi_cfg_client_discover_descriptor_compl_cbk(uint8_t client_id, uint16_t conn_id, + uint16_t character_handle, errcode_t status) +{ + osal_printk("[GATTClient]Discovery descriptor complete----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" charatcer handle:%d\n", character_handle); + osal_printk(" status:%d\n", status); +} + +static void ble_wifi_cfg_client_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *read_result, + gatt_status_t status) +{ + osal_printk("[GATTClient]Read result----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" handle:%d data_len:%d\ndata:", read_result->handle, read_result->data_len); + for (uint8_t i = 0; i < read_result->data_len; i++) { + osal_printk("%02x", read_result->data[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_wifi_cfg_client_read_compl_cbk(uint8_t client_id, uint16_t conn_id, + gattc_read_req_by_uuid_param_t *param, errcode_t status) +{ + osal_printk("[GATTClient]Read by uuid complete----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk("start handle:%d end handle:%d uuid len:%d\n uuid:", + param->start_hdl, param->end_hdl, param->uuid.uuid_len); + for (uint8_t i = 0; i < param->uuid.uuid_len; i++) { + osal_printk("%02x", param->uuid.uuid[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_wifi_cfg_client_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, + uint16_t handle, gatt_status_t status) +{ + osal_printk("[GATTClient]Write result----client:%d conn_id:%d handle:%d\n", client_id, conn_id, handle); + osal_printk(" status:%d\n", status); +} + +static void ble_wifi_cfg_client_mtu_changed_cbk(uint8_t client_id, uint16_t conn_id, + uint16_t mtu_size, errcode_t status) +{ + osal_printk("[GATTClient]Mtu changed----client:%d conn_id:%d mtu size:%d\n", client_id, conn_id, + mtu_size); + osal_printk("status:%d\n", status); +} + +static void ble_wifi_cfg_client_notification_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data, + errcode_t status) +{ + osal_printk("[GATTClient]Receive notification----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk("handle:%d data_len:%d\ndata:", data->handle, data->data_len); + for (uint8_t i = 0; i < data->data_len; i++) { + osal_printk("%02x", data->data[i]); + } + osal_printk("\n status:%d\n", status); +} + +static void ble_wifi_cfg_client_indication_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data, + errcode_t status) +{ + osal_printk("[GATTClient]Receive indication----client:%d conn_id:%d\n", client_id, conn_id); + osal_printk(" handle:%d data_len:%d\ndata:", data->handle, data->data_len); + for (uint8_t i = 0; i < data->data_len; i++) { + osal_printk("%02x", data->data[i]); + } + osal_printk("\n status:%d\n", status); +} + +/* ble client set scan param callback */ +void ble_wifi_cfg_set_scan_param_cbk(errcode_t status) +{ + osal_printk("%s set scan param status: %d\n", 0, status); + gap_ble_remove_all_pairs(); /* 配网业务无需多连接,因此扫描时需将其他设备断开, 然后扫描配对新设备 */ + ble_wifi_device_start_scan(); +} + +/* ble client scan result callback */ +void ble_wifi_cfg_scan_result_cbk(gap_scan_result_data_t *scan_result_data) +{ + if (memcmp(scan_result_data->adv_data, ble_wifi_adv_data, HW_ADV_DATA_LEN) == 0) { + gap_ble_stop_scan(); + osal_printk("\naddr:"); + for (uint8_t i = 0; i < BD_ADDR_LEN; i++) { + osal_printk(" %02x: ", scan_result_data->addr.addr[i]); + } + bd_addr_t client_addr = { 0 }; + client_addr.type = scan_result_data->addr.type; + if (memcpy_s(client_addr.addr, BD_ADDR_LEN, scan_result_data->addr.addr, BD_ADDR_LEN) != EOK) { + osal_printk("%s add server app addr memcpy failed\r\n", BLE_WIFI_CFG_CLIENT_ERROR); + return; + } + gap_ble_connect_remote_device(&client_addr); + } +} + +/* ble client connect state change callback */ +void ble_wifi_cfg_connect_change_cbk(uint16_t conn_id, bd_addr_t *addr, gap_ble_conn_state_t conn_state, + gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason) +{ + bd_addr_t client_addr = { 0 }; + client_addr.type = addr->type; + g_ble_wifi_cfg_conn_id = conn_id; + if (memcpy_s(client_addr.addr, BD_ADDR_LEN, addr->addr, BD_ADDR_LEN) != EOK) { + osal_printk("%s add server app addr memcpy failed\r\n", BLE_WIFI_CFG_CLIENT_ERROR); + return; + } + osal_printk("%s connect state change conn_id: %d, status: %d, pair_status:%d, disc_reason %x\n", + 0, conn_id, conn_state, pair_state, disc_reason); + + if (conn_state == GAP_BLE_STATE_CONNECTED && pair_state == GAP_BLE_PAIR_NONE) { + osal_printk("%s connect change cbk conn_id =%d \n", 0, conn_id); + gattc_exchange_mtu_req(g_ble_wifi_cfg_client_id, g_ble_wifi_cfg_conn_id, g_ble_wifi_cfg_mtu); + } else if (conn_state == GAP_BLE_STATE_DISCONNECTED) { + osal_printk("%s connect change cbk conn disconnected \n", 0); + return; + } +} + +/* ble client pair result callback */ +void ble_wifi_cfg_pair_result_cb(uint16_t conn_id, const bd_addr_t *addr, errcode_t status) +{ + osal_printk("%s pair result conn_id: %d,status: %d \n", 0, conn_id, status); + osal_printk("addr:\n"); + for (uint8_t i = 0; i < BD_ADDR_LEN; i++) { + osal_printk("%2x", addr->addr[i]); + } + osal_printk("\n"); + gattc_exchange_mtu_req(g_ble_wifi_cfg_client_id, g_ble_wifi_cfg_conn_id, + g_ble_wifi_cfg_mtu); +} + + +errcode_t ble_wifi_cfg_client_callback_register(void) +{ + errcode_t ret = ERRCODE_BT_UNHANDLED; + gap_ble_callbacks_t gap_cb = { 0 }; + gattc_callbacks_t cb = {0}; + + gap_cb.set_scan_param_cb = ble_wifi_cfg_set_scan_param_cbk; + gap_cb.scan_result_cb = ble_wifi_cfg_scan_result_cbk; + gap_cb.conn_state_change_cb = ble_wifi_cfg_connect_change_cbk; + gap_cb.pair_result_cb = ble_wifi_cfg_pair_result_cb; + ret = gap_ble_register_callbacks(&gap_cb); + if (ret != ERRCODE_BT_SUCCESS) { + osal_printk("%s reg gap cbk failed ret = %d\n", 0, ret); + } + + cb.discovery_svc_cb = ble_wifi_cfg_client_discover_service_cbk; + cb.discovery_svc_cmp_cb = ble_wifi_cfg_client_discover_service_compl_cbk; + cb.discovery_chara_cb = ble_wifi_cfg_client_discover_character_cbk; + cb.discovery_chara_cmp_cb = ble_wifi_cfg_client_discover_character_compl_cbk; + cb.discovery_desc_cb = ble_wifi_cfg_client_discover_descriptor_cbk; + cb.discovery_desc_cmp_cb = ble_wifi_cfg_client_discover_descriptor_compl_cbk; + cb.read_cb = ble_wifi_cfg_client_read_cfm_cbk; + cb.read_cmp_cb = ble_wifi_cfg_client_read_compl_cbk; + cb.write_cb = ble_wifi_cfg_client_write_cfm_cbk; + cb.mtu_changed_cb = ble_wifi_cfg_client_mtu_changed_cbk; + cb.notification_cb = ble_wifi_cfg_client_notification_cbk; + cb.indication_cb = ble_wifi_cfg_client_indication_cbk; + ret = gattc_register_callbacks(&cb); + + return ret; +} + +errcode_t ble_wifi_cfg_client_init(void) +{ + errcode_t ret = ERRCODE_BT_SUCCESS; + ret |= enable_ble(); + ret |= ble_wifi_cfg_client_callback_register(); + ret |= gattc_register_client(&g_ble_wifi_cfg_client_app, &g_ble_wifi_cfg_client_id); + return ret; +} + +errcode_t ble_wifi_cfg_client_discover_all_service(uint16_t conn_id) +{ + errcode_t ret = ERRCODE_BT_SUCCESS; + bt_uuid_t service_uuid = {0}; /* uuid length is zero, discover all service */ + ret |= gattc_discovery_service(g_ble_wifi_cfg_client_id, conn_id, &service_uuid); + return ret; +} + diff --git a/application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_scan.c b/application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_scan.c new file mode 100755 index 0000000..6934c38 --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_scan.c @@ -0,0 +1,31 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: BLE config wifi client scan +*/ + +#include "errcode.h" +#include "bts_def.h" +#include "bts_le_gap.h" +#include "ble_wifi_cfg_scan.h" + +static uint16_t scan_interval = 0x48; +static uint16_t scan_window = 0x48; +static uint8_t scan_type = 0x00; +static uint8_t scan_phy = 0x01; +static uint8_t scan_filter_policy = 0x00; + +errcode_t ble_wifi_set_scan_parameters(void) +{ + gap_ble_scan_params_t ble_device_scan_params = { 0 }; + ble_device_scan_params.scan_interval = scan_interval; + ble_device_scan_params.scan_window = scan_window; + ble_device_scan_params.scan_type = scan_type; + ble_device_scan_params.scan_phy = scan_phy; + ble_device_scan_params.scan_filter_policy = scan_filter_policy; + return gap_ble_set_scan_parameters(&ble_device_scan_params); +} + +errcode_t ble_wifi_device_start_scan(void) +{ + return gap_ble_start_scan(); +} \ No newline at end of file diff --git a/application/samples/bt/ble/ble_wifi_cfg_server/CMakeLists.txt b/application/samples/bt/ble/ble_wifi_cfg_server/CMakeLists.txt new file mode 100755 index 0000000..6924cde --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_server/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. +#=============================================================================== + +add_subdirectory_if_exist(src) +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_adv.h b/application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_adv.h new file mode 100755 index 0000000..d661016 --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_adv.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: BLE ADV Config. + */ +#ifndef BLE_WIFI_CFG_ADV_H +#define BLE_WIFI_CFG_ADV_H + +#include "bts_def.h" + +/* Ble keyboard categorylength */ +#define BLE_ADV_CATEGORY_LEN 2 + +/** + * @if Eng + * @brief Definitaion of BLE device appearance struct. + * @else + * @brief BLE 广播设备外观结构。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv appearance data length. + @else 设备外观数据类型长度 */ + uint8_t adv_data_type; /*!< @if Eng adv appearance data type. + @else 设备外观数据类型 */ + uint8_t catogory_id[BLE_ADV_CATEGORY_LEN]; /*!< @if Eng adv appearance data. + @else 设备外观数据 */ +} ble_appearance_st; + +/** + * @if Eng + * @brief Definitaion of BLE device name. + * @else + * @brief BLE 广播设备名称。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv device name length. + @else 广播设备名称类型长度 */ + uint8_t adv_data_type; /*!< @if Eng adv name data type. + @else 设备名称类型 */ + int8_t *name; /*!< @if Eng adv name data. + @else 设备名称数据指针 */ +} ble_local_name_st; + +/** + * @if Eng + * @brief Definitaion of BLE Tx power. + * @else + * @brief BLE 广播发送功率。 + * @endif + */ +typedef struct { + uint8_t length; /*!< @if Eng adv tx power length. + @else 广播发送功率长度 */ + uint8_t adv_data_type; /*!< @if Eng adv tx power type. + @else 广播发送数据类型 */ + uint8_t tx_power_value; /*!< @if Eng adv tx power value. + @else 广播发送数据 */ +} ble_tx_power_level_st; + +/** + * @if Eng + * @brief Definitaion value range for typedef struct ble_adv_para.adv_filter_policy. + * @else + * @brief Ble adv filter policy定义值范围。 + * @endif + */ +typedef enum ble_adv_filter_policy { + BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_ANY = 0x00, + BLE_ADV_FILTER_POLICY_SCAN_WHITE_LIST_CONNECT_ANY = 0x01, + BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_WHITE_LIST = 0x02, + BLE_ADV_FILTER_POLICY_SCAN_WHITE_LIST_CONNECT_WHITE_LIST = 0x03 +} ble_adv_filter_policy_t; + +/** + * @if Eng + * @brief Definitaion value range for adv type. + * @else + * @brief Ble adv 类型范围。 + * @endif + */ +typedef enum ble_adverting_type { + BLE_ADV_TYPE_CONNECTABLE_UNDIRECTED = 0x00, + BLE_ADV_TYPE_CONNECTABLE_HIGH_DUTY_CYCLE_DIRECTED = 0x01, + BLE_ADV_TYPE_SCANNABLE_UNDIRECTED = 0x02, + BLE_ADV_TYPE_NON_CONNECTABLE_UNDIRECTED = 0x03, + BLE_ADV_TYPE_CONNECTABLE_LOW_DUTY_CYCLE_DIRECTED = 0x04 +} ble_adverting_type_t; + + +/** + * @if Eng + * @brief Definitaion value range for adv channel map. + * @else + * @brief Ble 广播信道范围。 + * @endif + */ +typedef enum ble_adv_channel_map { + BLE_ADV_CHANNEL_MAP_CH_37 = 0x01, + BLE_ADV_CHANNEL_MAP_CH_38 = 0x02, + BLE_ADV_CHANNEL_MAP_CH_39 = 0x04, + BLE_ADV_CHANNEL_MAP_CH_37_CH_38 = 0x03, + BLE_ADV_CHANNEL_MAP_CH_37_CH_39 = 0x05, + BLE_ADV_CHANNEL_MAP_CH_38_CH_39 = 0x06, + BLE_ADV_CHANNEL_MAP_CH_DEFAULT = 0x07 +} ble_adv_channel_map_t; + +/** + * @if Eng + * @brief Definitaion value range for adv addr type. + * @else + * @brief Ble 广播地址类型。 + * @endif + */ +typedef enum { + BLE_PUBLIC_DEVICE_ADDRESS = 0x00, + BLE_RANDOM_DEVICE_ADDRESS = 0x01, + BLE_PUBLIC_IDENTITY_ADDRESS = 0x02, + BLE_RANDOM_STATIC_IDENTITY_ADDRESS = 0x03 +} ble_address_type; + +/* Ble adv min interval */ +#define BLE_ADV_MIN_INTERVAL 0x20 +/* Ble adv max interval */ +#define BLE_ADV_MAX_INTERVAL 0x60 +/* Ble adv handle */ +#define BTH_GAP_BLE_ADV_HANDLE_DEFAULT 0x01 +/* Ble adv duration */ +#define BTH_GAP_BLE_ADV_FOREVER_DURATION 0 + +/** + * @if Eng + * @brief Enable BLE adv. + * @attention NULL + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief 使能BLE广播。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +uint8_t ble_start_adv(void); + +/** + * @if Eng + * @brief BLE adv data config. + * @attention NULL + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief BLE广播数据配置。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +uint8_t ble_set_adv_data(void); + +uint8_t ble_wifi_cfg_start_adv(void); +#endif + diff --git a/application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_server.h b/application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_server.h new file mode 100755 index 0000000..5ef868f --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_server.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: BLE UUID Server module. + */ +#ifndef BLE_WIFI_CFG_SERVER_H +#define BLE_WIFI_CFG_SERVER_H + +#include "bts_def.h" + +/* Characteristic Property */ +#define BLE_WIFI_CFG_PROPERTIES (GATT_CHARACTER_PROPERTY_BIT_NOTIFY | GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP) + +/* Characteristic Property */ +#define UUID_SERVER_IND_PROPERTIES (GATT_CHARACTER_PROPERTY_BIT_INDICATE | GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP) + +/** + * @if Eng + * @brief BLE uuid server inir. + * @attention NULL + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief BLE UUID服务器初始化。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +errcode_t ble_wifi_cfg_server_init(void); + +/** + * @if Eng + * @brief send data to peer device by wifi server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief 通过wifi server 发送数据给对端。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +errcode_t ble_wifi_cfg_server_send_report_by_uuid(const uint8_t *data, uint32_t len); + +/** + * @if Eng + * @brief send data to peer device by handle on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval BT_STATUS_SUCCESS Excute successfully + * @retval BT_STATUS_FAIL Execute fail + * @par Dependency: + * @li bts_def.h + * @else + * @brief 通过wifi server 发送数据给对端。 + * @attention NULL + * @retval BT_STATUS_SUCCESS 执行成功 + * @retval BT_STATUS_FAIL 执行失败 + * @par 依赖: + * @li bts_def.h + * @endif + */ +errcode_t ble_wifi_cfg_server_send_report_by_handle(uint16_t attr_handle, const uint8_t *data, uint8_t len); + +#endif \ No newline at end of file diff --git a/application/samples/bt/ble/ble_wifi_cfg_server/src/CMakeLists.txt b/application/samples/bt/ble/ble_wifi_cfg_server/src/CMakeLists.txt new file mode 100755 index 0000000..edf0641 --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_server/src/CMakeLists.txt @@ -0,0 +1,9 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. +#=============================================================================== + +set(SOURCES "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/ble_wifi_cfg_adv.c" + "${CMAKE_CURRENT_SOURCE_DIR}/ble_wifi_cfg_server.c" + PARENT_SCOPE) diff --git a/application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_adv.c b/application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_adv.c new file mode 100755 index 0000000..2aed169 --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_adv.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: adv config for ble uuid server. + */ +#include +#include +#include +#include +#include "osal_addr.h" +#include "osal_debug.h" +#include "securec.h" +#include "errcode.h" +#include "bts_def.h" +#include "bts_le_gap.h" +#include "ble_wifi_cfg_adv.h" + +#define NAME_MAX_LENGTH 15 +#define EXT_ADV_OR_SCAN_RSP_DATA_LEN 251 +#define HW_ADV_DATA_LEN 0x17 + +/* Ble Adv data length */ +#define BLE_GENERAL_BYTE_1 1 +/* Ble name adv name type */ +#define BLE_ADV_LOCAL_NAME_DATA_TYPE 0x09 +/* Ble name adv tx power type */ +#define BLE_ADV_TX_POWER_LEVEL 0x0A +/* Ble name adv tx power response type */ +#define BLE_SCAN_RSP_TX_POWER_LEVEL_LEN 0x03 + +uint8_t g_device_name[ NAME_MAX_LENGTH] = { 'b', 'l', 'e', '_', 'w', 'i', 'f', 'i', '_', 'c', + 'o', 'n', 'f', 'i', 'g' }; + +uint8_t g_adv_data[31] = {0x02, 0x01, 0x02, 0x13, 0xFF, 0x7D, 0x02, 0x0E, 0x70, 0x80, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x01, 0x06, 0xCA, 0x2D, 0x28, 0xA0, 0x9D, 0xA3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +static uint16_t ble_set_scan_response_data(uint8_t *scan_rsp_data, uint8_t scan_rsp_data_max_len) +{ + uint8_t idx = 0; + errno_t n_ret; + + if (scan_rsp_data == NULL) { + return 0; + } + if (scan_rsp_data_max_len == 0) { + return 0; + } + + /* tx power level */ + ble_tx_power_level_st tx_power_level = { + .length = BLE_SCAN_RSP_TX_POWER_LEVEL_LEN - BLE_GENERAL_BYTE_1, + .adv_data_type = BLE_ADV_TX_POWER_LEVEL, + .tx_power_value = 0, + }; + + n_ret = memcpy_s(scan_rsp_data, scan_rsp_data_max_len, &tx_power_level, sizeof(ble_tx_power_level_st)); + if (n_ret != EOK) { + return 0; + } + idx += BLE_SCAN_RSP_TX_POWER_LEVEL_LEN; + + /* set local name */ + scan_rsp_data[idx++] = sizeof(g_device_name) + BLE_GENERAL_BYTE_1; + scan_rsp_data[idx++] = BLE_ADV_LOCAL_NAME_DATA_TYPE; + if ((idx + sizeof(g_device_name)) > scan_rsp_data_max_len) { + return 0; + } + n_ret = memcpy_s(&scan_rsp_data[idx], scan_rsp_data_max_len - idx, g_device_name, sizeof(g_device_name)); + if (n_ret != EOK) { + return 0; + } + idx += sizeof(g_device_name); + return idx; +} + +uint8_t ble_wifi_cfg_set_adv_data(void) +{ + errcode_t n_ret = 0; + uint16_t scan_rsp_data_len; + uint8_t set_scan_rsp_data[EXT_ADV_OR_SCAN_RSP_DATA_LEN] = { 0 }; + gap_ble_config_adv_data_t cfg_adv_data; + + /* set scan response data */ + scan_rsp_data_len = ble_set_scan_response_data(set_scan_rsp_data, EXT_ADV_OR_SCAN_RSP_DATA_LEN); + if ((scan_rsp_data_len > EXT_ADV_OR_SCAN_RSP_DATA_LEN) || (scan_rsp_data_len == 0)) { + return 0; + } + cfg_adv_data.adv_data = g_adv_data; + cfg_adv_data.adv_length = HW_ADV_DATA_LEN; + + cfg_adv_data.scan_rsp_data = set_scan_rsp_data; + cfg_adv_data.scan_rsp_length = scan_rsp_data_len; + + osal_printk("[uplus][debug] uplus_ble_gap_adv_data_set adv_length=%x, adv_data=", + cfg_adv_data.adv_length); + for (int i = 0; i < cfg_adv_data.adv_length; i++) { + osal_printk(" %02x", cfg_adv_data.adv_data[i]); + } + osal_printk("\n[uplus][debug] uplus_ble_gap_adv_data_set scan_rsp_length=%x, scan_rsp_data=", + cfg_adv_data.scan_rsp_length); + for (int i = 0; i < cfg_adv_data.scan_rsp_length; i++) { + osal_printk(" %02x", cfg_adv_data.scan_rsp_data[i]); + } + osal_printk("\n"); + n_ret = gap_ble_set_adv_data(BTH_GAP_BLE_ADV_HANDLE_DEFAULT, &cfg_adv_data); + if (n_ret != 0) { + return 0; + } + return 0; +} + +uint8_t ble_wifi_cfg_start_adv(void) +{ + errcode_t n_ret = 0; + gap_ble_adv_params_t adv_para = {0}; + + ble_wifi_cfg_set_adv_data(); + adv_para.min_interval = BLE_ADV_MIN_INTERVAL; + adv_para.max_interval = BLE_ADV_MAX_INTERVAL; + adv_para.duration = BTH_GAP_BLE_ADV_FOREVER_DURATION; + adv_para.peer_addr.type = BLE_PUBLIC_DEVICE_ADDRESS; + /* 广播通道选择bitMap, 可参考BleAdvChannelMap */ + adv_para.channel_map = BLE_ADV_CHANNEL_MAP_CH_DEFAULT; + adv_para.adv_type = BLE_ADV_TYPE_CONNECTABLE_UNDIRECTED; + adv_para.adv_filter_policy = BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_ANY; + (void)memset_s(&adv_para.peer_addr.addr, BD_ADDR_LEN, 0, BD_ADDR_LEN); + n_ret = gap_ble_set_adv_param(BTH_GAP_BLE_ADV_HANDLE_DEFAULT, &adv_para); + if (n_ret != 0) { + return 0; + } + n_ret = gap_ble_start_adv(BTH_GAP_BLE_ADV_HANDLE_DEFAULT); + if (n_ret != 0) { + return 0; + } + return 0; +} diff --git a/application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_server.c b/application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_server.c new file mode 100755 index 0000000..60e0aa0 --- /dev/null +++ b/application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_server.c @@ -0,0 +1,367 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: ble wifi config server sample. + */ + +#include +#include +#include +#include +#include "osal_addr.h" +#include "osal_debug.h" +#include "bts_def.h" +#include "securec.h" +#include "errcode.h" +#include "bts_def.h" +#include "bts_le_gap.h" +#include "bts_gatt_stru.h" +#include "bts_gatt_server.h" +#include "ble_wifi_cfg_server.h" + +/* server app uuid for test */ +char g_app_uuid[] = {0x0, 0x0}; + +/* ble service att handle */ +uint16_t g_service_hdl; + +/* ble chara handle trans wifi cfg info */ +uint16_t g_chara_cfg_hdl = 0; + +/* ble chara handle trans wifi list req&resp */ +uint16_t g_chara_wifi_list_hdl = 0; + +/* ble indication att handle */ +uint16_t g_ind_crt_att_hdl = 0; + +/* ble notification att handle */ +uint16_t g_ntf_crt_att_hdl = 0; + +uint16_t g_descriptor_report_hdl = 0; +uint16_t g_descriptor_ctrl_hdl = 0; +uint16_t g_descriptor_cfg_hdl = 0; + +/* ble connect handle */ +uint16_t g_conn_handle = 0; + +#define OCTET_BIT_LEN 8 +#define UUID_LEN_2 2 +#define CCC_UUID 0x2902 + +/* Service UUID */ +#define BLE_WIFI_CFG_SERVICE 0xfd5c +/* Characteristic Control Information UUID */ +#define BLE_WIFI_CFG_CONTROL_INFO 0xfd5d +/* Client Characteristic Configuration Wi-Fi Information UUID */ +#define BLE_WIFI_CFG_INFORMATION 0xfd5e +/* Client AP Lists Req/Resp Configuration UUID */ +#define BLE_WIFI_CFG_REQ_REPORT 0xfd5f + +/* Client Characteristic Configuration UUID */ +#define BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION 0x2902 + +/* Server ID */ +#define BLE_WIFI_CFG_SERVER_ID 1 +/* Wifi Configure Write Characteristic */ +#define BLE_WIFI_CFG_CHARACTER_VALUE_1 0x12 +#define BLE_WIFI_CFG_CHARACTER_VALUE_2 0x34 +#define BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_0 0X00 +#define BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_2 0X02 + +extern void set_wifi_cfg_info(uint8_t *info, uint16_t info_len); +extern int bgwc_wifi_list_resp_send(uint16_t handle); + +/* 将uint16的uuid数字转化为bt_uuid_t */ +void streams_data_to_uuid(uint16_t uuid_data, bt_uuid_t *out_uuid) +{ + char uuid[] = {(uint8_t)(uuid_data >> OCTET_BIT_LEN), (uint8_t)uuid_data}; + out_uuid->uuid_len = UUID_LEN_2; + if (memcpy_s(out_uuid->uuid, out_uuid->uuid_len, uuid, UUID_LEN_2) != EOK) { + return; + } +} + +errcode_t service_uuid_compare(bt_uuid_t *uuid1, bt_uuid_t *uuid2) +{ + if (uuid1->uuid_len != uuid2->uuid_len) { + return ERRCODE_BT_FAIL; + } + if (memcmp(uuid1->uuid, uuid2->uuid, uuid1->uuid_len) != 0) { + return ERRCODE_BT_FAIL; + } + return ERRCODE_BT_SUCCESS; +} + +/* 开始服务回调 */ +static void ble_wifi_cfg_server_service_start_cbk(uint8_t server_id, uint16_t handle, errcode_t status) +{ + osal_printk("[wifi_cfg_server] start service cbk : server: %d status: %d srv_hdl: %d\n", server_id, status, + handle); +} + +static void ble_wifi_cfg_server_receive_write_req_cbk(uint8_t server_id, uint16_t conn_id, + gatts_req_write_cb_t *write_cb_para, errcode_t status) +{ + osal_printk("[wifi_cfg_server]ReceiveWriteReqCallback--server_id:%d conn_id:%d\n", server_id, conn_id); + osal_printk("request_id:%d att_handle:%d offset:%d need_rsp:%d need_authorize:%d is_prep:%d\n", + write_cb_para->request_id, write_cb_para->handle, write_cb_para->offset, write_cb_para->need_rsp, + write_cb_para->need_authorize, write_cb_para->is_prep); + osal_printk("data_len:%d data:\n", write_cb_para->length); + for (uint8_t i = 0; i < write_cb_para->length; i++) { + osal_printk("%02x ", write_cb_para->value[i]); + } + osal_printk("\n"); + osal_printk("status:%d\n", status); + + if (write_cb_para->handle == g_chara_cfg_hdl) { + set_wifi_cfg_info(write_cb_para->value, write_cb_para->length); + } + if (write_cb_para->handle == g_chara_wifi_list_hdl) { + bgwc_wifi_list_resp_send(write_cb_para->handle); + } +} + +static void ble_wifi_cfg_server_receive_read_req_cbk(uint8_t server_id, uint16_t conn_id, + gatts_req_read_cb_t *read_cb_para, errcode_t status) +{ + osal_printk("[wifi_cfg_server]ReceiveReadReq--server_id:%d conn_id:%d\n", server_id, conn_id); + osal_printk("request_id:%d att_handle:%d offset:%d need_rsp:%d need_authorize:%d is_long:%d\n", + read_cb_para->request_id, read_cb_para->handle, read_cb_para->offset, read_cb_para->need_rsp, + read_cb_para->need_authorize, read_cb_para->is_long); + osal_printk("status:%d\n", status); +} + +static void ble_wifi_cfg_server_adv_enable_cbk(uint8_t adv_id, adv_status_t status) +{ + osal_printk("adv enable adv_id: %d, status:%d\n", adv_id, status); +} + +static void ble_wifi_cfg_server_adv_disable_cbk(uint8_t adv_id, adv_status_t status) +{ + osal_printk("adv disable adv_id: %d, status:%d\n", adv_id, status); +} + +void ble_wifi_cfg_server_connect_change_cbk(uint16_t conn_id, bd_addr_t *addr, gap_ble_conn_state_t conn_state, + gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason) +{ + osal_printk("connect state change conn_id: %d, status: %d, pair_status:%d, addr %x disc_reason %x\n", + conn_id, conn_state, pair_state, addr[0], disc_reason); + g_conn_handle = conn_id; +} + +void ble_wifi_cfg_server_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status) +{ + osal_printk("mtu change change server_id: %d, conn_id: %d, mtu_size: %d, status:%d \n", server_id, conn_id, + mtu_size, status); +} + +void ble_wifi_cfg_server_enable_cbk(errcode_t status) +{ + osal_printk("enable status: %d\n", status); +} + +static errcode_t ble_wifi_cfg_server_register_callbacks(void) +{ + errcode_t ret; + gap_ble_callbacks_t gap_cb = { 0 }; + gatts_callbacks_t service_cb = { 0 }; + + gap_cb.start_adv_cb = ble_wifi_cfg_server_adv_enable_cbk; + gap_cb.stop_adv_cb = ble_wifi_cfg_server_adv_disable_cbk; + gap_cb.conn_state_change_cb = ble_wifi_cfg_server_connect_change_cbk; + gap_cb.ble_enable_cb = ble_wifi_cfg_server_enable_cbk; + ret = gap_ble_register_callbacks(&gap_cb); + if (ret != ERRCODE_BT_SUCCESS) { + osal_printk("[wifi_cfg_server] reg gap cbk failed\r\n"); + return ERRCODE_BT_FAIL; + } + + service_cb.start_service_cb = ble_wifi_cfg_server_service_start_cbk; + service_cb.read_request_cb = ble_wifi_cfg_server_receive_read_req_cbk; + service_cb.write_request_cb = ble_wifi_cfg_server_receive_write_req_cbk; + service_cb.mtu_changed_cb = ble_wifi_cfg_server_mtu_changed_cbk; + ret = gatts_register_callbacks(&service_cb); + if (ret != ERRCODE_BT_SUCCESS) { + osal_printk("[wifi_cfg_server] reg service cbk failed\r\n"); + return ERRCODE_BT_FAIL; + } + return ret; +} + +static void wifi_cfg_add_character_control_point(uint8_t server_id, uint16_t srvc_handle) +{ + gatts_add_chara_info_t character = { 0 }; + gatts_add_character_result_t add_character_result = { 0 }; + uint8_t character_value[] = {BLE_WIFI_CFG_CHARACTER_VALUE_1, BLE_WIFI_CFG_CHARACTER_VALUE_2}; + uint8_t ccc_value_indicate[UUID_LEN_2] = {BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_2, + BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_0}; + gatts_add_desc_info_t ccc = { { UUID_LEN_2, { 0 } }, + GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE, + UUID_LEN_2, + NULL }; + streams_data_to_uuid(BLE_WIFI_CFG_CONTROL_INFO, &character.chara_uuid); + character.properties = BLE_WIFI_CFG_PROPERTIES; + character.permissions = 0; + character.value_len = sizeof(character_value); + character.value = character_value; + gatts_add_characteristic_sync(server_id, srvc_handle, &character, &add_character_result); + + ccc.desc_uuid.uuid[0] = BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION >> 8; /* 8: octet bit num */ + ccc.desc_uuid.uuid[1] = (uint8_t)BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION; + ccc.value = ccc_value_indicate; + gatts_add_descriptor_sync(server_id, srvc_handle, &ccc, &g_descriptor_ctrl_hdl); +} + +static void wifi_cfg_add_character_cfg_info(uint8_t server_id, uint16_t srvc_handle) +{ + gatts_add_chara_info_t character = { 0 }; + gatts_add_character_result_t add_character_result = { 0 }; + uint8_t character_value[] = {BLE_WIFI_CFG_CHARACTER_VALUE_1, BLE_WIFI_CFG_CHARACTER_VALUE_2}; + uint8_t ccc_value_indicate[UUID_LEN_2] = {BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_2, + BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_0}; + gatts_add_desc_info_t ccc = { { UUID_LEN_2, { 0 } }, + GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE, + UUID_LEN_2, + NULL }; + + streams_data_to_uuid(BLE_WIFI_CFG_INFORMATION, &character.chara_uuid); + character.properties = UUID_SERVER_IND_PROPERTIES; + character.permissions = 0; + character.value_len = sizeof(character_value); + character.value = character_value; + gatts_add_characteristic_sync(server_id, srvc_handle, &character, &add_character_result); + g_chara_cfg_hdl = add_character_result.value_handle; + + ccc.desc_uuid.uuid[0] = BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION >> 8; /* 8: octet bit num */ + ccc.desc_uuid.uuid[1] = (uint8_t)BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION; + ccc.value = ccc_value_indicate; + gatts_add_descriptor_sync(server_id, srvc_handle, &ccc, &g_descriptor_cfg_hdl); +} + +static void wifi_cfg_add_character_req_report(uint8_t server_id, uint16_t srvc_handle) +{ + gatts_add_chara_info_t character = { 0 }; + gatts_add_character_result_t add_character_result = { 0 }; + uint8_t character_value[] = {BLE_WIFI_CFG_CHARACTER_VALUE_1, BLE_WIFI_CFG_CHARACTER_VALUE_2}; + uint8_t ccc_value_indicate[UUID_LEN_2] = {BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_2, + BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_0}; + gatts_add_desc_info_t ccc = { { UUID_LEN_2, { 0 } }, + GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE, + UUID_LEN_2, + NULL }; + streams_data_to_uuid(BLE_WIFI_CFG_REQ_REPORT, &character.chara_uuid); + character.properties = BLE_WIFI_CFG_PROPERTIES; + character.permissions = 0; + character.value_len = sizeof(character_value); + character.value = character_value; + gatts_add_characteristic_sync(server_id, srvc_handle, &character, &add_character_result); + g_chara_wifi_list_hdl = add_character_result.value_handle; + + ccc.desc_uuid.uuid[0] = BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION >> 8; /* 8: octet bit num */ + ccc.desc_uuid.uuid[1] = (uint8_t)BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION; + ccc.value = ccc_value_indicate; + gatts_add_descriptor_sync(server_id, srvc_handle, &ccc, &g_descriptor_report_hdl); +} + +errcode_t wifi_cfg_server_service(void) +{ + errcode_t ret; + osal_printk("[wifi_cfg_server] ble uuid add service in\r\n"); + + /* Add Wifi Configure Service */ + bt_uuid_t service_uuid = { 0 }; + streams_data_to_uuid(BLE_WIFI_CFG_SERVICE, &service_uuid); + ret = gatts_add_service_sync(BLE_WIFI_CFG_SERVER_ID, &service_uuid, true, &g_service_hdl); + if (ret != ERRCODE_BT_SUCCESS) { + osal_printk("[wifi_cfg_server_service] reg service failed, ret=%x\r\n", ret); + return ret; + } + + /* Configure Trans Control Info Characteristic */ + wifi_cfg_add_character_control_point(BLE_WIFI_CFG_SERVER_ID, g_service_hdl); + /* Configure Trans Wi-Fi Info Characteristic */ + wifi_cfg_add_character_cfg_info(BLE_WIFI_CFG_SERVER_ID, g_service_hdl); + /* Configure Trans Wi-Fi Req/Resp info Characteristic */ + wifi_cfg_add_character_req_report(BLE_WIFI_CFG_SERVER_ID, g_service_hdl); + + gatts_start_service(BLE_WIFI_CFG_SERVER_ID, g_service_hdl); + osal_printk("[wifi_cfg_server] ble uuid add service out\r\n"); + return ERRCODE_BT_SUCCESS; +} + +errcode_t ble_wifi_gatts_register_server(void) +{ + uint8_t server_handle; + bt_uuid_t app_uuid = { 0 }; + app_uuid.uuid_len = sizeof(g_app_uuid); + if (memcpy_s(app_uuid.uuid, app_uuid.uuid_len, g_app_uuid, sizeof(g_app_uuid)) != EOK) { + return ERRCODE_BT_FAIL; + } + + osal_printk("[wifi_cfg_server] gatts_register_server begin\r\n"); + return gatts_register_server(&app_uuid, &server_handle); +} + +/* 初始化ble wifi cfg server service */ +errcode_t ble_wifi_cfg_server_init(void) +{ + errcode_t ret = ERRCODE_BT_SUCCESS; + ret |= enable_ble(); + ret |= ble_wifi_cfg_server_register_callbacks(); + ret |= ble_wifi_gatts_register_server(); + ret |= wifi_cfg_server_service(); + if (ret != ERRCODE_BT_SUCCESS) { + osal_printk("[wifi_cfg_server] init fail.\r\n"); + } else { + osal_printk("[wifi_cfg_server] init ok\r\n"); + } + return ret; +} + +/* device通过uuid向host发送数据:report */ +errcode_t ble_wifi_cfg_server_send_report_by_uuid(const uint8_t *data, uint32_t len) +{ + gatts_ntf_ind_by_uuid_t param = { 0 }; + uint16_t conn_id = g_conn_handle; + param.start_handle = 0; + param.end_handle = 0xffff; + streams_data_to_uuid(BLE_WIFI_CFG_CONTROL_INFO, ¶m.chara_uuid); + param.value_len = len; + param.value = osal_vmalloc(len); + + if (param.value == NULL) { + osal_printk("[hid][ERROR]send report new fail\r\n"); + return ERRCODE_BT_FAIL; + } + if (memcpy_s(param.value, param.value_len, data, len) != EOK) { + osal_printk("[hid][ERROR]send input report memcpy fail\r\n"); + osal_vfree(param.value); + return ERRCODE_BT_FAIL; + } + gatts_notify_indicate_by_uuid(BLE_WIFI_CFG_SERVER_ID, conn_id, ¶m); + osal_vfree(param.value); + return ERRCODE_BT_SUCCESS; +} + +/* device通过handle向host发送数据:report */ +errcode_t ble_wifi_cfg_server_send_report_by_handle(uint16_t attr_handle, const uint8_t *data, uint8_t len) +{ + gatts_ntf_ind_t param = { 0 }; + uint16_t conn_id = g_conn_handle; + + param.attr_handle = attr_handle; + param.value = osal_vmalloc(len); + param.value_len = len; + + if (param.value == NULL) { + osal_printk("[hid][ERROR]send report new fail\r\n"); + return ERRCODE_BT_FAIL; + } + if (memcpy_s(param.value, param.value_len, data, len) != EOK) { + osal_printk("[hid][ERROR]send input report memcpy fail\r\n"); + osal_vfree(param.value); + return ERRCODE_BT_FAIL; + } + gatts_notify_indicate(BLE_WIFI_CFG_SERVER_ID, conn_id, ¶m); + osal_vfree(param.value); + return ERRCODE_BT_SUCCESS; +} diff --git a/application/samples/bt/sle/CMakeLists.txt b/application/samples/bt/sle/CMakeLists.txt new file mode 100755 index 0000000..3c3094e --- /dev/null +++ b/application/samples/bt/sle/CMakeLists.txt @@ -0,0 +1,22 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_SLE_UUID_SERVER_SAMPLE) + add_subdirectory_if_exist(sle_uuid_server) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_SLE_UUID_CLIENT_SAMPLE) + add_subdirectory_if_exist(sle_uuid_client) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_SLE_SPEED_SERVER_SAMPLE) + add_subdirectory_if_exist(sle_speed_server) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_SLE_SPEED_CLIENT_SAMPLE) + add_subdirectory_if_exist(sle_speed_client) +endif() + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/sle/Kconfig b/application/samples/bt/sle/Kconfig new file mode 100755 index 0000000..1e51278 --- /dev/null +++ b/application/samples/bt/sle/Kconfig @@ -0,0 +1,31 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + +choice + prompt "SLE Sample" + +config SAMPLE_SUPPORT_SLE_UUID_SERVER_SAMPLE + bool "Support SLE UUID Server Sample." + +config SAMPLE_SUPPORT_SLE_UUID_CLIENT_SAMPLE + bool "Support SLE UUID Client Sample." + +config SAMPLE_SUPPORT_SLE_SPEED_SERVER_SAMPLE + bool "Support SLE Throughput Server Sample." + +config LARGE_THROUGHPUT_SERVER + bool "server large throughput." + default y + depends on SAMPLE_SUPPORT_SLE_SPEED_SERVER_SAMPLE + +config SAMPLE_SUPPORT_SLE_SPEED_CLIENT_SAMPLE + bool "Support SLE Throughput Client Sample." + +config LARGE_THROUGHPUT_CLIENT + bool "client large throughput." + default y + depends on SAMPLE_SUPPORT_SLE_SPEED_CLIENT_SAMPLE + +endchoice \ No newline at end of file diff --git a/application/samples/bt/sle/sle_speed_client/CMakeLists.txt b/application/samples/bt/sle/sle_speed_client/CMakeLists.txt new file mode 100755 index 0000000..be2e0bc --- /dev/null +++ b/application/samples/bt/sle/sle_speed_client/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/sle/sle_speed_client/inc/sle_speed_client.h b/application/samples/bt/sle/sle_speed_client/inc/sle_speed_client.h new file mode 100755 index 0000000..4132e6f --- /dev/null +++ b/application/samples/bt/sle/sle_speed_client/inc/sle_speed_client.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * + * Description: SLE private service register sample of client. + */ + +/** + * @defgroup SLE UUID CLIENT API + * @ingroup + * @{ + */ + +#ifndef SLE_CLIENT_ADV_H +#define SLE_CLIENT_ADV_H + +/** + * @if Eng + * @brief sle uuid client init. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle uuid客户端初始化。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +void sle_client_init(ssapc_notification_callback notification_cb, ssapc_indication_callback indication_cb); + +/** + * @if Eng + * @brief sle start scan. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle启动扫描。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +void sle_start_scan(void); + +#endif \ No newline at end of file diff --git a/application/samples/bt/sle/sle_speed_client/src/CMakeLists.txt b/application/samples/bt/sle/sle_speed_client/src/CMakeLists.txt new file mode 100755 index 0000000..47489b8 --- /dev/null +++ b/application/samples/bt/sle/sle_speed_client/src/CMakeLists.txt @@ -0,0 +1,7 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/sle_speed_client.c" + PARENT_SCOPE) diff --git a/application/samples/bt/sle/sle_speed_client/src/sle_speed_client.c b/application/samples/bt/sle/sle_speed_client/src/sle_speed_client.c new file mode 100755 index 0000000..a4c5abf --- /dev/null +++ b/application/samples/bt/sle/sle_speed_client/src/sle_speed_client.c @@ -0,0 +1,376 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * + * Description: SLE private service register sample of client. + */ +#include "app_init.h" +#include "systick.h" +#include "tcxo.h" +#include "los_memory.h" +#include "securec.h" +#include "soc_osal.h" +#include "common_def.h" + +#include "sle_device_discovery.h" +#include "sle_connection_manager.h" +#include "sle_ssap_client.h" + +#include "sle_speed_client.h" + +#undef THIS_FILE_ID +#define THIS_FILE_ID BTH_GLE_SAMPLE_UUID_CLIENT + +#define SLE_MTU_SIZE_DEFAULT 1500 +#define SLE_SEEK_INTERVAL_DEFAULT 100 +#define SLE_SEEK_WINDOW_DEFAULT 100 +#define UUID_16BIT_LEN 2 +#define UUID_128BIT_LEN 16 +#define SLE_SPEED_HUNDRED 100 /* 100 */ +#define SPEED_DEFAULT_CONN_INTERVAL 0x14 +#define SPEED_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4 +#define SPEED_DEFAULT_SCAN_INTERVAL 400 +#define SPEED_DEFAULT_SCAN_WINDOW 20 + +static int g_recv_pkt_num = 0; +static uint64_t g_count_before_get_us; +static uint64_t g_count_after_get_us; + +#ifdef CONFIG_LARGE_THROUGHPUT_CLIENT +#define RECV_PKT_CNT 1000 +#else +#define RECV_PKT_CNT 1 +#endif +static int g_rssi_sum = 0; +static int g_rssi_number = 0; + +static sle_announce_seek_callbacks_t g_seek_cbk = {0}; +static sle_connection_callbacks_t g_connect_cbk = {0}; +static ssapc_callbacks_t g_ssapc_cbk = {0}; +static sle_addr_t g_remote_addr = {0}; +static uint16_t g_conn_id = 0; +static ssapc_find_service_result_t g_find_service_result = {0}; + +void sle_sample_sle_enable_cbk(errcode_t status) +{ + if (status == 0) { + sle_start_scan(); + } +} + +void sle_sample_seek_enable_cbk(errcode_t status) +{ + if (status == 0) { + return; + } +} + +void sle_sample_seek_disable_cbk(errcode_t status) +{ + if (status == 0) { + sle_connect_remote_device(&g_remote_addr); + } +} + +void sle_sample_seek_result_info_cbk(sle_seek_result_info_t *seek_result_data) +{ + if (seek_result_data != NULL) { + uint8_t mac[SLE_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + if (memcmp(seek_result_data->addr.addr, mac, SLE_ADDR_LEN) == 0) { + (void)memcpy_s(&g_remote_addr, sizeof(sle_addr_t), &seek_result_data->addr, sizeof(sle_addr_t)); + sle_stop_seek(); + } + } +} + +static uint32_t get_float_int(float in) +{ + return (uint32_t)(((uint64_t)(in * SLE_SPEED_HUNDRED)) / SLE_SPEED_HUNDRED); +} + +static uint32_t get_float_dec(float in) +{ + return (uint32_t)(((uint64_t)(in * SLE_SPEED_HUNDRED)) % SLE_SPEED_HUNDRED); +} + +static void sle_speed_notification_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, + errcode_t status) +{ + unused(client_id); + unused(status); + sle_read_remote_device_rssi(conn_id); // 用于统计rssi均值 + + if (g_recv_pkt_num == 0) { + g_count_before_get_us = uapi_tcxo_get_us(); + } else if (g_recv_pkt_num == RECV_PKT_CNT) { + g_count_after_get_us = uapi_tcxo_get_us(); + printf("g_count_after_get_us = %llu, g_count_before_get_us = %llu, data_len = %d\r\n", + g_count_after_get_us, g_count_before_get_us, data->data_len); + float time = (float)(g_count_after_get_us - g_count_before_get_us) / 1000000.0; /* 1s = 1000000.0us */ + printf("time = %d.%d s\r\n", get_float_int(time), get_float_dec(time)); + uint16_t len = data->data_len; + float speed = len * RECV_PKT_CNT * 8 / time; /* 1B = 8bits */ + printf("speed = %d.%d bps\r\n", get_float_int(speed), get_float_dec(speed)); + g_recv_pkt_num = 0; + g_count_before_get_us = g_count_after_get_us; + } + g_recv_pkt_num++; +} + +static void sle_speed_indication_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, + errcode_t status) +{ + unused(status); + unused(conn_id); + unused(client_id); + osal_printk("\n sle_speed_indication_cb sle uart recived data : %s\r\n", data->data); +} + +void sle_sample_seek_cbk_register(void) +{ + g_seek_cbk.sle_enable_cb = sle_sample_sle_enable_cbk; + g_seek_cbk.seek_enable_cb = sle_sample_seek_enable_cbk; + g_seek_cbk.seek_disable_cb = sle_sample_seek_disable_cbk; + g_seek_cbk.seek_result_cb = sle_sample_seek_result_info_cbk; +} + +void sle_sample_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) +{ + osal_printk("[ssap client] conn state changed conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], + addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + osal_printk("[ssap client] conn state changed disc_reason:0x%x\n", disc_reason); + if (conn_state == SLE_ACB_STATE_CONNECTED) { + if (pair_state == SLE_PAIR_NONE) { + sle_pair_remote_device(&g_remote_addr); + } + g_conn_id = conn_id; + } +} + +void sle_sample_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + osal_printk("[ssap client] pair complete conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], + addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + if (status == 0) { + ssap_exchange_info_t info = {0}; + info.mtu_size = SLE_MTU_SIZE_DEFAULT; + info.version = 1; + ssapc_exchange_info_req(1, g_conn_id, &info); + } +} + +void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) +{ + unused(status); + osal_printk("[ssap client] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); +} + +void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) +{ + unused(conn_id); + unused(status); + osal_printk("[ssap client] sle_sample_update_req_cbk interval_min = %02x, interval_max = %02x\n", + param->interval_min, param->interval_max); +} + +void sle_sample_read_rssi_cbk(uint16_t conn_id, int8_t rssi, errcode_t status) +{ + unused(conn_id); + unused(status); + g_rssi_sum = g_rssi_sum + rssi; + g_rssi_number++; + if (g_rssi_number == RECV_PKT_CNT) { + osal_printk("rssi average = %d dbm\r\n", g_rssi_sum / g_rssi_number); + g_rssi_sum = 0; + g_rssi_number = 0; + } +} + +void sle_sample_connect_cbk_register(void) +{ + g_connect_cbk.connect_state_changed_cb = sle_sample_connect_state_changed_cbk; + g_connect_cbk.pair_complete_cb = sle_sample_pair_complete_cbk; + g_connect_cbk.connect_param_update_req_cb = sle_sample_update_req_cbk; + g_connect_cbk.connect_param_update_cb = sle_sample_update_cbk; + g_connect_cbk.read_rssi_cb = sle_sample_read_rssi_cbk; +} + +void sle_sample_exchange_info_cbk(uint8_t client_id, uint16_t conn_id, ssap_exchange_info_t *param, + errcode_t status) +{ + osal_printk("[ssap client] pair complete client id:%d status:%d\n", client_id, status); + osal_printk("[ssap client] exchange mtu, mtu size: %d, version: %d.\n", + param->mtu_size, param->version); + + ssapc_find_structure_param_t find_param = {0}; + find_param.type = SSAP_FIND_TYPE_PRIMARY_SERVICE; + find_param.start_hdl = 1; + find_param.end_hdl = 0xFFFF; + ssapc_find_structure(0, conn_id, &find_param); +} + +void sle_sample_find_structure_cbk(uint8_t client_id, uint16_t conn_id, ssapc_find_service_result_t *service, + errcode_t status) +{ + osal_printk("[ssap client] find structure cbk client: %d conn_id:%d status: %d \n", + client_id, conn_id, status); + osal_printk("[ssap client] find structure start_hdl:[0x%02x], end_hdl:[0x%02x], uuid len:%d\r\n", + service->start_hdl, service->end_hdl, service->uuid.len); + if (service->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] structure uuid:[0x%02x][0x%02x]\r\n", + service->uuid.uuid[14], service->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] structure uuid[%d]:[0x%02x]\r\n", idx, service->uuid.uuid[idx]); + } + } + g_find_service_result.start_hdl = service->start_hdl; + g_find_service_result.end_hdl = service->end_hdl; + memcpy_s(&g_find_service_result.uuid, sizeof(sle_uuid_t), &service->uuid, sizeof(sle_uuid_t)); +} + +void sle_sample_find_structure_cmp_cbk(uint8_t client_id, uint16_t conn_id, + ssapc_find_structure_result_t *structure_result, errcode_t status) +{ + osal_printk("[ssap client] find structure cmp cbk client id:%d status:%d type:%d uuid len:%d \r\n", + client_id, status, structure_result->type, structure_result->uuid.len); + if (structure_result->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] find structure cmp cbk structure uuid:[0x%02x][0x%02x]\r\n", + structure_result->uuid.uuid[14], structure_result->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] find structure cmp cbk structure uuid[%d]:[0x%02x]\r\n", idx, + structure_result->uuid.uuid[idx]); + } + } + uint8_t data[] = {0x11, 0x22, 0x33, 0x44}; + uint8_t len = sizeof(data); + ssapc_write_param_t param = {0}; + param.handle = g_find_service_result.start_hdl; + param.type = SSAP_PROPERTY_TYPE_VALUE; + param.data_len = len; + param.data = data; + ssapc_write_req(0, conn_id, ¶m); +} + +void sle_sample_find_property_cbk(uint8_t client_id, uint16_t conn_id, + ssapc_find_property_result_t *property, errcode_t status) +{ + osal_printk("[ssap client] find property cbk, client id: %d, conn id: %d, operate ind: %d, " + "descriptors count: %d status:%d.\n", client_id, conn_id, property->operate_indication, + property->descriptors_count, status); + for (uint16_t idx = 0; idx < property->descriptors_count; idx++) { + osal_printk("[ssap client] find property cbk, descriptors type [%d]: 0x%02x.\n", + idx, property->descriptors_type[idx]); + } + if (property->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] find property cbk, uuid: %02x %02x.\n", + property->uuid.uuid[14], property->uuid.uuid[15]); /* 14 15: uuid index */ + } else if (property->uuid.len == UUID_128BIT_LEN) { + for (uint16_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] find property cbk, uuid [%d]: %02x.\n", + idx, property->uuid.uuid[idx]); + } + } +} + +void sle_sample_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_write_result_t *write_result, + errcode_t status) +{ + osal_printk("[ssap client] write cfm cbk, client id: %d status:%d.\n", client_id, status); + ssapc_read_req(0, conn_id, write_result->handle, write_result->type); +} + +void sle_sample_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *read_data, + errcode_t status) +{ + osal_printk("[ssap client] read cfm cbk client id: %d conn id: %d status: %d\n", + client_id, conn_id, status); + osal_printk("[ssap client] read cfm cbk handle: %d, type: %d , len: %d\n", + read_data->handle, read_data->type, read_data->data_len); + for (uint16_t idx = 0; idx < read_data->data_len; idx++) { + osal_printk("[ssap client] read cfm cbk[%d] 0x%02x\r\n", idx, read_data->data[idx]); + } +} + +void sle_sample_ssapc_cbk_register(ssapc_notification_callback notification_cb, + ssapc_notification_callback indication_cb) +{ + g_ssapc_cbk.exchange_info_cb = sle_sample_exchange_info_cbk; + g_ssapc_cbk.find_structure_cb = sle_sample_find_structure_cbk; + g_ssapc_cbk.find_structure_cmp_cb = sle_sample_find_structure_cmp_cbk; + g_ssapc_cbk.ssapc_find_property_cbk = sle_sample_find_property_cbk; + g_ssapc_cbk.write_cfm_cb = sle_sample_write_cfm_cbk; + g_ssapc_cbk.read_cfm_cb = sle_sample_read_cfm_cbk; + g_ssapc_cbk.notification_cb = notification_cb; + g_ssapc_cbk.indication_cb = indication_cb; +} + +void sle_speed_connect_param_init(void) +{ + sle_default_connect_param_t param = {0}; + param.enable_filter_policy = 0; + param.gt_negotiate = 0; + param.initiate_phys = 1; + param.max_interval = SPEED_DEFAULT_CONN_INTERVAL; + param.min_interval = SPEED_DEFAULT_CONN_INTERVAL; + param.scan_interval = SPEED_DEFAULT_SCAN_INTERVAL; + param.scan_window = SPEED_DEFAULT_SCAN_WINDOW; + param.timeout = SPEED_DEFAULT_TIMEOUT_MULTIPLIER; + sle_default_connection_param_set(¶m); +} + +void sle_client_init(ssapc_notification_callback notification_cb, ssapc_indication_callback indication_cb) +{ + uint8_t local_addr[SLE_ADDR_LEN] = {0x13, 0x67, 0x5c, 0x07, 0x00, 0x51}; + sle_addr_t local_address; + local_address.type = 0; + (void)memcpy_s(local_address.addr, SLE_ADDR_LEN, local_addr, SLE_ADDR_LEN); + sle_sample_seek_cbk_register(); + sle_speed_connect_param_init(); + sle_sample_connect_cbk_register(); + sle_sample_ssapc_cbk_register(notification_cb, indication_cb); + sle_announce_seek_register_callbacks(&g_seek_cbk); + sle_connection_register_callbacks(&g_connect_cbk); + ssapc_register_callbacks(&g_ssapc_cbk); + enable_sle(); + sle_set_local_addr(&local_address); +} + +void sle_start_scan() +{ + sle_seek_param_t param = {0}; + param.own_addr_type = 0; + param.filter_duplicates = 0; + param.seek_filter_policy = 0; + param.seek_phys = 1; + param.seek_type[0] = 0; + param.seek_interval[0] = SLE_SEEK_INTERVAL_DEFAULT; + param.seek_window[0] = SLE_SEEK_WINDOW_DEFAULT; + sle_set_seek_param(¶m); + sle_start_seek(); +} + +int sle_speed_init(void) +{ + osal_msleep(1000); /* sleep 1000ms */ + sle_client_init(sle_speed_notification_cb, sle_speed_indication_cb); + return 0; +} + +#define SLE_SPEED_TASK_PRIO 26 +#define SLE_SPEED_STACK_SIZE 0x2000 +static void sle_speed_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)sle_speed_init, 0, "RadarTask", SLE_SPEED_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, SLE_SPEED_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the blinky_entry. */ +app_run(sle_speed_entry); \ No newline at end of file diff --git a/application/samples/bt/sle/sle_speed_server/CMakeLists.txt b/application/samples/bt/sle/sle_speed_server/CMakeLists.txt new file mode 100755 index 0000000..be2e0bc --- /dev/null +++ b/application/samples/bt/sle/sle_speed_server/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/sle/sle_speed_server/inc/sle_speed_server.h b/application/samples/bt/sle/sle_speed_server/inc/sle_speed_server.h new file mode 100755 index 0000000..3f15bbe --- /dev/null +++ b/application/samples/bt/sle/sle_speed_server/inc/sle_speed_server.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * + * Description: SLE UUID Server module. + */ + +/** + * @defgroup SLE UUID SERVER API + * @ingroup + * @{ + */ +#ifndef SLE_UUID_SERVER_H +#define SLE_UUID_SERVER_H + +#include "sle_ssap_server.h" + +/* Service UUID */ +#define SLE_UUID_SERVER_SERVICE 0xABCD + +/* Property UUID */ +#define SLE_UUID_SERVER_NTF_REPORT 0x1122 + +/* Property Property */ +#define SLE_UUID_TEST_PROPERTIES (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + +/* Descriptor Property */ +#define SLE_UUID_TEST_DESCRIPTOR (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + +/** + * @if Eng + * @brief SLE uuid server inir. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief SLE UUID服务器初始化。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_init(void); + +/** + * @if Eng + * @brief send data to peer device by uuid on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_send_report_by_uuid(uint8_t *data, uint16_t len); + +/** + * @if Eng + * @brief send data to peer device by handle on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_send_report_by_handle(const uint8_t *data, uint8_t len); +#endif diff --git a/application/samples/bt/sle/sle_speed_server/inc/sle_speed_server_adv.h b/application/samples/bt/sle/sle_speed_server/inc/sle_speed_server_adv.h new file mode 100755 index 0000000..9f3515f --- /dev/null +++ b/application/samples/bt/sle/sle_speed_server/inc/sle_speed_server_adv.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * + * Description: SLE ADV Config. + */ + +/** + * @defgroup bluetooth_sle_adv API + * @ingroup + * @{ + */ + +#ifndef SLE_SERVER_ADV_H +#define SLE_SERVER_ADV_H + +/* 广播ID */ +#define SLE_ADV_HANDLE_DEFAULT 1 + +/** + * @if Eng + * @brief Definitaion of BLE ADV 通用广播结构. + * @else + * @brief SLE 广播普通数据结构。 + * @endif + */ +struct sle_adv_common_value { + uint8_t length; + uint8_t type; + uint8_t value; +}; + +/** + * @if Eng + * @brief Definitaion of BLE ADV Channel mapping. + * @else + * @brief SLE 广播信道映射。 + * @endif + */ +typedef enum { + SLE_ADV_CHANNEL_MAP_77 = 0x01, + SLE_ADV_CHANNEL_MAP_78 = 0x02, + SLE_ADV_CHANNEL_MAP_79 = 0x04, + SLE_ADV_CHANNEL_MAP_DEFAULT = 0x07 +} sle_adv_channel_map; + +/** + * @if Eng + * @brief Definitaion of SLE ADV Data Type. + * @else + * @brief SLE 广播数据类型 + * @endif + */ +typedef enum { + SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL = 0x01, /*!< 发现等级 */ + SLE_ADV_DATA_TYPE_ACCESS_MODE = 0x02, /*!< 接入层能力 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_16BIT_UUID = 0x03, /*!< 标准服务数据信息 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_128BIT_UUID = 0x04, /*!< 自定义服务数据信息 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x05, /*!< 完整标准服务标识列表 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x06, /*!< 完整自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x07, /*!< 部分标准服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x08, /*!< 部分自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_SERVICE_STRUCTURE_HASH_VALUE = 0x09, /*!< 服务结构散列值 */ + SLE_ADV_DATA_TYPE_SHORTENED_LOCAL_NAME = 0x0A, /*!< 设备缩写本地名称 */ + SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME = 0x0B, /*!< 设备完整本地名称 */ + SLE_ADV_DATA_TYPE_TX_POWER_LEVEL = 0x0C, /*!< 广播发送功率 */ + SLE_ADV_DATA_TYPE_SLB_COMMUNICATION_DOMAIN = 0x0D, /*!< SLB通信域域名 */ + SLE_ADV_DATA_TYPE_SLB_MEDIA_ACCESS_LAYER_ID = 0x0E, /*!< SLB媒体接入层标识 */ + SLE_ADV_DATA_TYPE_EXTENDED = 0xFE, /*!< 数据类型扩展 */ + SLE_ADV_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF /*!< 厂商自定义信息 */ +} sle_adv_data_type; + + +/** + * @if Eng + * @brief sle adv data config. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle广播数据配置。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +errcode_t sle_uuid_server_adv_init(void); +#endif \ No newline at end of file diff --git a/application/samples/bt/sle/sle_speed_server/src/CMakeLists.txt b/application/samples/bt/sle/sle_speed_server/src/CMakeLists.txt new file mode 100755 index 0000000..9a6d6eb --- /dev/null +++ b/application/samples/bt/sle/sle_speed_server/src/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/sle_speed_server_adv.c" + "${CMAKE_CURRENT_SOURCE_DIR}/sle_speed_server.c" + PARENT_SCOPE) diff --git a/application/samples/bt/sle/sle_speed_server/src/sle_speed_server.c b/application/samples/bt/sle/sle_speed_server/src/sle_speed_server.c new file mode 100755 index 0000000..f0179d6 --- /dev/null +++ b/application/samples/bt/sle/sle_speed_server/src/sle_speed_server.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: sle uuid server sample. + */ +#include "app_init.h" +#include "watchdog.h" +#include "tcxo.h" +#include "systick.h" +#include "los_memory.h" +#include "securec.h" +#include "errcode.h" +#include "osal_addr.h" +#include "soc_osal.h" +#include "common_def.h" + +#include "sle_common.h" +#include "sle_errcode.h" +#include "sle_ssap_server.h" +#include "sle_connection_manager.h" +#include "sle_device_discovery.h" +#include "sle_transmition_manager.h" +#include "nv.h" + +#include "sle_speed_server_adv.h" +#include "sle_speed_server.h" + +#define OCTET_BIT_LEN 8 +#define UUID_LEN_2 2 +#define BT_INDEX_4 4 +#define BT_INDEX_5 5 +#define BT_INDEX_0 0 +extern void send_data_thread_function(void); +#define encode2byte_little(_ptr, data) \ + do { \ + *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 8); \ + *(uint8_t *)(_ptr) = (uint8_t)(data); \ + } while (0) + +/* sle server app uuid for test */ +static char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x0, 0x0}; +/* server notify property uuid for test */ +static char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +/* sle connect acb handle */ +static uint16_t g_sle_conn_hdl = 0; +/* sle server handle */ +static uint8_t g_server_id = 0; +/* sle service handle */ +static uint16_t g_service_handle = 0; +/* sle ntf property handle */ +static uint16_t g_property_handle = 0; +#ifdef SLE_QOS_FLOWCTRL_FUNCTION_SWITCH +static sle_link_qos_state_t g_sle_link_state = 0; /* sle link state */ +#endif + +#ifdef CONFIG_LARGE_THROUGHPUT_SERVER +#define PKT_DATA_LEN 1200 +#define SPEED_DEFAULT_CONN_INTERVAL 0x14 +#else +#define PKT_DATA_LEN 600 +#define SPEED_DEFAULT_CONN_INTERVAL 0xA0 +#endif + +#define SPEED_DEFAULT_KTHREAD_SIZE 0x2000 +#define SPEED_DEFAULT_KTHREAD_PROI 26 +#define DEFAULT_SLE_SPEED_DATA_LEN 1500 +#define DEFAULT_SLE_SPEED_MTU_SIZE 1500 +#define SPEED_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4 +#define SPEED_DEFAULT_SCAN_INTERVAL 400 +#define SPEED_DEFAULT_SCAN_WINDOW 20 +static unsigned char data[PKT_DATA_LEN]; + +static uint8_t sle_uuid_base[] = { 0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, \ + 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +static void sle_uuid_set_base(sle_uuid_t *out) +{ + (void)memcpy_s(out->uuid, SLE_UUID_LEN, sle_uuid_base, SLE_UUID_LEN); + out->len = UUID_LEN_2; +} + +static void sle_uuid_setu2(uint16_t u2, sle_uuid_t *out) +{ + sle_uuid_set_base(out); + out->len = UUID_LEN_2; + encode2byte_little(&out->uuid[14], u2); +} + +static void ssaps_read_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_read_cb_t *read_cb_para, + errcode_t status) +{ + osal_printk("[speed server] ssaps read request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n", + server_id, conn_id, read_cb_para->handle, status); + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)send_data_thread_function, + 0, "RadarTask", SPEED_DEFAULT_KTHREAD_SIZE); + osal_kthread_set_priority(task_handle, SPEED_DEFAULT_KTHREAD_PROI + 1); + if (task_handle != NULL) { + osal_kfree(task_handle); + } + osal_kthread_unlock(); + printf("kthread success\r\n"); +} + +static void ssaps_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para, + errcode_t status) +{ + osal_printk("[speed server] ssaps write request cbk server_id:%d, conn_id:%d, handle:%d, status:%d\r\n", + server_id, conn_id, write_cb_para->handle, status); +} + +static void ssaps_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, ssap_exchange_info_t *mtu_size, + errcode_t status) +{ + osal_printk("[speed server] ssaps write request cbk server_id:%d, conn_id:%d, mtu_size:%d, status:%d\r\n", + server_id, conn_id, mtu_size->mtu_size, status); +} + +static void ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status) +{ + osal_printk("[speed server] start service cbk server_id:%d, handle:%d, status:%d\r\n", + server_id, handle, status); +} + +static void sle_ssaps_register_cbks(void) +{ + ssaps_callbacks_t ssaps_cbk = {0}; + ssaps_cbk.start_service_cb = ssaps_start_service_cbk; + ssaps_cbk.mtu_changed_cb = ssaps_mtu_changed_cbk; + ssaps_cbk.read_request_cb = ssaps_read_request_cbk; + ssaps_cbk.write_request_cb = ssaps_write_request_cbk; + ssaps_register_callbacks(&ssaps_cbk); +} + +errcode_t sle_uuid_server_send_report_by_handle_id(uint8_t *data, uint16_t len, uint16_t connect_id) +{ + ssaps_ntf_ind_t param = {0}; + param.handle = g_property_handle; + param.type = SSAP_PROPERTY_TYPE_VALUE; + param.value = data; + param.value_len = len; + ssaps_notify_indicate(g_server_id, connect_id, ¶m); + return ERRCODE_SLE_SUCCESS; +} + +#ifdef SLE_QOS_FLOWCTRL_FUNCTION_SWITCH +static void sle_send_data_cbk(uint16_t conn_id, sle_link_qos_state_t link_state) +{ + conn_id = conn_id; + g_sle_link_state = link_state; + printf("%s enter, gle_tx_acb_data_num_get:%d.\n", __FUNCTION__, link_state); +} + +static void sle_transmission_register_cbks(void) +{ + sle_transmission_callbacks_t trans_cbk = {0}; + trans_cbk.send_data_cb = sle_send_data_cbk; + sle_transmission_register_callbacks(&trans_cbk); +} +#else +extern uint8_t gle_tx_acb_data_num_get(void); +#endif + +uint8_t sle_flow_ctrl_flag(void) +{ +#ifdef SLE_QOS_FLOWCTRL_FUNCTION_SWITCH + return (g_sle_link_state <= SLE_QOS_FLOWCTRL) ? 1 : 0; +#else + return gle_tx_acb_data_num_get(); +#endif +} + +void send_data_thread_function(void) +{ + sle_set_data_len(g_sle_conn_hdl, DEFAULT_SLE_SPEED_DATA_LEN); +#ifdef CONFIG_LARGE_THROUGHPUT_SERVER +#define DEFAULT_SLE_SPEED_MCS 10 + sle_set_phy_t phy_parm = { + .tx_format = SLE_RADIO_FRAME_2, + .rx_format = SLE_RADIO_FRAME_2, + .tx_phy = SLE_PHY_4M, + .rx_phy = SLE_PHY_4M, + .tx_pilot_density = SLE_PHY_PILOT_DENSITY_16_TO_1, + .rx_pilot_density = SLE_PHY_PILOT_DENSITY_16_TO_1, + .g_feedback = 0, + .t_feedback = 0, + }; + sle_set_phy_param(g_sle_conn_hdl, &phy_parm); + sle_set_mcs(g_sle_conn_hdl, DEFAULT_SLE_SPEED_MCS); + osal_printk("code: ploar MCS10, PHY 4MHZ, power: 20dbm \r\n"); +#else + osal_printk("code: GFSK, PHY 1MHZ, power: 20dbm \r\n"); +#endif + int i = 0; + while (1) { + if (sle_flow_ctrl_flag() > 0) { + i++; + data[0] = (i >> 8) & 0xFF; /* offset 8bits */ + data[1] = i & 0xFF; + sle_uuid_server_send_report_by_handle_id(data, PKT_DATA_LEN, g_sle_conn_hdl); + } +#ifndef CONFIG_LARGE_THROUGHPUT_SERVER + osal_msleep(1000); /* sleep 1000ms */ + i = 0; +#endif + } +} + +static errcode_t sle_uuid_server_service_add(void) +{ + errcode_t ret; + sle_uuid_t service_uuid = {0}; + sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid); + ret = ssaps_add_service_sync(g_server_id, &service_uuid, 1, &g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[speed server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + return ERRCODE_SLE_SUCCESS; +} + +static errcode_t sle_uuid_server_property_add(void) +{ + errcode_t ret; + ssaps_property_info_t property = {0}; + ssaps_desc_info_t descriptor = {0}; + uint8_t ntf_value[] = {0x01, 0x0}; + + property.permissions = SLE_UUID_TEST_PROPERTIES; + sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &property.uuid); + property.value = osal_vmalloc(sizeof(g_sle_property_value)); + property.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_NOTIFY; + if (property.value == NULL) { + osal_printk("[speed server] sle property mem fail\r\n"); + return ERRCODE_SLE_FAIL; + } + if (memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, + sizeof(g_sle_property_value)) != EOK) { + osal_vfree(property.value); + osal_printk("[speed server] sle property mem cpy fail\r\n"); + return ERRCODE_SLE_FAIL; + } + ret = ssaps_add_property_sync(g_server_id, g_service_handle, &property, &g_property_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[speed server] sle uuid add property fail, ret:%x\r\n", ret); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + descriptor.permissions = SLE_UUID_TEST_DESCRIPTOR; + descriptor.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_WRITE; + descriptor.type = SSAP_DESCRIPTOR_USER_DESCRIPTION; + descriptor.value = ntf_value; + descriptor.value_len = sizeof(ntf_value); + + ret = ssaps_add_descriptor_sync(g_server_id, g_service_handle, g_property_handle, &descriptor); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[speed server] sle uuid add descriptor fail, ret:%x\r\n", ret); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + osal_vfree(property.value); + return ERRCODE_SLE_SUCCESS; +} + +static errcode_t sle_uuid_server_add(void) +{ + errcode_t ret; + sle_uuid_t app_uuid = {0}; + + osal_printk("[speed server] sle uuid add service in\r\n"); + app_uuid.len = sizeof(g_sle_uuid_app_uuid); + if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)) != EOK) { + return ERRCODE_SLE_FAIL; + } + ssaps_register_server(&app_uuid, &g_server_id); + + if (sle_uuid_server_service_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + + if (sle_uuid_server_property_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + osal_printk("[speed server] sle uuid add service, server_id:%x, service_handle:%x, property_handle:%x\r\n", + g_server_id, g_service_handle, g_property_handle); + ret = ssaps_start_service(g_server_id, g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[speed server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + osal_printk("[speed server] sle uuid add service out\r\n"); + return ERRCODE_SLE_SUCCESS; +} + +static void sle_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) +{ + osal_printk("[speed server] connect state changed conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \ + disc_reason:0x%x\r\n", conn_id, conn_state, pair_state, disc_reason); + osal_printk("[speed server] connect state changed addr:%02x:**:**:**:%02x:%02x\r\n", + addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); + g_sle_conn_hdl = conn_id; + sle_connection_param_update_t parame = {0}; + parame.conn_id = conn_id; + parame.interval_min = SPEED_DEFAULT_CONN_INTERVAL; + parame.interval_max = SPEED_DEFAULT_CONN_INTERVAL; + parame.max_latency = 0; + parame.supervision_timeout = SPEED_DEFAULT_TIMEOUT_MULTIPLIER; + if (conn_state == SLE_ACB_STATE_CONNECTED) { + sle_update_connect_param(¶me); + } else if (conn_state == SLE_ACB_STATE_DISCONNECTED) { + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); + } +} + +static void sle_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + osal_printk("[speed server] pair complete conn_id:%02x, status:%x\r\n", + conn_id, status); + osal_printk("[speed server] pair complete addr:%02x:**:**:**:%02x:%02x\r\n", + addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); +} + +void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) +{ + unused(status); + osal_printk("[ssap server] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); +} + +void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) +{ + unused(conn_id); + unused(status); + osal_printk("[ssap server] sle_sample_update_req_cbk interval_min:%02x, interval_max:%02x\n", + param->interval_min, param->interval_max); +} + +void sle_sample_rssi_cbk(uint16_t conn_id, int8_t rssi, errcode_t status) +{ + osal_printk("[ssap server] conn_id:%d, rssi = %c, status = %x\n", conn_id, rssi, status); +} + +static void sle_conn_register_cbks(void) +{ + sle_connection_callbacks_t conn_cbks = {0}; + conn_cbks.connect_state_changed_cb = sle_connect_state_changed_cbk; + conn_cbks.pair_complete_cb = sle_pair_complete_cbk; + conn_cbks.connect_param_update_req_cb = sle_sample_update_req_cbk; + conn_cbks.connect_param_update_cb = sle_sample_update_cbk; + conn_cbks.read_rssi_cb = sle_sample_rssi_cbk; + sle_connection_register_callbacks(&conn_cbks); +} + +void sle_ssaps_set_info(void) +{ + ssap_exchange_info_t info = {0}; + info.mtu_size = DEFAULT_SLE_SPEED_MTU_SIZE; + info.version = 1; + ssaps_set_info(g_server_id, &info); +} + +void sle_speed_connect_param_init(void) +{ + sle_default_connect_param_t param = {0}; + param.enable_filter_policy = 0; + param.gt_negotiate = 0; + param.initiate_phys = 1; + param.max_interval = SPEED_DEFAULT_CONN_INTERVAL; + param.min_interval = SPEED_DEFAULT_CONN_INTERVAL; + param.scan_interval = SPEED_DEFAULT_SCAN_INTERVAL; + param.scan_window = SPEED_DEFAULT_SCAN_WINDOW; + param.timeout = SPEED_DEFAULT_TIMEOUT_MULTIPLIER; + sle_default_connection_param_set(¶m); +} + +void sle_set_local_addr_init(void) +{ + sle_addr_t addr = {0}; + uint8_t mac[SLE_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + addr.type = 0; + memcpy_s(addr.addr, SLE_ADDR_LEN, mac, SLE_ADDR_LEN); + sle_set_local_addr(&addr); +} + +void sle_speed_server_set_nv(void) +{ + uint16_t nv_value_len = 0; + uint8_t nv_value = 0; + uapi_nv_read(0x20A0, sizeof(uint16_t), &nv_value_len, &nv_value); + if (nv_value != 7) { // 7:btc功率档位 + nv_value = 7; // 7:btc功率档位 + uapi_nv_write(0x20A0, (uint8_t *)&(nv_value), sizeof(nv_value)); + } + osal_printk("[speed server] The value of nv is set to %d.\r\n", nv_value); +} + +/* 初始化speed server */ +errcode_t sle_speed_server_init(void) +{ + uapi_watchdog_disable(); + enable_sle(); + printf("sle enable\r\n"); + sle_speed_server_set_nv(); + sle_conn_register_cbks(); + sle_ssaps_register_cbks(); + sle_uuid_server_add(); + sle_uuid_server_adv_init(); + sle_ssaps_set_info(); +#ifdef SLE_QOS_FLOWCTRL_FUNCTION_SWITCH + sle_transmission_register_cbks(); +#endif + sle_speed_connect_param_init(); + sle_set_local_addr_init(); + osal_printk("[speed server] init ok\r\n"); + return ERRCODE_SLE_SUCCESS; +} + +int sle_speed_init(void) +{ + for (int i = 0; i < PKT_DATA_LEN; i++) { + data[i] = 'A'; + data[PKT_DATA_LEN - 1] = '\0'; + } + osal_msleep(1000); /* sleep 1000ms */ + sle_speed_server_init(); + return 0; +} + +static void sle_speed_entry(void) +{ + osal_task *task_handle1 = NULL; + osal_kthread_lock(); + task_handle1= osal_kthread_create((osal_kthread_handler)sle_speed_init, 0, "speed", SPEED_DEFAULT_KTHREAD_SIZE); + if (task_handle1 != NULL) { + osal_kthread_set_priority(task_handle1, SPEED_DEFAULT_KTHREAD_PROI); + osal_kfree(task_handle1); + } + osal_kthread_unlock(); +} + +/* Run the blinky_entry. */ +app_run(sle_speed_entry); + diff --git a/application/samples/bt/sle/sle_speed_server/src/sle_speed_server_adv.c b/application/samples/bt/sle/sle_speed_server/src/sle_speed_server_adv.c new file mode 100755 index 0000000..6fc9ff2 --- /dev/null +++ b/application/samples/bt/sle/sle_speed_server/src/sle_speed_server_adv.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved. + * Description: sle adv config for sle uuid server. + */ +#include "securec.h" +#include "errcode.h" +#include "osal_addr.h" +#include "osal_debug.h" +#include "sle_common.h" +#include "sle_device_discovery.h" +#include "sle_connection_manager.h" +#include "sle_errcode.h" +#include "sle_speed_server_adv.h" + +/* sle device name */ +#define NAME_MAX_LENGTH 15 +/* 连接调度间隔12.5ms,单位125us */ +#define SLE_CONN_INTV_MIN_DEFAULT 0xA +/* 连接调度间隔12.5ms,单位125us */ +#define SLE_CONN_INTV_MAX_DEFAULT 0xA +/* 连接调度间隔25ms,单位125us */ +#define SLE_ADV_INTERVAL_MIN_DEFAULT 0xC8 +/* 连接调度间隔25ms,单位125us */ +#define SLE_ADV_INTERVAL_MAX_DEFAULT 0xC8 +/* 超时时间5000ms,单位10ms */ +#define SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT 0x1F4 +/* 超时时间4990ms,单位10ms */ +#define SLE_CONN_MAX_LATENCY 0x1F3 +/* 广播发送功率 */ +#define SLE_ADV_TX_POWER 20 +/* 最大广播数据长度 */ +#define SLE_ADV_DATA_LEN_MAX 251 + +uint8_t sle_local_name[ NAME_MAX_LENGTH] = "sle_uart_server"; + +static uint16_t sle_set_adv_local_name(uint8_t *adv_data, uint16_t max_len) +{ + errno_t ret; + uint8_t index = 0; + + uint8_t *local_name = sle_local_name; + uint8_t local_name_len = (uint8_t)strlen((char *)local_name); + for (uint8_t i = 0; i < local_name_len; i++) { + osal_printk("local_name[%d] = 0x%02x\r\n", i, local_name[i]); + } + + adv_data[index++] = local_name_len + 1; + adv_data[index++] = SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME; + ret = memcpy_s(&adv_data[index], max_len - index, local_name, local_name_len); + if (ret != EOK) { + osal_printk("memcpy fail\r\n"); + return 0; + } + return (uint16_t)index + local_name_len; +} + +static uint16_t sle_set_adv_data(uint8_t *adv_data) +{ + size_t len = 0; + uint16_t idx = 0; + errno_t ret = 0; + + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_disc_level = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL, + .value = SLE_ANNOUNCE_LEVEL_NORMAL, + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_disc_level, len); + if (ret != EOK) { + osal_printk("adv_disc_level memcpy fail\r\n"); + return 0; + } + idx += len; + + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_access_mode = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_ACCESS_MODE, + .value = 0, + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_access_mode, len); + if (ret != EOK) { + osal_printk("memcpy fail\r\n"); + return 0; + } + idx += len; + return idx; +} + +static uint16_t sle_set_scan_response_data(uint8_t *scan_rsp_data) +{ + uint16_t idx = 0; + errno_t ret; + size_t scan_rsp_data_len = sizeof(struct sle_adv_common_value); + + struct sle_adv_common_value tx_power_level = { + .length = scan_rsp_data_len - 1, + .type = SLE_ADV_DATA_TYPE_TX_POWER_LEVEL, + .value = SLE_ADV_TX_POWER, + }; + ret = memcpy_s(scan_rsp_data, SLE_ADV_DATA_LEN_MAX, &tx_power_level, scan_rsp_data_len); + if (ret != EOK) { + osal_printk("sle scan response data memcpy fail\r\n"); + return 0; + } + idx += scan_rsp_data_len; + + /* set local name */ + idx += sle_set_adv_local_name(&scan_rsp_data[idx], SLE_ADV_DATA_LEN_MAX - idx); + return idx; +} + +static int sle_set_default_announce_param(void) +{ + sle_announce_param_t param = {0}; + uint8_t mac[SLE_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + param.announce_mode = SLE_ANNOUNCE_MODE_CONNECTABLE_SCANABLE; + param.announce_handle = SLE_ADV_HANDLE_DEFAULT; + param.announce_gt_role = SLE_ANNOUNCE_ROLE_T_CAN_NEGO; + param.announce_level = SLE_ANNOUNCE_LEVEL_NORMAL; + param.announce_channel_map = SLE_ADV_CHANNEL_MAP_DEFAULT; + param.announce_interval_min = SLE_ADV_INTERVAL_MIN_DEFAULT; + param.announce_interval_max = SLE_ADV_INTERVAL_MAX_DEFAULT; + param.conn_interval_min = SLE_CONN_INTV_MIN_DEFAULT; + param.conn_interval_max = SLE_CONN_INTV_MAX_DEFAULT; + param.conn_max_latency = SLE_CONN_MAX_LATENCY; + param.conn_supervision_timeout = SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT; + param.announce_tx_power = SLE_ADV_TX_POWER; + param.own_addr.type = 0; + memcpy_s(param.own_addr.addr, SLE_ADDR_LEN, mac, SLE_ADDR_LEN); + return sle_set_announce_param(param.announce_handle, ¶m); +} + +static int sle_set_default_announce_data(void) +{ + errcode_t ret; + uint8_t announce_data_len = 0; + uint8_t seek_data_len = 0; + sle_announce_data_t data = {0}; + uint8_t adv_handle = SLE_ADV_HANDLE_DEFAULT; + uint8_t announce_data[SLE_ADV_DATA_LEN_MAX] = {0}; + uint8_t seek_rsp_data[SLE_ADV_DATA_LEN_MAX] = {0}; + + osal_printk("set adv data default\r\n"); + announce_data_len = sle_set_adv_data(announce_data); + data.announce_data = announce_data; + data.announce_data_len = announce_data_len; + + seek_data_len = sle_set_scan_response_data(seek_rsp_data); + data.seek_rsp_data = seek_rsp_data; + data.seek_rsp_data_len = seek_data_len; + + ret = sle_set_announce_data(adv_handle, &data); + if (ret == ERRCODE_SLE_SUCCESS) { + osal_printk("[SLE DD SDK] set announce data success."); + } else { + osal_printk("[SLE DD SDK] set adv param fail."); + } + return ERRCODE_SLE_SUCCESS; +} + +void sle_announce_enable_cbk(uint32_t announce_id, errcode_t status) +{ + osal_printk("sle announce enable id:%02x, state:%02x\r\n", announce_id, status); +} + +void sle_announce_disable_cbk(uint32_t announce_id, errcode_t status) +{ + osal_printk("sle announce disable id:%02x, state:%02x\r\n", announce_id, status); +} + +void sle_announce_terminal_cbk(uint32_t announce_id) +{ + osal_printk("sle announce terminal id:%02x\r\n", announce_id); +} + +void sle_enable_cbk(errcode_t status) +{ + osal_printk("sle enable status:%02x\r\n", status); +} + +void sle_announce_register_cbks(void) +{ + sle_announce_seek_callbacks_t seek_cbks = {0}; + seek_cbks.announce_enable_cb = sle_announce_enable_cbk; + seek_cbks.announce_disable_cb = sle_announce_disable_cbk; + seek_cbks.announce_terminal_cb = sle_announce_terminal_cbk; + seek_cbks.sle_enable_cb = sle_enable_cbk; + sle_announce_seek_register_callbacks(&seek_cbks); +} + +errcode_t sle_uuid_server_adv_init(void) +{ + osal_printk("sle_uuid_server_adv_init in\r\n"); + + sle_announce_register_cbks(); + sle_set_default_announce_param(); + sle_set_default_announce_data(); + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); + osal_printk("sle_uuid_server_adv_init out\r\n"); + return ERRCODE_SLE_SUCCESS; +} diff --git a/application/samples/bt/sle/sle_uuid_client/CMakeLists.txt b/application/samples/bt/sle/sle_uuid_client/CMakeLists.txt new file mode 100755 index 0000000..6e00cb6 --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_client/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/sle/sle_uuid_client/inc/sle_uuid_client.h b/application/samples/bt/sle/sle_uuid_client/inc/sle_uuid_client.h new file mode 100755 index 0000000..f7d9957 --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_client/inc/sle_uuid_client.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * + * Description: SLE private service register sample of client. + */ + +/** + * @defgroup SLE UUID CLIENT API + * @ingroup + * @{ + */ + +#ifndef SLE_CLIENT_ADV_H +#define SLE_CLIENT_ADV_H + +/** + * @if Eng + * @brief sle uuid client init. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle uuid客户端初始化。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +void sle_client_init(void); + +/** + * @if Eng + * @brief sle start scan. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle启动扫描。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +void sle_start_scan(void); + +#endif \ No newline at end of file diff --git a/application/samples/bt/sle/sle_uuid_client/src/CMakeLists.txt b/application/samples/bt/sle/sle_uuid_client/src/CMakeLists.txt new file mode 100755 index 0000000..c74179a --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_client/src/CMakeLists.txt @@ -0,0 +1,7 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/sle_uuid_client.c" + PARENT_SCOPE) diff --git a/application/samples/bt/sle/sle_uuid_client/src/sle_uuid_client.c b/application/samples/bt/sle/sle_uuid_client/src/sle_uuid_client.c new file mode 100755 index 0000000..eb82473 --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_client/src/sle_uuid_client.c @@ -0,0 +1,249 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved. + * + * Description: SLE private service register sample of client. + */ +#include "securec.h" +#include "soc_osal.h" +#include "app_init.h" +#include "sle_device_discovery.h" +#include "sle_connection_manager.h" +#include "sle_ssap_client.h" +#include "sle_uuid_client.h" + +#undef THIS_FILE_ID +#define THIS_FILE_ID BTH_GLE_SAMPLE_UUID_CLIENT + +#define SLE_MTU_SIZE_DEFAULT 300 +#define SLE_SEEK_INTERVAL_DEFAULT 100 +#define SLE_SEEK_WINDOW_DEFAULT 100 +#define UUID_16BIT_LEN 2 +#define UUID_128BIT_LEN 16 + +sle_announce_seek_callbacks_t g_seek_cbk = {0}; +sle_connection_callbacks_t g_connect_cbk = {0}; +ssapc_callbacks_t g_ssapc_cbk = {0}; +sle_addr_t g_remote_addr = {0}; +uint16_t g_conn_id = 0; +ssapc_find_service_result_t g_find_service_result = {0}; + +void sle_sample_sle_enable_cbk(errcode_t status) +{ + if (status == 0) { + sle_start_scan(); + } +} + +void sle_sample_seek_enable_cbk(errcode_t status) +{ + if (status == 0) { + return; + } +} + +void sle_sample_seek_disable_cbk(errcode_t status) +{ + if (status == 0) { + sle_connect_remote_device(&g_remote_addr); + } +} + +void sle_sample_seek_result_info_cbk(sle_seek_result_info_t *seek_result_data) +{ + if (seek_result_data != NULL) { + (void)memcpy_s(&g_remote_addr, sizeof(sle_addr_t), &seek_result_data->addr, sizeof(sle_addr_t)); + sle_stop_seek(); + } +} + +void sle_sample_seek_cbk_register(void) +{ + g_seek_cbk.sle_enable_cb = sle_sample_sle_enable_cbk; + g_seek_cbk.seek_enable_cb = sle_sample_seek_enable_cbk; + g_seek_cbk.seek_disable_cb = sle_sample_seek_disable_cbk; + g_seek_cbk.seek_result_cb = sle_sample_seek_result_info_cbk; +} + +void sle_sample_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) +{ + osal_printk("[ssap client] conn state changed conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], + addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + osal_printk("[ssap client] conn state changed disc_reason:0x%x\n", disc_reason); + if (conn_state == SLE_ACB_STATE_CONNECTED) { + if (pair_state == SLE_PAIR_NONE) { + sle_pair_remote_device(&g_remote_addr); + } + g_conn_id = conn_id; + } +} + +void sle_sample_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + osal_printk("[ssap client] pair complete conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], + addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + if (status == 0) { + ssap_exchange_info_t info = {0}; + info.mtu_size = SLE_MTU_SIZE_DEFAULT; + info.version = 1; + ssapc_exchange_info_req(1, g_conn_id, &info); + } +} + +void sle_sample_connect_cbk_register(void) +{ + g_connect_cbk.connect_state_changed_cb = sle_sample_connect_state_changed_cbk; + g_connect_cbk.pair_complete_cb = sle_sample_pair_complete_cbk; +} + +void sle_sample_exchange_info_cbk(uint8_t client_id, uint16_t conn_id, ssap_exchange_info_t *param, + errcode_t status) +{ + osal_printk("[ssap client] pair complete client id:%d status:%d\n", client_id, status); + osal_printk("[ssap client] exchange mtu, mtu size: %d, version: %d.\n", + param->mtu_size, param->version); + + ssapc_find_structure_param_t find_param = {0}; + find_param.type = SSAP_FIND_TYPE_PRIMARY_SERVICE; + find_param.start_hdl = 1; + find_param.end_hdl = 0xFFFF; + ssapc_find_structure(0, conn_id, &find_param); +} + +void sle_sample_find_structure_cbk(uint8_t client_id, uint16_t conn_id, ssapc_find_service_result_t *service, + errcode_t status) +{ + osal_printk("[ssap client] find structure cbk client: %d conn_id:%d status: %d \n", + client_id, conn_id, status); + osal_printk("[ssap client] find structure start_hdl:[0x%02x], end_hdl:[0x%02x], uuid len:%d\r\n", + service->start_hdl, service->end_hdl, service->uuid.len); + if (service->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] structure uuid:[0x%02x][0x%02x]\r\n", + service->uuid.uuid[14], service->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] structure uuid[%d]:[0x%02x]\r\n", idx, service->uuid.uuid[idx]); + } + } + g_find_service_result.start_hdl = service->start_hdl; + g_find_service_result.end_hdl = service->end_hdl; + memcpy_s(&g_find_service_result.uuid, sizeof(sle_uuid_t), &service->uuid, sizeof(sle_uuid_t)); +} + +void sle_sample_find_structure_cmp_cbk(uint8_t client_id, uint16_t conn_id, + ssapc_find_structure_result_t *structure_result, errcode_t status) +{ + osal_printk("[ssap client] find structure cmp cbk client id:%d status:%d type:%d uuid len:%d \r\n", + client_id, status, structure_result->type, structure_result->uuid.len); + if (structure_result->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] find structure cmp cbk structure uuid:[0x%02x][0x%02x]\r\n", + structure_result->uuid.uuid[14], structure_result->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] find structure cmp cbk structure uuid[%d]:[0x%02x]\r\n", idx, + structure_result->uuid.uuid[idx]); + } + } + uint8_t data[] = {0x11, 0x22, 0x33, 0x44}; + uint8_t len = sizeof(data); + ssapc_write_param_t param = {0}; + param.handle = g_find_service_result.start_hdl; + param.type = SSAP_PROPERTY_TYPE_VALUE; + param.data_len = len; + param.data = data; + ssapc_write_req(0, conn_id, ¶m); +} + +void sle_sample_find_property_cbk(uint8_t client_id, uint16_t conn_id, + ssapc_find_property_result_t *property, errcode_t status) +{ + osal_printk("[ssap client] find property cbk, client id: %d, conn id: %d, operate ind: %d, " + "descriptors count: %d status:%d.\n", client_id, conn_id, property->operate_indication, + property->descriptors_count, status); + for (uint16_t idx = 0; idx < property->descriptors_count; idx++) { + osal_printk("[ssap client] find property cbk, descriptors type [%d]: 0x%02x.\n", + idx, property->descriptors_type[idx]); + } + if (property->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] find property cbk, uuid: %02x %02x.\n", + property->uuid.uuid[14], property->uuid.uuid[15]); /* 14 15: uuid index */ + } else if (property->uuid.len == UUID_128BIT_LEN) { + for (uint16_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] find property cbk, uuid [%d]: %02x.\n", + idx, property->uuid.uuid[idx]); + } + } +} + +void sle_sample_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_write_result_t *write_result, + errcode_t status) +{ + osal_printk("[ssap client] write cfm cbk, client id: %d status:%d.\n", client_id, status); + ssapc_read_req(0, conn_id, write_result->handle, write_result->type); +} + +void sle_sample_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *read_data, + errcode_t status) +{ + osal_printk("[ssap client] read cfm cbk client id: %d conn id: %d status: %d\n", + client_id, conn_id, status); + osal_printk("[ssap client] read cfm cbk handle: %d, type: %d , len: %d\n", + read_data->handle, read_data->type, read_data->data_len); + for (uint16_t idx = 0; idx < read_data->data_len; idx++) { + osal_printk("[ssap client] read cfm cbk[%d] 0x%02x\r\n", idx, read_data->data[idx]); + } +} + +void sle_sample_ssapc_cbk_register(void) +{ + g_ssapc_cbk.exchange_info_cb = sle_sample_exchange_info_cbk; + g_ssapc_cbk.find_structure_cb = sle_sample_find_structure_cbk; + g_ssapc_cbk.find_structure_cmp_cb = sle_sample_find_structure_cmp_cbk; + g_ssapc_cbk.ssapc_find_property_cbk = sle_sample_find_property_cbk; + g_ssapc_cbk.write_cfm_cb = sle_sample_write_cfm_cbk; + g_ssapc_cbk.read_cfm_cb = sle_sample_read_cfm_cbk; +} + +void sle_client_init() +{ + sle_sample_seek_cbk_register(); + sle_sample_connect_cbk_register(); + sle_sample_ssapc_cbk_register(); + sle_announce_seek_register_callbacks(&g_seek_cbk); + sle_connection_register_callbacks(&g_connect_cbk); + ssapc_register_callbacks(&g_ssapc_cbk); + enable_sle(); +} + +void sle_start_scan() +{ + sle_seek_param_t param = {0}; + param.own_addr_type = 0; + param.filter_duplicates = 0; + param.seek_filter_policy = 0; + param.seek_phys = 1; + param.seek_type[0] = 0; + param.seek_interval[0] = SLE_SEEK_INTERVAL_DEFAULT; + param.seek_window[0] = SLE_SEEK_WINDOW_DEFAULT; + sle_set_seek_param(¶m); + sle_start_seek(); +} + +#define SLE_UUID_CLIENT_TASK_PRIO 26 +#define SLE_UUID_CLIENT_STACK_SIZE 0x2000 + +static void sle_uuid_client_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle= osal_kthread_create((osal_kthread_handler)sle_client_init, 0, "sle_gatt_client", + SLE_UUID_CLIENT_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, SLE_UUID_CLIENT_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the app entry. */ +app_run(sle_uuid_client_entry); \ No newline at end of file diff --git a/application/samples/bt/sle/sle_uuid_server/CMakeLists.txt b/application/samples/bt/sle/sle_uuid_server/CMakeLists.txt new file mode 100755 index 0000000..be2e0bc --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_server/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(src) + +set(SOURCES "${SOURCES}" PARENT_SCOPE) +set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/bt/sle/sle_uuid_server/inc/sle_server_adv.h b/application/samples/bt/sle/sle_uuid_server/inc/sle_server_adv.h new file mode 100755 index 0000000..8e34f7e --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_server/inc/sle_server_adv.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd.. 2023. All rights reserved. + * + * Description: SLE ADV Config. + */ + +/** + * @defgroup bluetooth_sle_adv API + * @ingroup + * @{ + */ + +#ifndef SLE_SERVER_ADV_H +#define SLE_SERVER_ADV_H + +/* 广播ID */ +#define SLE_ADV_HANDLE_DEFAULT 1 + +/** + * @if Eng + * @brief Definitaion of BLE ADV 通用广播结构. + * @else + * @brief SLE 广播普通数据结构。 + * @endif + */ +struct sle_adv_common_value { + uint8_t length; + uint8_t type; + uint8_t value; +}; + +/** + * @if Eng + * @brief Definitaion of BLE ADV Channel mapping. + * @else + * @brief SLE 广播信道映射。 + * @endif + */ +typedef enum { + SLE_ADV_CHANNEL_MAP_77 = 0x01, + SLE_ADV_CHANNEL_MAP_78 = 0x02, + SLE_ADV_CHANNEL_MAP_79 = 0x04, + SLE_ADV_CHANNEL_MAP_DEFAULT = 0x07 +} sle_adv_channel_map; + +/** + * @if Eng + * @brief Definitaion of SLE ADV Data Type. + * @else + * @brief SLE 广播数据类型 + * @endif + */ +typedef enum { + SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL = 0x01, /*!< 发现等级 */ + SLE_ADV_DATA_TYPE_ACCESS_MODE = 0x02, /*!< 接入层能力 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_16BIT_UUID = 0x03, /*!< 标准服务数据信息 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_128BIT_UUID = 0x04, /*!< 自定义服务数据信息 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x05, /*!< 完整标准服务标识列表 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x06, /*!< 完整自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x07, /*!< 部分标准服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x08, /*!< 部分自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_SERVICE_STRUCTURE_HASH_VALUE = 0x09, /*!< 服务结构散列值 */ + SLE_ADV_DATA_TYPE_SHORTENED_LOCAL_NAME = 0x0A, /*!< 设备缩写本地名称 */ + SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME = 0x0B, /*!< 设备完整本地名称 */ + SLE_ADV_DATA_TYPE_TX_POWER_LEVEL = 0x0C, /*!< 广播发送功率 */ + SLE_ADV_DATA_TYPE_SLB_COMMUNICATION_DOMAIN = 0x0D, /*!< SLB通信域域名 */ + SLE_ADV_DATA_TYPE_SLB_MEDIA_ACCESS_LAYER_ID = 0x0E, /*!< SLB媒体接入层标识 */ + SLE_ADV_DATA_TYPE_EXTENDED = 0xFE, /*!< 数据类型扩展 */ + SLE_ADV_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF /*!< 厂商自定义信息 */ +} sle_adv_data_type; + + +/** + * @if Eng + * @brief sle adv data config. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle广播数据配置。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +errcode_t sle_uuid_server_adv_init(void); +#endif \ No newline at end of file diff --git a/application/samples/bt/sle/sle_uuid_server/inc/sle_uuid_server.h b/application/samples/bt/sle/sle_uuid_server/inc/sle_uuid_server.h new file mode 100755 index 0000000..1c514d2 --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_server/inc/sle_uuid_server.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd.. 2022. All rights reserved. + * + * Description: SLE UUID Server module. + */ + +/** + * @defgroup SLE UUID SERVER API + * @ingroup + * @{ + */ +#ifndef SLE_UUID_SERVER_H +#define SLE_UUID_SERVER_H + +#include "sle_ssap_server.h" + +/* Service UUID */ +#define SLE_UUID_SERVER_SERVICE 0xABCD + +/* Property UUID */ +#define SLE_UUID_SERVER_NTF_REPORT 0x1122 + +/* Property Property */ +#define SLE_UUID_TEST_PROPERTIES (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + +/* Descriptor Property */ +#define SLE_UUID_TEST_DESCRIPTOR (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + +/** + * @if Eng + * @brief SLE uuid server inir. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief SLE UUID服务器初始化。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_init(void); + +/** + * @if Eng + * @brief send data to peer device by uuid on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_send_report_by_uuid(const uint8_t *data, uint16_t len); + +/** + * @if Eng + * @brief send data to peer device by handle on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_send_report_by_handle(const uint8_t *data, uint8_t len); +#endif diff --git a/application/samples/bt/sle/sle_uuid_server/src/CMakeLists.txt b/application/samples/bt/sle/sle_uuid_server/src/CMakeLists.txt new file mode 100755 index 0000000..d8c7be3 --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_server/src/CMakeLists.txt @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/sle_server_adv.c" + "${CMAKE_CURRENT_SOURCE_DIR}/sle_uuid_server.c" + PARENT_SCOPE) diff --git a/application/samples/bt/sle/sle_uuid_server/src/sle_server_adv.c b/application/samples/bt/sle/sle_uuid_server/src/sle_server_adv.c new file mode 100755 index 0000000..e48495e --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_server/src/sle_server_adv.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd.. 2023. All rights reserved. + * Description: sle adv config for sle uuid server. + */ +#include "securec.h" +#include "errcode.h" +#include "osal_addr.h" +#include "osal_debug.h" +#include "sle_common.h" +#include "sle_device_discovery.h" +#include "sle_errcode.h" +#include "sle_server_adv.h" + +/* sle device name */ +#define NAME_MAX_LENGTH 15 +/* 连接调度间隔12.5ms,单位125us */ +#define SLE_CONN_INTV_MIN_DEFAULT 0x64 +/* 连接调度间隔12.5ms,单位125us */ +#define SLE_CONN_INTV_MAX_DEFAULT 0x64 +/* 连接调度间隔25ms,单位125us */ +#define SLE_ADV_INTERVAL_MIN_DEFAULT 0xC8 +/* 连接调度间隔25ms,单位125us */ +#define SLE_ADV_INTERVAL_MAX_DEFAULT 0xC8 +/* 超时时间5000ms,单位10ms */ +#define SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT 0x1F4 +/* 超时时间4990ms,单位10ms */ +#define SLE_CONN_MAX_LATENCY 0x1F3 +/* 广播发送功率 */ +#define SLE_ADV_TX_POWER 10 +/* 最大广播数据长度 */ +#define SLE_ADV_DATA_LEN_MAX 251 +/* 广播名称 */ +uint8_t sle_local_name[ NAME_MAX_LENGTH] = { 's', 'l', 'e', '_', 'u', 'u', 'i', 'd', '_', 's', + 'e', 'r', 'v', 'e', 'r' }; + +static uint16_t sle_set_adv_local_name(uint8_t *adv_data, uint16_t max_len) +{ + errno_t ret; + uint8_t index = 0; + + uint8_t *local_name = sle_local_name; + uint8_t local_name_len = (uint8_t)strlen((char *)local_name); + for (uint8_t i = 0; i < local_name_len; i++) { + osal_printk("local_name[%d] = 0x%02x\r\n", i, local_name[i]); + } + + adv_data[index++] = local_name_len + 1; + adv_data[index++] = SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME; + ret = memcpy_s(&adv_data[index], max_len - index, local_name, local_name_len); + if (ret != EOK) { + osal_printk("memcpy fail\r\n"); + return 0; + } + return (uint16_t)index + local_name_len; +} + +static uint16_t sle_set_adv_data(uint8_t *adv_data) +{ + size_t len = 0; + uint16_t idx = 0; + errno_t ret = 0; + + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_disc_level = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL, + .value = SLE_ANNOUNCE_LEVEL_NORMAL, + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_disc_level, len); + if (ret != EOK) { + osal_printk("adv_disc_level memcpy fail\r\n"); + return 0; + } + idx += len; + + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_access_mode = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_ACCESS_MODE, + .value = 0, + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_access_mode, len); + if (ret != EOK) { + osal_printk("memcpy fail\r\n"); + return 0; + } + idx += len; + return idx; +} + +static uint16_t sle_set_scan_response_data(uint8_t *scan_rsp_data) +{ + uint16_t idx = 0; + errno_t ret; + size_t scan_rsp_data_len = sizeof(struct sle_adv_common_value); + + struct sle_adv_common_value tx_power_level = { + .length = scan_rsp_data_len - 1, + .type = SLE_ADV_DATA_TYPE_TX_POWER_LEVEL, + .value = SLE_ADV_TX_POWER, + }; + ret = memcpy_s(scan_rsp_data, SLE_ADV_DATA_LEN_MAX, &tx_power_level, scan_rsp_data_len); + if (ret != EOK) { + osal_printk("sle scan response data memcpy fail\r\n"); + return 0; + } + idx += scan_rsp_data_len; + + /* set local name */ + idx += sle_set_adv_local_name(&scan_rsp_data[idx], SLE_ADV_DATA_LEN_MAX - idx); + return idx; +} + +static int sle_set_default_announce_param(void) +{ + sle_announce_param_t param = {0}; + param.announce_mode = SLE_ANNOUNCE_MODE_CONNECTABLE_SCANABLE; + param.announce_handle = SLE_ADV_HANDLE_DEFAULT; + param.announce_gt_role = SLE_ANNOUNCE_ROLE_T_CAN_NEGO; + param.announce_level = SLE_ANNOUNCE_LEVEL_NORMAL; + param.announce_channel_map = SLE_ADV_CHANNEL_MAP_DEFAULT; + param.announce_interval_min = SLE_ADV_INTERVAL_MIN_DEFAULT; + param.announce_interval_max = SLE_ADV_INTERVAL_MAX_DEFAULT; + param.conn_interval_min = SLE_CONN_INTV_MIN_DEFAULT; + param.conn_interval_max = SLE_CONN_INTV_MAX_DEFAULT; + param.conn_max_latency = SLE_CONN_MAX_LATENCY; + param.conn_supervision_timeout = SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT; + return sle_set_announce_param(param.announce_handle, ¶m); +} + +static int sle_set_default_announce_data(void) +{ + errcode_t ret; + uint8_t announce_data_len = 0; + uint8_t seek_data_len = 0; + sle_announce_data_t data = {0}; + uint8_t adv_handle = SLE_ADV_HANDLE_DEFAULT; + uint8_t announce_data[SLE_ADV_DATA_LEN_MAX] = {0}; + uint8_t seek_rsp_data[SLE_ADV_DATA_LEN_MAX] = {0}; + + osal_printk("set adv data default\r\n"); + announce_data_len = sle_set_adv_data(announce_data); + data.announce_data = announce_data; + data.announce_data_len = announce_data_len; + + seek_data_len = sle_set_scan_response_data(seek_rsp_data); + data.seek_rsp_data = seek_rsp_data; + data.seek_rsp_data_len = seek_data_len; + + ret = sle_set_announce_data(adv_handle, &data); + if (ret == ERRCODE_SLE_SUCCESS) { + osal_printk("[SLE DD SDK] set announce data success."); + } else { + osal_printk("[SLE DD SDK] set adv param fail."); + } + return ERRCODE_SLE_SUCCESS; +} + +void sle_announce_enable_cbk(uint32_t announce_id, errcode_t status) +{ + osal_printk("sle announce enable id:%02x, state:%02x\r\n", announce_id, status); +} + +void sle_announce_disable_cbk(uint32_t announce_id, errcode_t status) +{ + osal_printk("sle announce disable id:%02x, state:%02x\r\n", announce_id, status); +} + +void sle_announce_terminal_cbk(uint32_t announce_id) +{ + osal_printk("sle announce terminal id:%02x\r\n", announce_id); +} + +void sle_enable_cbk(errcode_t status) +{ + osal_printk("sle enable status:%02x\r\n", status); +} + +void sle_announce_register_cbks(void) +{ + sle_announce_seek_callbacks_t seek_cbks = {0}; + seek_cbks.announce_enable_cb = sle_announce_enable_cbk; + seek_cbks.announce_disable_cb = sle_announce_disable_cbk; + seek_cbks.announce_terminal_cb = sle_announce_terminal_cbk; + seek_cbks.sle_enable_cb = sle_enable_cbk; + sle_announce_seek_register_callbacks(&seek_cbks); +} + +errcode_t sle_uuid_server_adv_init(void) +{ + osal_printk("sle_uuid_server_adv_init in\r\n"); + sle_announce_register_cbks(); + sle_set_default_announce_param(); + sle_set_default_announce_data(); + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); + osal_printk("sle_uuid_server_adv_init out\r\n"); + return ERRCODE_SLE_SUCCESS; +} diff --git a/application/samples/bt/sle/sle_uuid_server/src/sle_uuid_server.c b/application/samples/bt/sle/sle_uuid_server/src/sle_uuid_server.c new file mode 100755 index 0000000..cd25dc1 --- /dev/null +++ b/application/samples/bt/sle/sle_uuid_server/src/sle_uuid_server.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd.. 2023. All rights reserved. + * Description: sle uuid server sample. + */ +#include "securec.h" +#include "errcode.h" +#include "osal_addr.h" +#include "soc_osal.h" +#include "app_init.h" +#include "sle_common.h" +#include "sle_errcode.h" +#include "sle_ssap_server.h" +#include "sle_connection_manager.h" +#include "sle_device_discovery.h" +#include "sle_server_adv.h" +#include "sle_uuid_server.h" + +#define OCTET_BIT_LEN 8 +#define UUID_LEN_2 2 +#define BT_INDEX_4 4 +#define BT_INDEX_5 5 +#define BT_INDEX_0 0 + +#define encode2byte_little(_ptr, data) \ + do { \ + *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 8); \ + *(uint8_t *)(_ptr) = (uint8_t)(data); \ + } while (0) + +/* sle server app uuid for test */ +char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x0, 0x0}; +/* server notify property uuid for test */ +char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +/* sle connect acb handle */ +uint16_t g_sle_conn_hdl = 0; +/* sle server handle */ +uint8_t g_server_id = 0; +/* sle service handle */ +uint16_t g_service_handle = 0; +/* sle ntf property handle */ +uint16_t g_property_handle = 0; + +static uint8_t sle_uuid_base[] = { 0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, \ + 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +static void sle_uuid_set_base(sle_uuid_t *out) +{ + (void)memcpy_s(out->uuid, SLE_UUID_LEN, sle_uuid_base, SLE_UUID_LEN); + out->len = UUID_LEN_2; +} + +static void sle_uuid_setu2(uint16_t u2, sle_uuid_t *out) +{ + sle_uuid_set_base(out); + out->len = UUID_LEN_2; + encode2byte_little(&out->uuid[14], u2); +} + +static void ssaps_read_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_read_cb_t *read_cb_para, + errcode_t status) +{ + osal_printk("[uuid server] ssaps read request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n", + server_id, conn_id, read_cb_para->handle, status); +} + +static void ssaps_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para, + errcode_t status) +{ + osal_printk("[uuid server] ssaps write request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n", + server_id, conn_id, write_cb_para->handle, status); +} + +static void ssaps_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, ssap_exchange_info_t *mtu_size, + errcode_t status) +{ + osal_printk("[uuid server] ssaps write request cbk server_id:%x, conn_id:%x, mtu_size:%x, status:%x\r\n", + server_id, conn_id, mtu_size->mtu_size, status); +} + +static void ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status) +{ + osal_printk("[uuid server] start service cbk server_id:%x, handle:%x, status:%x\r\n", + server_id, handle, status); +} + +static void sle_ssaps_register_cbks(void) +{ + ssaps_callbacks_t ssaps_cbk = {0}; + ssaps_cbk.start_service_cb = ssaps_start_service_cbk; + ssaps_cbk.mtu_changed_cb = ssaps_mtu_changed_cbk; + ssaps_cbk.read_request_cb = ssaps_read_request_cbk; + ssaps_cbk.write_request_cb = ssaps_write_request_cbk; + ssaps_register_callbacks(&ssaps_cbk); +} + +static errcode_t sle_uuid_server_service_add(void) +{ + errcode_t ret; + sle_uuid_t service_uuid = {0}; + sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid); + ret = ssaps_add_service_sync(g_server_id, &service_uuid, 1, &g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[uuid server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + return ERRCODE_SLE_SUCCESS; +} + +static errcode_t sle_uuid_server_property_add(void) +{ + errcode_t ret; + ssaps_property_info_t property = {0}; + ssaps_desc_info_t descriptor = {0}; + uint8_t ntf_value[] = {0x01, 0x0}; + + property.permissions = SLE_UUID_TEST_PROPERTIES; + sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &property.uuid); + property.value = osal_vmalloc(sizeof(g_sle_property_value)); + if (property.value == NULL) { + osal_printk("[uuid server] sle property mem fail\r\n"); + return ERRCODE_SLE_FAIL; + } + if (memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, + sizeof(g_sle_property_value)) != EOK) { + osal_vfree(property.value); + osal_printk("[uuid server] sle property mem cpy fail\r\n"); + return ERRCODE_SLE_FAIL; + } + ret = ssaps_add_property_sync(g_server_id, g_service_handle, &property, &g_property_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[uuid server] sle uuid add property fail, ret:%x\r\n", ret); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + descriptor.permissions = SLE_UUID_TEST_DESCRIPTOR; + descriptor.value = osal_vmalloc(sizeof(ntf_value)); + if (descriptor.value == NULL) { + osal_printk("[uuid server] sle descriptor mem fail\r\n"); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + if (memcpy_s(descriptor.value, sizeof(ntf_value), ntf_value, sizeof(ntf_value)) != EOK) { + osal_printk("[uuid server] sle descriptor mem cpy fail\r\n"); + osal_vfree(property.value); + osal_vfree(descriptor.value); + return ERRCODE_SLE_FAIL; + } + ret = ssaps_add_descriptor_sync(g_server_id, g_service_handle, g_property_handle, &descriptor); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[uuid server] sle uuid add descriptor fail, ret:%x\r\n", ret); + osal_vfree(property.value); + osal_vfree(descriptor.value); + return ERRCODE_SLE_FAIL; + } + osal_vfree(property.value); + osal_vfree(descriptor.value); + return ERRCODE_SLE_SUCCESS; +} + +static errcode_t sle_uuid_server_add(void) +{ + errcode_t ret; + sle_uuid_t app_uuid = {0}; + + osal_printk("[uuid server] sle uuid add service in\r\n"); + app_uuid.len = sizeof(g_sle_uuid_app_uuid); + if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)) != EOK) { + return ERRCODE_SLE_FAIL; + } + ssaps_register_server(&app_uuid, &g_server_id); + + if (sle_uuid_server_service_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + + if (sle_uuid_server_property_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + osal_printk("[uuid server] sle uuid add service, server_id:%x, service_handle:%x, property_handle:%x\r\n", + g_server_id, g_service_handle, g_property_handle); + ret = ssaps_start_service(g_server_id, g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[uuid server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + osal_printk("[uuid server] sle uuid add service out\r\n"); + return ERRCODE_SLE_SUCCESS; +} + +/* device通过uuid向host发送数据:report */ +errcode_t sle_uuid_server_send_report_by_uuid(const uint8_t *data, uint16_t len) +{ + ssaps_ntf_ind_by_uuid_t param = {0}; + param.type = SSAP_PROPERTY_TYPE_VALUE; + param.start_handle = g_service_handle; + param.end_handle = g_property_handle; + param.value_len = len; + param.value = osal_vmalloc(len); + if (param.value == NULL) { + osal_printk("[uuid server] send report new fail\r\n"); + return ERRCODE_SLE_FAIL; + } + if (memcpy_s(param.value, param.value_len, data, len) != EOK) { + osal_printk("[uuid server] send input report memcpy fail\r\n"); + osal_vfree(param.value); + return ERRCODE_SLE_FAIL; + } + sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, ¶m.uuid); + ssaps_notify_indicate_by_uuid(g_server_id, g_sle_conn_hdl, ¶m); + osal_vfree(param.value); + return ERRCODE_SLE_SUCCESS; +} + +/* device通过handle向host发送数据:report */ +errcode_t sle_uuid_server_send_report_by_handle(const uint8_t *data, uint8_t len) +{ + ssaps_ntf_ind_t param = {0}; + + param.handle = g_property_handle; + param.type = SSAP_PROPERTY_TYPE_VALUE; + param.value = osal_vmalloc(len); + param.value_len = len; + if (param.value == NULL) { + osal_printk("[uuid server] send report new fail\r\n"); + return ERRCODE_SLE_FAIL; + } + if (memcpy_s(param.value, param.value_len, data, len) != EOK) { + osal_printk("[uuid server] send input report memcpy fail\r\n"); + osal_vfree(param.value); + return ERRCODE_SLE_FAIL; + } + ssaps_notify_indicate(g_server_id, g_sle_conn_hdl, ¶m); + osal_vfree(param.value); + return ERRCODE_SLE_SUCCESS; +} + +static void sle_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) +{ + osal_printk("[uuid server] connect state changed conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \ + disc_reason:0x%x\r\n", conn_id, conn_state, pair_state, disc_reason); + osal_printk("[uuid server] connect state changed addr:%02x:**:**:**:%02x:%02x\r\n", + addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); + g_sle_conn_hdl = conn_id; + if (conn_state == SLE_ACB_STATE_DISCONNECTED) { + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); + } +} + +static void sle_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + osal_printk("[uuid server] pair complete conn_id:%02x, status:%x\r\n", + conn_id, status); + osal_printk("[uuid server] pair complete addr:%02x:**:**:**:%02x:%02x\r\n", + addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); +} + +static void sle_conn_register_cbks(void) +{ + sle_connection_callbacks_t conn_cbks = {0}; + conn_cbks.connect_state_changed_cb = sle_connect_state_changed_cbk; + conn_cbks.pair_complete_cb = sle_pair_complete_cbk; + sle_connection_register_callbacks(&conn_cbks); +} + +/* 初始化uuid server */ +errcode_t sle_uuid_server_init(void) +{ + enable_sle(); + sle_conn_register_cbks(); + sle_ssaps_register_cbks(); + sle_uuid_server_add(); + sle_uuid_server_adv_init(); + osal_printk("[uuid server] init ok\r\n"); + return ERRCODE_SLE_SUCCESS; +} + +#define SLE_UUID_SERVER_TASK_PRIO 26 +#define SLE_UUID_SERVER_STACK_SIZE 0x2000 + +static void sle_uuid_server_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle= osal_kthread_create((osal_kthread_handler)sle_uuid_server_init, 0, "sle_uuid_server", + SLE_UUID_SERVER_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, SLE_UUID_SERVER_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the app entry. */ +app_run(sle_uuid_server_entry); \ No newline at end of file diff --git a/application/samples/peripheral/CMakeLists.txt b/application/samples/peripheral/CMakeLists.txt new file mode 100755 index 0000000..1fe94e5 --- /dev/null +++ b/application/samples/peripheral/CMakeLists.txt @@ -0,0 +1,116 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_AMIC) + add_subdirectory_if_exist(amic) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_BLINKY) + add_subdirectory_if_exist(blinky) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_BUTTON) + add_subdirectory_if_exist(button) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_TASKS) + add_subdirectory_if_exist(tasks) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_TCXO) + add_subdirectory_if_exist(tcxo) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_DMA) + add_subdirectory_if_exist(dma) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_I2C) + add_subdirectory_if_exist(i2c) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_I2S) + add_subdirectory_if_exist(i2s) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_KEYSCAN) + add_subdirectory_if_exist(keyscan) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_PDM) + add_subdirectory_if_exist(pdm) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_PDM_AMIC) + add_subdirectory_if_exist(pdm_amic) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_PINCTRL) + add_subdirectory_if_exist(pinctrl) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_QDEC) + add_subdirectory_if_exist(qdec) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_SFC) + add_subdirectory_if_exist(sfc) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_SPI) + add_subdirectory_if_exist(spi) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_SYSTICK) + add_subdirectory_if_exist(systick) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_WDT) + add_subdirectory_if_exist(watchdog) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_PWM) + add_subdirectory_if_exist(pwm) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_UART) + add_subdirectory_if_exist(uart) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_ADC) + add_subdirectory_if_exist(adc) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_RTC) + add_subdirectory_if_exist(rtc) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_TIMER) + add_subdirectory_if_exist(timer) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_EFLASH) + add_subdirectory_if_exist(eflash) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_CALENDAR) + add_subdirectory_if_exist(calendar) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_I2S_DMA) + add_subdirectory_if_exist(i2s_dma) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_I2S_DMA_LLI) + add_subdirectory_if_exist(i2s_dma_lli) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_CAN) + add_subdirectory_if_exist(can) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_CLOCKS) + add_subdirectory_if_exist(clocks) +endif() +set(SOURCES "${SOURCES}" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/peripheral/Kconfig b/application/samples/peripheral/Kconfig new file mode 100755 index 0000000..9e3783c --- /dev/null +++ b/application/samples/peripheral/Kconfig @@ -0,0 +1,406 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config ENABLE_ALL_PERIPHERAL_SAMPLE + bool + prompt "Enable all the sample of peripheral, it's just for build." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + select SAMPLE_SUPPORT_ADC + select SAMPLE_SUPPORT_AMIC if ADC_SUPPORT_AMIC + select SAMPLE_SUPPORT_BLINKY + select SAMPLE_SUPPORT_BUTTON + select SAMPLE_SUPPORT_CALENDAR + select SAMPLE_SUPPORT_CLOCKS + select SAMPLE_SUPPORT_DMA + select SAMPLE_SUPPORT_EFLASH + select SAMPLE_SUPPORT_I2C + select SAMPLE_SUPPORT_I2S + select SAMPLE_SUPPORT_I2S_DMA + select SAMPLE_SUPPORT_I2S_DMA_LLI + select SAMPLE_SUPPORT_KEYSCAN + select SAMPLE_SUPPORT_PDM + select SAMPLE_SUPPORT_PDM_AMIC if ADC_SUPPORT_AMIC + select SAMPLE_SUPPORT_PINCTRL + select SAMPLE_SUPPORT_PWM + select SAMPLE_SUPPORT_QDEC + select SAMPLE_SUPPORT_RTC + select SAMPLE_SUPPORT_SPI + select SAMPLE_SUPPORT_SYSTICK + select SAMPLE_SUPPORT_TASKS + select SAMPLE_SUPPORT_TCXO + select SAMPLE_SUPPORT_TIMER + select SAMPLE_SUPPORT_UART + select SAMPLE_SUPPORT_WDT + help + This option means enable all the sample of peripheral, it is just for build. + +config SAMPLE_SUPPORT_ADC + bool + prompt "Support ADC Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support ADC Sample. + +if SAMPLE_SUPPORT_ADC +menu "ADC Sample Configuration" + osource "application/samples/peripheral/adc/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_AMIC + bool + prompt "Support AMIC Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support AMIC Sample. + +if SAMPLE_SUPPORT_AMIC +menu "AFE Sample Configuration" + osource "application/samples/peripheral/amic/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_BLINKY + bool + prompt "Support BLINKY Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support BLINKY Sample. + +if SAMPLE_SUPPORT_BLINKY +menu "Blinky Sample Configuration" + osource "application/samples/peripheral/blinky/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_BUTTON + bool + prompt "Support BUTTON Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support BUTTON Sample. +if SAMPLE_SUPPORT_BUTTON +menu "BUTTON Sample Configuration" + osource "application/samples/peripheral/button/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_CALENDAR + bool + prompt "Support CALENDAR Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support CALENDAR Sample. + +if SAMPLE_SUPPORT_CALENDAR +menu "CALENDAR Sample Configuration" + osource "application/samples/peripheral/calendar/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_CAN + bool + prompt "Support CAN Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + select DRIVER_SUPPORT_CAN_FD + help + This option means support CAN Sample. + +if SAMPLE_SUPPORT_CAN +menu "CAN Sample Configuration" + osource "application/samples/peripheral/can/Kconfig" +endmenu +endif +config SAMPLE_SUPPORT_CLOCKS + bool + prompt "Support CLOCKS Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support CLOCKS Sample. + +if SAMPLE_SUPPORT_CLOCKS +menu "CLOCKS Sample Configuration" + osource "application/samples/peripheral/clocks/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_DMA + bool + prompt "Support DMA Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support DMA Sample. + +if SAMPLE_SUPPORT_DMA +menu "DMA Sample Configuration" + osource "application/samples/peripheral/dma/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_EFLASH + bool + prompt "Support EFLASH Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support EFLASH Sample. + +if SAMPLE_SUPPORT_EFLASH +menu "EFLASH Sample Configuration" + osource "application/samples/peripheral/eflash/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_I2C + bool + prompt "Support I2C Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support I2C Sample. + +if SAMPLE_SUPPORT_I2C +menu "I2C Sample Configuration" + osource "application/samples/peripheral/i2c/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_I2S + bool + prompt "Support I2S Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support I2S Sample. + +if SAMPLE_SUPPORT_I2S +menu "I2S Sample Configuration" + osource "application/samples/peripheral/i2s/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_I2S_DMA + bool + prompt "Support I2S DMA Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + select I2S_SUPPORT_DMA + help + This option means support I2S DMA Sample. + +if SAMPLE_SUPPORT_I2S_DMA +menu "I2S DMA Sample Configuration" + osource "application/samples/peripheral/i2s_dma/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_I2S_DMA_LLI + bool + prompt "Support I2S DMA lli Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + select I2S_SUPPORT_DMA + help + This option means support I2S DMA LLI Sample. + +if SAMPLE_SUPPORT_I2S_DMA_LLI +menu "I2S DMA lli Sample Configuration" + osource "application/samples/peripheral/i2s_dma_lli/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_KEYSCAN + bool + prompt "Support KEYSCAN Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support KEYSCAN Sample. + +config SAMPLE_SUPPORT_PDM + bool + prompt "Support PDM Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support PDM Sample. + +if SAMPLE_SUPPORT_PDM +menu "PDM Sample Configuration" + osource "application/samples/peripheral/pdm/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_PDM_AMIC + bool + prompt "Support PDM AMIC Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE && ADC_SUPPORT_AMIC + help + This option means support PDM AMIC Sample. + +if SAMPLE_SUPPORT_PDM_AMIC +menu "PDM AMIC Sample Configuration" + osource "application/samples/peripheral/pdm_amic/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_PINCTRL + bool + prompt "Support PINCTRL Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support PINCTRL Sample. + +if SAMPLE_SUPPORT_PINCTRL +menu "PINCTRL Sample Configuration" + osource "application/samples/peripheral/pinctrl/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_PWM + bool + prompt "Support PWM Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support PWM Sample. + +if SAMPLE_SUPPORT_PWM +menu "PWM Sample Configuration" + osource "application/samples/peripheral/pwm/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_QDEC + bool + prompt "Support QDEC Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support QDEC Sample. + +if SAMPLE_SUPPORT_QDEC +menu "QDEC Sample Configuration" + osource "application/samples/peripheral/qdec/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_RTC + bool + prompt "Support RTC Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support RTC Sample. + +if SAMPLE_SUPPORT_RTC +menu "RTC Sample Configuration" + osource "application/samples/peripheral/rtc/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_SFC + bool + prompt "Support SFC Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support SFC Sample. + +if SAMPLE_SUPPORT_SFC +menu "SFC Sample Configuration" + osource "application/samples/peripheral/sfc/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_SPI + bool + prompt "Support SPI Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support SPI Sample. + +if SAMPLE_SUPPORT_SPI +menu "SPI Sample Configuration" + osource "application/samples/peripheral/spi/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_SYSTICK + bool + prompt "Support SYSTICK Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support SYSTICK Sample. + +config SAMPLE_SUPPORT_TASKS + bool + prompt "Support TASKS Test Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support TASKS Test Sample. + +config SAMPLE_SUPPORT_TCXO + bool + prompt "Support TCXO Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support TCXO Sample. + +config SAMPLE_SUPPORT_TIMER + bool + prompt "Support TIMER Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support TIMER Sample. + +if SAMPLE_SUPPORT_TIMER +menu "TIMER Sample Configuration" + osource "application/samples/peripheral/timer/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_UART + bool + prompt "Support UART Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support UART Sample. + +if SAMPLE_SUPPORT_UART +menu "UART Sample Configuration" + osource "application/samples/peripheral/uart/Kconfig" +endmenu +endif + +config SAMPLE_SUPPORT_WDT + bool + prompt "Support WATCHDOG Sample." + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support WATCHDOG Sample. + +if SAMPLE_SUPPORT_WDT +menu "WATCHDOG Sample Configuration" + osource "application/samples/peripheral/watchdog/Kconfig" +endmenu +endif \ No newline at end of file diff --git a/application/samples/peripheral/adc/CMakeLists.txt b/application/samples/peripheral/adc/CMakeLists.txt new file mode 100755 index 0000000..32cc74e --- /dev/null +++ b/application/samples/peripheral/adc/CMakeLists.txt @@ -0,0 +1,10 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + +if((DEFINED CONFIG_ADC_USING_V154) OR (DEFINED CONFIG_ADC_USING_V155)) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/adc_demo_inc.c" PARENT_SCOPE) +else() + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/adc_demo.c" PARENT_SCOPE) +endif() \ No newline at end of file diff --git a/application/samples/peripheral/adc/Kconfig b/application/samples/peripheral/adc/Kconfig new file mode 100755 index 0000000..c1a8b86 --- /dev/null +++ b/application/samples/peripheral/adc/Kconfig @@ -0,0 +1,25 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config HADC_SELF_CALIBRATION + bool + prompt "HADC calibration, or use record code." + default y + depends on ADC_USING_V152 + +config HADC_SAMPLE + bool + prompt "Enable HADC sample." + default y + depends on ADC_USING_V152 + +config TIMING_SAMPLE + bool + prompt "Create timing sample irq." + default n + +config ADC_CHANNEL + int + prompt "Choose ADC channel." + default 5 \ No newline at end of file diff --git a/application/samples/peripheral/adc/adc.code-workspace b/application/samples/peripheral/adc/adc.code-workspace new file mode 100755 index 0000000..96487ab --- /dev/null +++ b/application/samples/peripheral/adc/adc.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/adc" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/adc/adc_demo_inc.c b/application/samples/peripheral/adc/adc_demo_inc.c new file mode 100755 index 0000000..f727555 --- /dev/null +++ b/application/samples/peripheral/adc/adc_demo_inc.c @@ -0,0 +1,53 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: ADC Sample Source. \n + * + * History: \n + * 2023-07-06, Create file. \n + */ +#include "pinctrl.h" +#include "adc.h" +#include "adc_porting.h" +#include "common_def.h" +#include "soc_osal.h" +#include "app_init.h" +#include "tcxo.h" + +#define DELAY_10000MS 10000 +#define CYCLES 10 +#define ADC_TASK_PRIO 26 +#define ADC_TASK_STACK_SIZE 0x1000 + +static void *adc_task(const char *arg) +{ + unused(arg); + osal_printk("start adc sample\r\n"); + uapi_adc_init(ADC_CLOCK_NONE); + uint8_t adc_channel = CONFIG_ADC_CHANNEL; + uint16_t voltage = 0; + uint32_t cnt = 0; + while (cnt++ < CYCLES) { + adc_port_read(adc_channel, &voltage); + osal_printk("voltage: %d mv\r\n", voltage); + osal_msleep(DELAY_10000MS); + } + /* 当前测量的电压值和实际值可能有较大差别,请确认是否有分压电阻,如果有分压电阻,则差别符合预期 */ + uapi_adc_deinit(); + + return NULL; +} + +static void adc_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)adc_task, 0, "AdcTask", ADC_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, ADC_TASK_PRIO); + } + osal_kthread_unlock(); +} + +/* Run the adc_entry. */ +app_run(adc_entry); \ No newline at end of file diff --git a/application/samples/peripheral/blinky/CMakeLists.txt b/application/samples/peripheral/blinky/CMakeLists.txt new file mode 100755 index 0000000..8218eb2 --- /dev/null +++ b/application/samples/peripheral/blinky/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/blinky_demo.c" PARENT_SCOPE) diff --git a/application/samples/peripheral/blinky/Kconfig b/application/samples/peripheral/blinky/Kconfig new file mode 100755 index 0000000..672168d --- /dev/null +++ b/application/samples/peripheral/blinky/Kconfig @@ -0,0 +1,8 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. +#=============================================================================== +config BLINKY_PIN + int + prompt "Choose blinky pin." + default 2 \ No newline at end of file diff --git a/application/samples/peripheral/blinky/blinky.code-workspace b/application/samples/peripheral/blinky/blinky.code-workspace new file mode 100755 index 0000000..e4da5ec --- /dev/null +++ b/application/samples/peripheral/blinky/blinky.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/blinky" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/blinky/blinky_demo.c b/application/samples/peripheral/blinky/blinky_demo.c new file mode 100755 index 0000000..0d68cf0 --- /dev/null +++ b/application/samples/peripheral/blinky/blinky_demo.c @@ -0,0 +1,51 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: Blinky Sample Source. \n + * + * History: \n + * 2023-04-03, Create file. \n + */ + +#include "pinctrl.h" +#include "gpio.h" +#include "soc_osal.h" +#include "app_init.h" + +#define BLINKY_DURATION_MS 500 + +#define BLINKY_TASK_PRIO 24 +#define BLINKY_TASK_STACK_SIZE 0x1000 + +static int blinky_task(const char *arg) +{ + unused(arg); + + uapi_pin_set_mode(CONFIG_BLINKY_PIN, HAL_PIO_FUNC_GPIO); + + uapi_gpio_set_dir(CONFIG_BLINKY_PIN, GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(CONFIG_BLINKY_PIN, GPIO_LEVEL_LOW); + + while (1) { + osal_msleep(BLINKY_DURATION_MS); + uapi_gpio_toggle(CONFIG_BLINKY_PIN); + osal_printk("Blinky working.\r\n"); + } + + return 0; +} + +static void blinky_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)blinky_task, 0, "BlinkyTask", BLINKY_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, BLINKY_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the blinky_entry. */ +app_run(blinky_entry); \ No newline at end of file diff --git a/application/samples/peripheral/dma/CMakeLists.txt b/application/samples/peripheral/dma/CMakeLists.txt new file mode 100755 index 0000000..867d0ed --- /dev/null +++ b/application/samples/peripheral/dma/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/dma_demo.c" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/peripheral/dma/Kconfig b/application/samples/peripheral/dma/Kconfig new file mode 100755 index 0000000..41ed48b --- /dev/null +++ b/application/samples/peripheral/dma/Kconfig @@ -0,0 +1,9 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config DMA_MEMORY_LLI_TRANSFER_MODE + bool + prompt "Choose DMA memory to memory lli transfer mode." + depends on SAMPLE_SUPPORT_DMA + default n \ No newline at end of file diff --git a/application/samples/peripheral/dma/dma.code-workspace b/application/samples/peripheral/dma/dma.code-workspace new file mode 100755 index 0000000..b835c68 --- /dev/null +++ b/application/samples/peripheral/dma/dma.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/dma" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/dma/dma_demo.c b/application/samples/peripheral/dma/dma_demo.c new file mode 100755 index 0000000..061728b --- /dev/null +++ b/application/samples/peripheral/dma/dma_demo.c @@ -0,0 +1,115 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: DMA Sample Source. \n + * + * History: \n + * 2023-07-06, Create file. \n + */ +#include "hal_dma.h" +#include "soc_osal.h" +#include "securec.h" +#include "app_init.h" + +#define DMA_TRANSFER_WORD_NUM 32 +#define DMA_TRANSFER_PRIORITY 0 +#define DMA_TRANSFER_WIDTH 2 +#define DMA_TASK_DURATION_MS 500 + +#define DMA_TASK_PRIO 24 +#define DMA_TASK_STACK_SIZE 0x1000 + +static uint32_t g_app_dma_src_data[DMA_TRANSFER_WORD_NUM] = { 0 }; +static uint32_t g_app_dma_desc_data[DMA_TRANSFER_WORD_NUM] = { 0 }; +static uint8_t g_dma_trans_done = 0; + +static void app_dma_trans_done_callback(uint8_t int_type, uint8_t channel, uintptr_t arg) +{ + unused(arg); + unused(channel); + switch (int_type) { + case HAL_DMA_INTERRUPT_TFR: + g_dma_trans_done = 1; + break; + case HAL_DMA_INTERRUPT_BLOCK: + g_dma_trans_done = 1; + break; + case HAL_DMA_INTERRUPT_ERR: + osal_printk("DMA transfer error.\r\n"); + break; + default: + break; + } +} + +static void *dma_task(const char *arg) +{ + unused(arg); + /* DMA init. */ + uapi_dma_init(); + uapi_dma_open(); + +#if defined(CONFIG_DMA_MEMORY_LLI_TRANSFER_MODE) + dma_channel_t dma_channel = DMA_CHANNEL_NONE; + dma_channel = uapi_dma_get_lli_channel(0, HAL_DMA_HANDSHAKING_MAX_NUM); +#endif + + for (uint32_t i = 0; i < DMA_TRANSFER_WORD_NUM; i++) { + g_app_dma_src_data[i] = i; + } + memset_s(g_app_dma_desc_data, DMA_TRANSFER_WORD_NUM, 0, DMA_TRANSFER_WORD_NUM); + + dma_ch_user_memory_config_t transfer_config = { 0 }; + transfer_config.src = (uint32_t)(uintptr_t)g_app_dma_src_data; + transfer_config.dest = (uint32_t)(uintptr_t)g_app_dma_desc_data; + transfer_config.transfer_num = DMA_TRANSFER_WORD_NUM; + transfer_config.priority = DMA_TRANSFER_PRIORITY; + transfer_config.width = DMA_TRANSFER_WIDTH; + + while (1) { + osal_msleep(DMA_TASK_DURATION_MS); + g_dma_trans_done = 0; +#if defined(CONFIG_DMA_MEMORY_LLI_TRANSFER_MODE) + osal_printk("dma config link list item of memory to memory start!\r\n"); + if (uapi_dma_transfer_memory_lli(dma_channel, &transfer_config, app_dma_trans_done_callback) == ERRCODE_SUCC) { + osal_printk("dma config link list item of memory to memory succ!\r\n"); + } + osal_printk("dma enable lli memory transfer start!\r\n"); + if (uapi_dma_enable_lli(dma_channel, app_dma_trans_done_callback, (uintptr_t)NULL) == ERRCODE_SUCC) { + osal_printk("dma enable lli memory transfer succ!\r\n"); + } + while (!g_dma_trans_done) {} + if (uapi_dma_end_transfer(dma_channel) == ERRCODE_SUCC) { + osal_printk("dma channel transfer finish!\r\n"); + } +#else + osal_printk("dma single memory transfer start!\r\n"); + if (uapi_dma_transfer_memory_single(&transfer_config, app_dma_trans_done_callback, + (uintptr_t)NULL) == ERRCODE_SUCC) { + osal_printk("dma single memory transfer succ!\r\n"); + } + while (!g_dma_trans_done) {} + osal_printk("dma checking transfer from 0x%08x to 0x%08x...\r\n", transfer_config.src, transfer_config.dest); + if (memcmp((void *)transfer_config.src, (void *)transfer_config.dest, transfer_config.transfer_num) == 0) { + osal_printk("dma memory copy test succ, length = %d block\r\n", transfer_config.transfer_num); + } +#endif + } + + return NULL; +} + +static void dma_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)dma_task, 0, "DmaTask", DMA_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, DMA_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the dma_entry. */ +app_run(dma_entry); \ No newline at end of file diff --git a/application/samples/peripheral/i2c/CMakeLists.txt b/application/samples/peripheral/i2c/CMakeLists.txt new file mode 100755 index 0000000..ddc695f --- /dev/null +++ b/application/samples/peripheral/i2c/CMakeLists.txt @@ -0,0 +1,9 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_I2C_MASTER) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/i2c_master_demo.c" PARENT_SCOPE) +elseif(DEFINED CONFIG_SAMPLE_SUPPORT_I2C_SLAVE) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/i2c_slave_demo.c" PARENT_SCOPE) +endif() \ No newline at end of file diff --git a/application/samples/peripheral/i2c/Kconfig b/application/samples/peripheral/i2c/Kconfig new file mode 100755 index 0000000..3b29215 --- /dev/null +++ b/application/samples/peripheral/i2c/Kconfig @@ -0,0 +1,79 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config SAMPLE_SUPPORT_I2C_MASTER + bool + prompt "Support I2C Master Sample." + default n + depends on SAMPLE_SUPPORT_I2C + help + This option means support I2C Master Sample. + +config I2C_MASTER_BUS_ID + int + prompt "Choose I2C master bus id." + depends on SAMPLE_SUPPORT_I2C_MASTER + default 2 + +config I2C_SCL_MASTER_PIN + int + prompt "Choose I2C SCL master pin." + depends on SAMPLE_SUPPORT_I2C_MASTER + default 8 + +config I2C_SDA_MASTER_PIN + int + prompt "Choose I2C SDA master pin." + depends on SAMPLE_SUPPORT_I2C_MASTER + default 9 + +config I2C_MASTER_PIN_MODE + int + prompt "Choose I2C master pin mode." + depends on SAMPLE_SUPPORT_I2C_MASTER + default 3 + +config I2C_SLAVE_ADDR + hex + prompt "Choose I2C slave addr." + depends on SAMPLE_SUPPORT_I2C_MASTER + default 0x49 + +config SAMPLE_SUPPORT_I2C_SLAVE + bool + prompt "Support I2C Slave Sample." + default n + depends on SAMPLE_SUPPORT_I2C + help + This option means support I2C Slave Sample. + +config I2C_SLAVE_BUS_ID + int + prompt "Choose I2C slave bus id." + depends on SAMPLE_SUPPORT_I2C_SLAVE + default 2 + +config I2C_SCL_SLAVE_PIN + int + prompt "Choose I2C SCL slave pin." + depends on SAMPLE_SUPPORT_I2C_SLAVE + default 8 + +config I2C_SDA_SLAVE_PIN + int + prompt "Choose I2C SDA slave pin." + depends on SAMPLE_SUPPORT_I2C_SLAVE + default 9 + +config I2C_SLAVE_PIN_MODE + int + prompt "Choose I2C slave pin mode." + depends on SAMPLE_SUPPORT_I2C_SLAVE + default 3 + +config I2C_TRANSFER_LEN + int + prompt "Choose I2C transfer length." + depends on SAMPLE_SUPPORT_I2C + default 8 \ No newline at end of file diff --git a/application/samples/peripheral/i2c/i2c.code-workspace b/application/samples/peripheral/i2c/i2c.code-workspace new file mode 100755 index 0000000..d515610 --- /dev/null +++ b/application/samples/peripheral/i2c/i2c.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/i2c" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/i2c/i2c_master_demo.c b/application/samples/peripheral/i2c/i2c_master_demo.c new file mode 100755 index 0000000..70a349b --- /dev/null +++ b/application/samples/peripheral/i2c/i2c_master_demo.c @@ -0,0 +1,104 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: I2C Sample Source. \n + * + * History: \n + * 2023-05-25, Create file. \n + */ +#include "pinctrl.h" +#include "i2c.h" +#include "soc_osal.h" +#include "app_init.h" +#if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1) +#include "dma.h" +#endif + +#define I2C_MASTER_ADDR 0x0 +#define I2C_SET_BAUDRATE 400000 +#define I2C_TASK_DURATION_MS 500 +#if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1) +#define I2C_INT_TRANSFER_DELAY_MS 800 +#endif + +#define I2C_TASK_PRIO 24 +#define I2C_TASK_STACK_SIZE 0x1000 + +static void app_i2c_init_pin(void) +{ + /* I2C pinmux. */ + uapi_pin_set_mode(CONFIG_I2C_SCL_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_I2C_SDA_MASTER_PIN, CONFIG_I2C_MASTER_PIN_MODE); +} + +static void *i2c_master_task(const char *arg) +{ + unused(arg); + i2c_data_t data = { 0 }; + + uint32_t baudrate = I2C_SET_BAUDRATE; + uint8_t hscode = I2C_MASTER_ADDR; + uint16_t dev_addr = CONFIG_I2C_SLAVE_ADDR; + +#if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1) + uapi_dma_init(); + uapi_dma_open(); +#endif /* CONFIG_I2C_SUPPORT_DMA */ + + /* I2C master init config. */ + app_i2c_init_pin(); + uapi_i2c_master_init(CONFIG_I2C_MASTER_BUS_ID, baudrate, hscode); + +#if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1) + uapi_i2c_set_irq_mode(CONFIG_I2C_MASTER_BUS_ID, 1); +#endif /* CONFIG_I2C_SUPPORT_INT */ + + /* I2C data config. */ + uint8_t tx_buff[CONFIG_I2C_TRANSFER_LEN] = { 0 }; + for (uint32_t loop = 0; loop < CONFIG_I2C_TRANSFER_LEN; loop++) { + tx_buff[loop] = (loop & 0xFF); + } + + uint8_t rx_buff[CONFIG_I2C_TRANSFER_LEN] = { 0 }; + data.send_buf = tx_buff; + data.send_len = CONFIG_I2C_TRANSFER_LEN; + data.receive_buf = rx_buff; + data.receive_len = CONFIG_I2C_TRANSFER_LEN; + + while (1) { + osal_msleep(I2C_TASK_DURATION_MS); + osal_printk("i2c%d master send start!\r\n", CONFIG_I2C_MASTER_BUS_ID); + if (uapi_i2c_master_write(CONFIG_I2C_MASTER_BUS_ID, dev_addr, &data) == ERRCODE_SUCC) { + osal_printk("i2c%d master send succ!\r\n", CONFIG_I2C_MASTER_BUS_ID); + } else { + continue; + } +#if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1) + osal_msleep(I2C_INT_TRANSFER_DELAY_MS); +#endif + osal_printk("i2c%d master receive start!\r\n", CONFIG_I2C_MASTER_BUS_ID); + if (uapi_i2c_master_read(CONFIG_I2C_MASTER_BUS_ID, dev_addr, &data) == ERRCODE_SUCC) { + for (uint32_t i = 0; i < data.receive_len; i++) { + osal_printk("i2c%d master receive data is %x\r\n", CONFIG_I2C_MASTER_BUS_ID, data.receive_buf[i]); + } + osal_printk("i2c%d master receive succ!\r\n", CONFIG_I2C_MASTER_BUS_ID); + } + } + + return NULL; +} + +static void i2c_master_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)i2c_master_task, 0, "I2cMasterTask", I2C_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, I2C_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the i2c_master_entry. */ +app_run(i2c_master_entry); \ No newline at end of file diff --git a/application/samples/peripheral/i2c/i2c_slave_demo.c b/application/samples/peripheral/i2c/i2c_slave_demo.c new file mode 100755 index 0000000..edb8510 --- /dev/null +++ b/application/samples/peripheral/i2c/i2c_slave_demo.c @@ -0,0 +1,101 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: I2C Sample Source. \n + * + * History: \n + * 2023-05-25, Create file. \n + */ +#include "pinctrl.h" +#include "i2c.h" +#include "soc_osal.h" +#include "app_init.h" +#if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1) +#include "dma.h" +#endif + +#define I2C_SLAVE_ADDR 0x8 +#define I2C_SET_BAUDRATE 500000 +#define I2C_TASK_DURATION_MS 100 +#if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1) +#define I2C_DMA_TRANSFER_DELAY_MS 500 +#endif + +#define I2C_TASK_PRIO 24 +#define I2C_TASK_STACK_SIZE 0x1000 + +static void app_i2c_init_pin(void) +{ + /* I2C pinmux. */ + uapi_pin_set_mode(CONFIG_I2C_SCL_SLAVE_PIN, CONFIG_I2C_SLAVE_PIN_MODE); + uapi_pin_set_mode(CONFIG_I2C_SDA_SLAVE_PIN, CONFIG_I2C_SLAVE_PIN_MODE); +} + +void *i2c_slave_task(const char *arg) +{ + unused(arg); + i2c_data_t data = { 0 }; + + uint32_t baudrate = I2C_SET_BAUDRATE; + uint16_t dev_addr = I2C_SLAVE_ADDR; + +#if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1) + uapi_dma_init(); + uapi_dma_open(); +#endif /* CONFIG_I2C_SUPPORT_DMA */ + + /* I2C slave init config. */ + app_i2c_init_pin(); + uapi_i2c_slave_init(CONFIG_I2C_SLAVE_BUS_ID, baudrate, dev_addr); + +#if defined(CONFIG_I2C_SUPPORT_INT) && (CONFIG_I2C_SUPPORT_INT == 1) + uapi_i2c_set_irq_mode(CONFIG_I2C_SLAVE_BUS_ID, 1); +#endif /* CONFIG_I2C_SUPPORT_INT */ + + /* I2C data config. */ + uint8_t tx_buff[CONFIG_I2C_TRANSFER_LEN] = { 0 }; + for (uint32_t loop = 0; loop < CONFIG_I2C_TRANSFER_LEN; loop++) { + tx_buff[loop] = (loop & 0xFF); + } + + uint8_t rx_buff[CONFIG_I2C_TRANSFER_LEN] = { 0 }; + data.send_buf = tx_buff; + data.send_len = CONFIG_I2C_TRANSFER_LEN; + data.receive_buf = rx_buff; + data.receive_len = CONFIG_I2C_TRANSFER_LEN; + + while (1) { + osal_msleep(I2C_TASK_DURATION_MS); + osal_printk("i2c%d slave receive start!\r\n", CONFIG_I2C_SLAVE_BUS_ID); + if (uapi_i2c_slave_read(CONFIG_I2C_SLAVE_BUS_ID, &data) == ERRCODE_SUCC) { + for (uint32_t i = 0; i < data.receive_len; i++) { + osal_printk("i2c slave receive data is %x\r\n", data.receive_buf[i]); + } + osal_printk("i2c%d slave receive succ!\r\n", CONFIG_I2C_SLAVE_BUS_ID); + } + osal_printk("i2c%d slave send start!\r\n", CONFIG_I2C_SLAVE_BUS_ID); +#if defined(CONFIG_I2C_SUPPORT_DMA) && (CONFIG_I2C_SUPPORT_DMA == 1) + osal_msleep(I2C_DMA_TRANSFER_DELAY_MS); +#endif + if (uapi_i2c_slave_write(CONFIG_I2C_SLAVE_BUS_ID, &data) == ERRCODE_SUCC) { + osal_printk("i2c%d slave send succ!\r\n", CONFIG_I2C_SLAVE_BUS_ID); + } + } + + return NULL; +} + +static void i2c_slave_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)i2c_slave_task, 0, "I2cSlaveTask", I2C_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, I2C_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the i2c_slave_entry. */ +app_run(i2c_slave_entry); \ No newline at end of file diff --git a/application/samples/peripheral/i2s_dma_lli/CMakeLists.txt b/application/samples/peripheral/i2s_dma_lli/CMakeLists.txt new file mode 100755 index 0000000..a69b02c --- /dev/null +++ b/application/samples/peripheral/i2s_dma_lli/CMakeLists.txt @@ -0,0 +1,9 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_I2S_DMA_LLI_MASTER) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/i2s_dma_lli_master_demo.c" PARENT_SCOPE) +elseif(DEFINED CONFIG_SAMPLE_SUPPORT_I2S_DMA_LLI_SLAVE) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/i2s_dma_lli_slave_demo.c" PARENT_SCOPE) +endif() \ No newline at end of file diff --git a/application/samples/peripheral/i2s_dma_lli/Kconfig b/application/samples/peripheral/i2s_dma_lli/Kconfig new file mode 100755 index 0000000..eb462e6 --- /dev/null +++ b/application/samples/peripheral/i2s_dma_lli/Kconfig @@ -0,0 +1,26 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config SAMPLE_SUPPORT_I2S_DMA_LLI_MASTER + bool + prompt "Support I2S Master Sample." + default n + depends on SAMPLE_SUPPORT_I2S_DMA_LLI + help + This option means support I2S Master Sample. + +config SAMPLE_SUPPORT_I2S_DMA_LLI_SLAVE + bool + prompt "Support I2S Slave Sample." + default n + depends on SAMPLE_SUPPORT_I2S_DMA_LLI + help + This option means support I2S Slave Sample. + +config I2S_TRANSFER_LEN_OF_DMA_LLI + int + prompt "Set the length of transfer by DMA." + default 128 + help + This option means the length of transfer by DMA. \ No newline at end of file diff --git a/application/samples/peripheral/i2s_dma_lli/i2s_dma_lli_master_demo.c b/application/samples/peripheral/i2s_dma_lli/i2s_dma_lli_master_demo.c new file mode 100755 index 0000000..2b47721 --- /dev/null +++ b/application/samples/peripheral/i2s_dma_lli/i2s_dma_lli_master_demo.c @@ -0,0 +1,103 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: i2s dma master lli Sample Source. \n + * + * History: \n + * 2024-04-26, Create file. \n + */ +#include "i2s.h" +#include "watchdog.h" +#include "hal_sio.h" +#include "hal_dma.h" +#include "soc_osal.h" +#include "app_init.h" + +#define I2S_DIV_NUMBER 32 +#define I2S_CHANNEL_NUMBER 2 +#define I2S_TX_INT_THRESHOLD 7 +#define I2S_RX_INT_THRESHOLD 1 +#define I2S_DMA_SRC_WIDTH 2 +#define I2S_DMA_DEST_WIDTH 2 +#define I2S_DMA_BURST_LENGTH 0 +#define I2S_DMA_TRANS_STEP 2 + +#define I2S_TASK_PRIO 24 +#define I2S_TASK_STACK_SIZE 0xc00 + +static uint32_t g_i2s_first_data = 0x10000000; /* 32 bits */ +static uint32_t g_i2s_send_dma_data[CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI] = { 0 }; + +static void i2s_dma_master_init(void) +{ + uapi_i2s_deinit(SIO_BUS_0); + uapi_i2s_init(SIO_BUS_0, NULL); + sio_porting_i2s_pinmux(); + i2s_config_t config = { + .drive_mode = MASTER, + .transfer_mode = STD_MODE, + .data_width = THIRTY_TWO_BIT, + .channels_num = TWO_CH, + .timing = NONE_TIMING_MODE, + .clk_edge = RISING_EDGE, + .div_number = I2S_DIV_NUMBER, + .number_of_channels = I2S_CHANNEL_NUMBER, + }; + i2s_dma_attr_t attr = { + .tx_dma_enable = 1, + .tx_int_threshold = I2S_TX_INT_THRESHOLD, + .rx_dma_enable = 0, + .rx_int_threshold = I2S_RX_INT_THRESHOLD, + }; + uapi_i2s_set_config(SIO_BUS_0, &config); + uapi_i2s_dma_config(SIO_BUS_0, &attr); +} + +static void *i2s_dma_master_task(const char *arg) +{ + unused(arg); + int32_t ret = CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI; +#if defined(CONFIG_SIO_USING_V151) + ret = ERRCODE_SUCC; +#endif + uapi_dma_deinit(); + i2s_dma_master_init(); + for (uint32_t i = 0; i < CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI; i += I2S_DMA_TRANS_STEP) { + g_i2s_send_dma_data[i] = g_i2s_first_data; + g_i2s_send_dma_data[i + 1] = g_i2s_first_data; + g_i2s_first_data++; + } + /* DMA init. */ + uapi_dma_init(); + uapi_dma_open(); + i2s_dma_config_t dma_cfg = { + .src_width = I2S_DMA_SRC_WIDTH, + .dest_width = I2S_DMA_DEST_WIDTH, + .burst_length = I2S_DMA_BURST_LENGTH, + .priority = 0, + }; + osal_printk("DMA master transfer start.\r\n"); + while (1) { + uapi_watchdog_kick(); + if (uapi_i2s_merge_write_by_dma(SIO_BUS_0, &g_i2s_send_dma_data, CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI, &dma_cfg, + (uintptr_t)NULL, true) != ret) { + osal_printk("master uapi_i2s_merge_write_by_dma error.\r\n"); + } + } + return NULL; +} + +static void i2s_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)i2s_dma_master_task, 0, "I2sDmaMasterTask", + I2S_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, I2S_TASK_PRIO); + } + osal_kthread_unlock(); +} + +/* Run the i2s_entry. */ +app_run(i2s_entry); \ No newline at end of file diff --git a/application/samples/peripheral/i2s_dma_lli/i2s_dma_lli_slave_demo.c b/application/samples/peripheral/i2s_dma_lli/i2s_dma_lli_slave_demo.c new file mode 100755 index 0000000..bb8d0f9 --- /dev/null +++ b/application/samples/peripheral/i2s_dma_lli/i2s_dma_lli_slave_demo.c @@ -0,0 +1,185 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: i2s dma slave lli Sample Source. \n + * + * History: \n + * 2024-04-26, Create file. \n + */ +#include "i2s.h" +#include "watchdog.h" +#include "hal_sio.h" +#include "hal_dma.h" +#include "soc_osal.h" +#include "app_init.h" + +#define I2S_DIV_NUMBER 32 +#define I2S_CHANNEL_NUMBER 2 +#define I2S_TX_INT_THRESHOLD 7 +#define I2S_RX_INT_THRESHOLD 1 +#define I2S_DMA_TRANSFER_EVENT 1 +#define I2S_RING_BUFFER_NUMBER 4 +#define I2S_DMA_DATA_CMP_MIDDLE 9 +#define I2S_DMA_DATA_CMP_END (CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI - 1) +#define I2S_DMA_TRANS_STEP 2 + +#define I2S_TASK_PRIO 24 +#define I2S_TASK_STACK_SIZE 0xc00 + +static uint32_t g_i2s_dma_data0[CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI] = { 0 }; +static uint32_t g_i2s_dma_data1[CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI] = { 0 }; +static uint32_t g_i2s_dma_data2[CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI] = { 0 }; +static uint32_t g_i2s_dma_data3[CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI] = { 0 }; +static uint32_t *g_i2s_dma_data[I2S_RING_BUFFER_NUMBER] = { + g_i2s_dma_data0, g_i2s_dma_data1, g_i2s_dma_data2, g_i2s_dma_data3}; +static osal_event g_i2s_dma_id; +static uint8_t g_transfer_err_flag = 0; +static uint32_t g_cb_count = 0; + +static int32_t i2s_add_dma_lli_node(uint8_t index, dma_channel_t dma_channel, dma_transfer_cb_t trans_done) +{ + dma_ch_user_peripheral_config_t transfer_config; + + transfer_config.src = i2s_porting_rx_merge_data_addr_get(SIO_BUS_0); + transfer_config.dest = (uint32_t)(uintptr_t)g_i2s_dma_data[index]; + transfer_config.transfer_num = (uint16_t)CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI; + transfer_config.src_handshaking = HAL_DMA_HANDSHAKING_I2S_RX; + transfer_config.dest_handshaking = 0; + transfer_config.trans_type = HAL_DMA_TRANS_PERIPHERAL_TO_MEMORY_DMA; + transfer_config.trans_dir = HAL_DMA_TRANSFER_DIR_PERIPHERAL_TO_MEM; + transfer_config.priority = 0; + transfer_config.src_width = HAL_DMA_TRANSFER_WIDTH_32; + transfer_config.dest_width = HAL_DMA_TRANSFER_WIDTH_32; + transfer_config.burst_length = 0; + transfer_config.src_increment = HAL_DMA_ADDRESS_INC_NO_CHANGE; + transfer_config.dest_increment = HAL_DMA_ADDRESS_INC_INCREMENT; + transfer_config.protection = HAL_DMA_PROTECTION_CONTROL_BUFFERABLE; + + errcode_t ret = uapi_dma_configure_peripheral_transfer_lli(dma_channel, &transfer_config, trans_done); + if (ret != ERRCODE_SUCC) { + osal_printk("%s Configure the DMA fail. %x\r\n", "i2s dma lli", ret); + return 1; + } + return 0; +} + +void app_printf_err(void) +{ + if (g_cb_count >= I2S_RING_BUFFER_NUMBER && g_transfer_err_flag) { + g_transfer_err_flag = 0; + // receive ok + if ((g_i2s_dma_data0[0] == g_i2s_dma_data1[0]) && (g_i2s_dma_data1[0] == g_i2s_dma_data2[0]) && + (g_i2s_dma_data2[0] == g_i2s_dma_data3[0]) && + (g_i2s_dma_data0[I2S_DMA_DATA_CMP_MIDDLE] == g_i2s_dma_data1[I2S_DMA_DATA_CMP_MIDDLE]) && + (g_i2s_dma_data1[I2S_DMA_DATA_CMP_MIDDLE] == g_i2s_dma_data2[I2S_DMA_DATA_CMP_MIDDLE]) && + (g_i2s_dma_data2[I2S_DMA_DATA_CMP_MIDDLE] == g_i2s_dma_data3[I2S_DMA_DATA_CMP_MIDDLE]) && + (g_i2s_dma_data0[I2S_DMA_DATA_CMP_END] == g_i2s_dma_data1[I2S_DMA_DATA_CMP_END]) && + (g_i2s_dma_data1[I2S_DMA_DATA_CMP_END] == g_i2s_dma_data2[I2S_DMA_DATA_CMP_END]) && + (g_i2s_dma_data2[I2S_DMA_DATA_CMP_END] == g_i2s_dma_data3[I2S_DMA_DATA_CMP_END])) { + osal_printk("recv OK\r\n"); + return; + } + // receive error + for (uint32_t j = 0; j < I2S_RING_BUFFER_NUMBER; j++) { + for (uint32_t i = 0; i < CONFIG_I2S_TRANSFER_LEN_OF_DMA_LLI; i += I2S_DMA_TRANS_STEP) { + osal_printk("%d, %d ~ %x\r\n", j, i, g_i2s_dma_data[j][i]); + } + } + } +} + +static void i2s_dma_trans_done_callback(uint8_t intr, uint8_t channel, uintptr_t arg) +{ + unused(channel); + unused(arg); + switch (intr) { + case HAL_DMA_INTERRUPT_TFR: + g_cb_count++; + if (g_cb_count >= I2S_RING_BUFFER_NUMBER) { + g_transfer_err_flag = 1; + } + if (osal_event_write(&g_i2s_dma_id, I2S_DMA_TRANSFER_EVENT) != OSAL_SUCCESS) { + osal_printk("osal_event_write fail!\r\n"); + return; + } + break; + case HAL_DMA_INTERRUPT_ERR: + osal_printk("i2s DMA transfer error.\r\n"); + break; + default: + break; + } +} + +static void *i2s_dma_slave_task(const char *arg) +{ + unused(arg); + if (osal_event_init(&g_i2s_dma_id) != OSAL_SUCCESS) { + return NULL; + } + uapi_dma_deinit(); + uapi_i2s_deinit(SIO_BUS_0); + uapi_i2s_init(SIO_BUS_0, NULL); + sio_porting_i2s_pinmux(); + i2s_config_t config = { + .drive_mode= SLAVE, + .transfer_mode = STD_MODE, + .data_width = THIRTY_TWO_BIT, + .channels_num = TWO_CH, + .timing = NONE_TIMING_MODE, + .clk_edge = RISING_EDGE, + .div_number = I2S_DIV_NUMBER, + .number_of_channels = I2S_CHANNEL_NUMBER, + }; + i2s_dma_attr_t attr = { + .tx_dma_enable = 0, + .tx_int_threshold = I2S_TX_INT_THRESHOLD, + .rx_dma_enable = 1, + .rx_int_threshold = I2S_RX_INT_THRESHOLD, + }; + + uapi_i2s_set_config(SIO_BUS_0, &config); + uapi_i2s_dma_config(SIO_BUS_0, &attr); + + /* DMA init. */ + uapi_dma_init(); + uapi_dma_open(); + + dma_channel_t dma_channel = uapi_dma_get_lli_channel(0, HAL_DMA_HANDSHAKING_MAX_NUM); + for (uint8_t i = 0; i < I2S_RING_BUFFER_NUMBER; i++) { + if (i2s_add_dma_lli_node(i, dma_channel, i2s_dma_trans_done_callback) != 0) { + osal_printk("i2s_add_dma_lli_node fail!\r\n"); + return NULL; + } + } + + if (uapi_dma_enable_lli(dma_channel, i2s_dma_trans_done_callback, (uintptr_t)NULL) == ERRCODE_SUCC) { + osal_printk("dma enable lli memory transfer succ!\r\n"); + } + hal_sio_set_rx_enable(SIO_BUS_0, 1); + + while (1) { + uapi_watchdog_kick(); + if (!(osal_event_read(&g_i2s_dma_id, I2S_DMA_TRANSFER_EVENT, OSAL_WAIT_FOREVER, + OSAL_WAITMODE_AND | OSAL_WAITMODE_CLR))) { + continue; + } + app_printf_err(); + } + return NULL; +} + +static void i2s_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)i2s_dma_slave_task, 0, "I2sDmaSlaveTask", + I2S_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, I2S_TASK_PRIO); + } + osal_kthread_unlock(); +} + +/* Run the i2s_entry. */ +app_run(i2s_entry); \ No newline at end of file diff --git a/application/samples/peripheral/pinctrl/CMakeLists.txt b/application/samples/peripheral/pinctrl/CMakeLists.txt new file mode 100755 index 0000000..ab7cb58 --- /dev/null +++ b/application/samples/peripheral/pinctrl/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/pinctrl_demo.c" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/peripheral/pinctrl/Kconfig b/application/samples/peripheral/pinctrl/Kconfig new file mode 100755 index 0000000..9cdabc3 --- /dev/null +++ b/application/samples/peripheral/pinctrl/Kconfig @@ -0,0 +1,9 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config PINCTRL_USE_PIN + int + prompt "Choose Pinctrl use pin." + depends on SAMPLE_SUPPORT_PINCTRL + default 23 \ No newline at end of file diff --git a/application/samples/peripheral/pinctrl/pinctrl.code-workspace b/application/samples/peripheral/pinctrl/pinctrl.code-workspace new file mode 100755 index 0000000..5bca9ad --- /dev/null +++ b/application/samples/peripheral/pinctrl/pinctrl.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/pinctrl" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/pinctrl/pinctrl_demo.c b/application/samples/peripheral/pinctrl/pinctrl_demo.c new file mode 100755 index 0000000..fc9e5ee --- /dev/null +++ b/application/samples/peripheral/pinctrl/pinctrl_demo.c @@ -0,0 +1,80 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: PINCTRL Sample Source. \n + * + * History: \n + * 2023-07-27, Create file. \n + */ +#include "pinctrl.h" +#include "common_def.h" +#include "soc_osal.h" +#include "app_init.h" + +#define PINCTRL_PIN_MODE 5 +#define PINCTRL_PIN_DS 3 +#define PINCTRL_PIN_PULL 2 + +#define PINCTRL_TASK_PRIO 24 +#define PINCTRL_TASK_STACK_SIZE 0x1000 + +static void *pinctrl_task(const char *arg) +{ + unused(arg); + pin_t pin = CONFIG_PINCTRL_USE_PIN; + pin_mode_t mode; + pin_drive_strength_t ds; + pin_pull_t pull; + + /* PINCTRL init. */ + uapi_pin_init(); + + osal_printk("start get pin<%d> mode!\r\n", pin); + mode = uapi_pin_get_mode(pin); + osal_printk("the mode of pin<%d> is %d.\r\n", pin, mode); + mode = PINCTRL_PIN_MODE; + osal_printk("start set pin<%d> mode<%d>!\r\n", pin, mode); + if (uapi_pin_set_mode(pin, mode) == ERRCODE_SUCC && uapi_pin_get_mode(pin) == mode) { + osal_printk("set pin<%d> mode<%d> succ.\r\n", pin, mode); + } + + osal_printk("\r\n"); + osal_printk("start get pin<%d> driver-strength!\r\n", pin); + ds = uapi_pin_get_ds(pin); + osal_printk("The driver-strength of pin<%d> is %d.\r\n", pin, ds); + ds = PINCTRL_PIN_DS; + osal_printk("start set pin<%d> driver-strength<%d>!\r\n", pin, ds); + if (uapi_pin_set_ds(pin, ds) == ERRCODE_SUCC && uapi_pin_get_ds(pin) == ds) { + osal_printk("set pin<%d> driver-strength<%d> succ.\r\n", pin, ds); + } + + osal_printk("\r\n"); + osal_printk("start get pin<%d> pull/down status!\r\n", pin); + pull = uapi_pin_get_pull(pin); + osal_printk("The pull/down status of pin<%d> is %d.\r\n", pin, pull); + pull = PINCTRL_PIN_PULL; + osal_printk("start set pin<%d> pull/down status<%d>!\r\n", pin, pull); + if (uapi_pin_set_pull(pin, pull) == ERRCODE_SUCC && uapi_pin_get_pull(pin) == pull) { + osal_printk("set pin<%d> pull/down status<%d> succ.\r\n", pin, pull); + } + + /* PINCTRL deinit. */ + uapi_pin_deinit(); + + return NULL; +} + +static void pinctrl_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)pinctrl_task, 0, "PinctrlTask", PINCTRL_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, PINCTRL_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the pinctrl_entry. */ +app_run(pinctrl_entry); \ No newline at end of file diff --git a/application/samples/peripheral/pwm/CMakeLists.txt b/application/samples/peripheral/pwm/CMakeLists.txt new file mode 100755 index 0000000..445b0f3 --- /dev/null +++ b/application/samples/peripheral/pwm/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/pwm_demo.c" PARENT_SCOPE) diff --git a/application/samples/peripheral/pwm/Kconfig b/application/samples/peripheral/pwm/Kconfig new file mode 100755 index 0000000..0ffefc8 --- /dev/null +++ b/application/samples/peripheral/pwm/Kconfig @@ -0,0 +1,28 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config PWM_CHANNEL + int + prompt "Choose PWM Test Channel." + depends on SAMPLE_SUPPORT_PWM + default 0 + +config PWM_GROUP_ID + int + prompt "Choose PWM Test Group ID." + depends on SAMPLE_SUPPORT_PWM && PWM_USING_V151 + default 0 + +config PWM_PIN + int + prompt "Choose PWM pin." + depends on SAMPLE_SUPPORT_PWM + default 20 + +config PWM_PIN_MODE + int + prompt "Choose PWM pin mode." + default 3 + depends on SAMPLE_SUPPORT_PWM + diff --git a/application/samples/peripheral/pwm/pwm.code-workspace b/application/samples/peripheral/pwm/pwm.code-workspace new file mode 100755 index 0000000..16ea51c --- /dev/null +++ b/application/samples/peripheral/pwm/pwm.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/pwm" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/pwm/pwm_demo.c b/application/samples/peripheral/pwm/pwm_demo.c new file mode 100755 index 0000000..e52d28e --- /dev/null +++ b/application/samples/peripheral/pwm/pwm_demo.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: PWM Sample Source. \n + * + * History: \n + * 2023-06-27, Create file. \n + */ +#if defined(CONFIG_PWM_SUPPORT_LPM) +#include "pm_veto.h" +#endif +#include "common_def.h" +#include "pinctrl.h" +#include "pwm.h" +#include "tcxo.h" +#include "soc_osal.h" +#include "app_init.h" + +#define TEST_TCXO_DELAY_1000MS 1000 + +#define PWM_TASK_PRIO 24 +#define PWM_TASK_STACK_SIZE 0x1000 + +static errcode_t pwm_sample_callback(uint8_t channel) +{ + osal_printk("PWM %d, cycle done. \r\n", channel); + return ERRCODE_SUCC; +} + +static void *pwm_task(const char *arg) +{ + UNUSED(arg); + pwm_config_t cfg_no_repeat = { + 100, + 100, + 0, + 0xFF, + false + }; + + uapi_pin_set_mode(CONFIG_PWM_PIN, CONFIG_PWM_PIN_MODE); + uapi_pwm_deinit(); + uapi_pwm_init(); + uapi_pwm_open(CONFIG_PWM_CHANNEL, &cfg_no_repeat); + + uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); + uapi_pwm_unregister_interrupt(CONFIG_PWM_CHANNEL); + uapi_pwm_register_interrupt(CONFIG_PWM_CHANNEL, pwm_sample_callback); +#ifdef CONFIG_PWM_USING_V151 + uint8_t channel_id = CONFIG_PWM_CHANNEL; + /* channel_id can also choose to configure multiple channels, and the third parameter also needs to be adjusted + accordingly. */ + uapi_pwm_set_group(CONFIG_PWM_GROUP_ID, &channel_id, 1); + /* Here you can also call the uapi_pwm_start interface to open each channel individually. */ + uapi_pwm_start_group(CONFIG_PWM_GROUP_ID); +#else + uapi_pwm_start(CONFIG_PWM_CHANNEL); +#endif + + uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); +#ifdef CONFIG_PWM_USING_V151 + uapi_pwm_close(CONFIG_PWM_GROUP_ID); +#else + uapi_pwm_close(CONFIG_PWM_CHANNEL); +#endif + + uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); + uapi_pwm_deinit(); + return NULL; +} + +static void pwm_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)pwm_task, 0, "PwmTask", PWM_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, PWM_TASK_PRIO); + } + osal_kthread_unlock(); +} + +/* Run the pwm_entry. */ +app_run(pwm_entry); \ No newline at end of file diff --git a/application/samples/peripheral/pwm_light/CMakeLists.txt b/application/samples/peripheral/pwm_light/CMakeLists.txt new file mode 100755 index 0000000..445b0f3 --- /dev/null +++ b/application/samples/peripheral/pwm_light/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/pwm_demo.c" PARENT_SCOPE) diff --git a/application/samples/peripheral/pwm_light/Kconfig b/application/samples/peripheral/pwm_light/Kconfig new file mode 100755 index 0000000..0ffefc8 --- /dev/null +++ b/application/samples/peripheral/pwm_light/Kconfig @@ -0,0 +1,28 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config PWM_CHANNEL + int + prompt "Choose PWM Test Channel." + depends on SAMPLE_SUPPORT_PWM + default 0 + +config PWM_GROUP_ID + int + prompt "Choose PWM Test Group ID." + depends on SAMPLE_SUPPORT_PWM && PWM_USING_V151 + default 0 + +config PWM_PIN + int + prompt "Choose PWM pin." + depends on SAMPLE_SUPPORT_PWM + default 20 + +config PWM_PIN_MODE + int + prompt "Choose PWM pin mode." + default 3 + depends on SAMPLE_SUPPORT_PWM + diff --git a/application/samples/peripheral/pwm_light/pwm.code-workspace b/application/samples/peripheral/pwm_light/pwm.code-workspace new file mode 100755 index 0000000..16ea51c --- /dev/null +++ b/application/samples/peripheral/pwm_light/pwm.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/pwm" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/pwm_light/pwm_demo.c b/application/samples/peripheral/pwm_light/pwm_demo.c new file mode 100755 index 0000000..8a9a5b6 --- /dev/null +++ b/application/samples/peripheral/pwm_light/pwm_demo.c @@ -0,0 +1,96 @@ +#include "pinctrl.h" +#include "gpio.h" +#include "pwm.h" +#include "timer.h" + +#define LIGHT_GPIO_W GPIO_02 +#define LIGHT_GPIO_Y GPIO_08 + +static uint32_t period_ns = 40000; //80M/2K +static uint8_t channel_id_w = 0; +static uint8_t channel_id_y = 0; +static uint32_t high_ns = 0; +static uint32_t low_ns = 0; +void hfgpio_pwm_init(void) +{ + high_ns = ((period_ns / 1000) * 0) / 1000; // 高电平时间 + low_ns = period_ns - high_ns; // 低电平时间 + pwm_config_t cfg_no_repeat = { + low_ns, + high_ns, + 0, + 0xFF, + true + }; + channel_id_w = LIGHT_GPIO_W % 8; + channel_id_y = LIGHT_GPIO_Y % 8; + + uapi_pin_set_mode(LIGHT_GPIO_W, PIN_MODE_1); + uapi_pin_set_mode(LIGHT_GPIO_Y, PIN_MODE_1); + uapi_pwm_deinit(); + uapi_pwm_init(); + uapi_pwm_open(channel_id_w, &cfg_no_repeat); + uapi_pwm_set_group(channel_id_w, &channel_id_w, 1); + uapi_pwm_start_group(channel_id_w); + + uapi_pwm_open(channel_id_y, &cfg_no_repeat); + uapi_pwm_set_group(channel_id_y, &channel_id_y, 1); + uapi_pwm_start_group(channel_id_y); +} + +static void hfgpio_pwm_update(int fid, uint32_t hrate) +{ + high_ns = ((period_ns / 1000) * hrate) / 1000; // 高电平时间 + low_ns = period_ns - high_ns; // 低电平时间 + + if(fid == LIGHT_GPIO_W){ + uapi_pwm_update_duty_ratio(channel_id_w, low_ns, high_ns); + uapi_pwm_start_group(channel_id_w); + }else if(fid == LIGHT_GPIO_Y){ + uapi_pwm_update_duty_ratio(channel_id_y, low_ns, high_ns); + uapi_pwm_start_group(channel_id_y); + } +} + +static int pwm_hrate = 0; +static int dir_flag = 0; +static timer_handle_t timer1_handle = 0; +static void light_dim_timer_callback(uintptr_t data) +{ + if(data){} + if(dir_flag == 0){ + pwm_hrate++; + if(pwm_hrate == 1000){ + dir_flag = 1; + } + } + else if(dir_flag == 1){ + pwm_hrate--; + if(pwm_hrate == 0){ + dir_flag = 0; + } + } + hfgpio_pwm_update(LIGHT_GPIO_W, pwm_hrate); + hfgpio_pwm_update(LIGHT_GPIO_Y, pwm_hrate); + + uapi_timer_start(timer1_handle, 5000, light_dim_timer_callback, 0); +} + +void light_hwtimer_dim_entry(void) +{ + uapi_timer_init(); + int ret = 0; + ret = uapi_timer_adapter(TIMER_INDEX_1, TIMER_1_IRQN, 1); + ret = uapi_timer_create(TIMER_INDEX_1, &timer1_handle); + ret = uapi_timer_start(timer1_handle, 1000, light_dim_timer_callback, 0); + if(ret != 0) + osal_printk("hwtimer start fail\r\n"); + else + osal_printk("hwtimer start success\r\n"); +} + +void pwm_test(void) +{ + hfgpio_pwm_init(); + light_hwtimer_dim_entry(); +} \ No newline at end of file diff --git a/application/samples/peripheral/sfc/CMakeLists.txt b/application/samples/peripheral/sfc/CMakeLists.txt new file mode 100755 index 0000000..ea231bb --- /dev/null +++ b/application/samples/peripheral/sfc/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/sfc_demo.c" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/peripheral/sfc/Kconfig b/application/samples/peripheral/sfc/Kconfig new file mode 100755 index 0000000..ae67844 --- /dev/null +++ b/application/samples/peripheral/sfc/Kconfig @@ -0,0 +1,15 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config SFC_SAMPLE_USER_ADDR + hex + prompt "choose SFC sample Start Address(Real address of the flash memory)." + depends on SAMPLE_SUPPORT_SFC + default 0x7C000 + +config SFC_SAMPLE_USER_SIZE + hex + prompt "choose SFC sample End Address(Real address of the flash memory)." + depends on SAMPLE_SUPPORT_SFC + default 0x1000 \ No newline at end of file diff --git a/application/samples/peripheral/sfc/sfc.code-workspace b/application/samples/peripheral/sfc/sfc.code-workspace new file mode 100755 index 0000000..3144b82 --- /dev/null +++ b/application/samples/peripheral/sfc/sfc.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/sfc" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/sfc/sfc_demo.c b/application/samples/peripheral/sfc/sfc_demo.c new file mode 100755 index 0000000..351c6a7 --- /dev/null +++ b/application/samples/peripheral/sfc/sfc_demo.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Provides SFC sample source \n + * + * History: \n + * 2024-03-04, Create file. \n + */ +#include "soc_osal.h" +#include "securec.h" +#include "sfc.h" +#include "sfc_porting.h" +#include "app_init.h" +#include "memory_config_common.h" + +#define SFC_TASK_PRIO 24 +#define SFC_TASK_STACK_SIZE 0x1000 +#define SFC_SAMPLE_LEN 0x80000 +#define SFC_PRINT_BUFF_LEN 32 +uint8_t g_print_data_buff[SFC_PRINT_BUFF_LEN] = {0}; +uint8_t g_write_data_buff[SFC_PRINT_BUFF_LEN] = {0}; + +static void sfc_sample_start_api_test(void) +{ + osal_printk("API test start\r\n"); + uint32_t remained_len = CONFIG_SFC_SAMPLE_USER_SIZE; + uint32_t start_addr = CONFIG_SFC_SAMPLE_USER_ADDR; + while (remained_len > 0) { + uint32_t cur_len = remained_len > SFC_PRINT_BUFF_LEN ? SFC_PRINT_BUFF_LEN : remained_len; + uapi_sfc_reg_read(start_addr, g_print_data_buff, cur_len); + for (uint8_t i = 0; i < cur_len; i++) { + osal_printk("%02x ", g_print_data_buff[i]); + } + uapi_sfc_reg_write(start_addr, g_write_data_buff, cur_len); + start_addr += cur_len; + remained_len -= cur_len; + osal_printk("\r\n"); + } + start_addr = CONFIG_SFC_SAMPLE_USER_ADDR; + remained_len = CONFIG_SFC_SAMPLE_USER_SIZE; + while (remained_len > 0) { + uint32_t cur_len = remained_len > SFC_PRINT_BUFF_LEN ? SFC_PRINT_BUFF_LEN : remained_len; + uapi_sfc_reg_read(start_addr, g_print_data_buff, cur_len); + for (uint8_t i = 0; i < cur_len; i++) { + osal_printk("%02x ", g_print_data_buff[i]); + } + start_addr += cur_len; + remained_len -= cur_len; + osal_printk("\r\n"); + } +} + +static void *sfc_task(const char *arg) +{ + unused(arg); + for (uint8_t i = 0; i < SFC_PRINT_BUFF_LEN; i++) { + g_write_data_buff[i] = i; + } + /* Erase User space */ + osal_printk("Erasing for API sample...\r\n"); + errcode_t ret = uapi_sfc_reg_erase(CONFIG_SFC_SAMPLE_USER_ADDR, CONFIG_SFC_SAMPLE_USER_SIZE); + if (ret != ERRCODE_SUCC) { + osal_printk("flash erase failed! ret = %x\r\n", ret); + return NULL; + } + osal_printk("Start API read sample...\r\n"); + sfc_sample_start_api_test(); + return NULL; +} + +static void sfc_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)sfc_task, 0, "SFCTask", SFC_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, SFC_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the spi_master_entry. */ +app_run(sfc_entry); \ No newline at end of file diff --git a/application/samples/peripheral/spi/CMakeLists.txt b/application/samples/peripheral/spi/CMakeLists.txt new file mode 100755 index 0000000..478f7b2 --- /dev/null +++ b/application/samples/peripheral/spi/CMakeLists.txt @@ -0,0 +1,9 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_SPI_MASTER) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/spi_master_demo.c" PARENT_SCOPE) +elseif(DEFINED CONFIG_SAMPLE_SUPPORT_SPI_SLAVE) + set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/spi_slave_demo.c" PARENT_SCOPE) +endif() \ No newline at end of file diff --git a/application/samples/peripheral/spi/Kconfig b/application/samples/peripheral/spi/Kconfig new file mode 100755 index 0000000..d7d5647 --- /dev/null +++ b/application/samples/peripheral/spi/Kconfig @@ -0,0 +1,127 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config SAMPLE_SUPPORT_SPI_MASTER + bool + prompt "Support SPI Master Sample." + default n + depends on SAMPLE_SUPPORT_SPI + help + This option means support SPI Master Sample. + +config SPI_MASTER_BUS_ID + int + prompt "Choose SPI master bus id." + depends on SAMPLE_SUPPORT_SPI_MASTER + default 2 + +config SPI_DI_MASTER_PIN + int + prompt "Choose SPI DI master pin." + depends on SAMPLE_SUPPORT_SPI_MASTER + default 16 + +config SPI_DO_MASTER_PIN + int + prompt "Choose SPI DO master pin." + depends on SAMPLE_SUPPORT_SPI_MASTER + default 17 + +config SPI_CLK_MASTER_PIN + int + prompt "Choose SPI CLK master pin." + depends on SAMPLE_SUPPORT_SPI_MASTER + default 18 + +config SPI_CS_MASTER_PIN + int + prompt "Choose SPI CS master pin." + depends on SAMPLE_SUPPORT_SPI_MASTER + default 19 + +config SPI_MASTER_PIN_MODE + int + prompt "Choose SPI master pin mode." + depends on SAMPLE_SUPPORT_SPI_MASTER + default 1 + +config SPI_MASTER_SUPPORT_QSPI + bool + prompt "SPI master support QSPI." + depends on SAMPLE_SUPPORT_SPI_MASTER + default n + +config SPI_MASTER_D3_PIN_MODE + int + prompt "Choose QSPI master D3 pin mode." + depends on SPI_MASTER_SUPPORT_QSPI + default 1 + +config SPI_MASTER_D2_PIN_MODE + int + prompt "Choose QSPI master D2 pin mode." + depends on SPI_MASTER_SUPPORT_QSPI + default 1 + +config SPI_MASTER_D3_PIN + int + prompt "Choose QSPI master D3 pin." + depends on SPI_MASTER_SUPPORT_QSPI + default 40 + +config SPI_MASTER_D2_PIN + int + prompt "Choose QSPI master D2 pin." + depends on SPI_MASTER_SUPPORT_QSPI + default 41 + +config SAMPLE_SUPPORT_SPI_SLAVE + bool + prompt "Support SPI Slave Sample." + default n + depends on SAMPLE_SUPPORT_SPI + help + This option means support SPI Slave Sample. + +config SPI_SLAVE_BUS_ID + int + prompt "Choose SPI slave bus id." + depends on SAMPLE_SUPPORT_SPI_SLAVE + default 4 + +config SPI_DI_SLAVE_PIN + int + prompt "Choose SPI DI slave pin." + depends on SAMPLE_SUPPORT_SPI_SLAVE + default 12 + +config SPI_DO_SLAVE_PIN + int + prompt "Choose SPI DO slave pin." + depends on SAMPLE_SUPPORT_SPI_SLAVE + default 13 + +config SPI_CLK_SLAVE_PIN + int + prompt "Choose SPI CLK slave pin." + depends on SAMPLE_SUPPORT_SPI_SLAVE + default 14 + +config SPI_CS_SLAVE_PIN + int + prompt "Choose SPI CS slave pin." + depends on SAMPLE_SUPPORT_SPI_SLAVE + default 15 + +config SPI_SLAVE_PIN_MODE + int + prompt "Choose SPI slave pin mode." + depends on SAMPLE_SUPPORT_SPI_SLAVE + default 5 + +config SPI_TRANSFER_LEN + int + prompt "Choose SPI transfer length." + depends on SAMPLE_SUPPORT_SPI + default 8 \ No newline at end of file diff --git a/application/samples/peripheral/spi/spi.code-workspace b/application/samples/peripheral/spi/spi.code-workspace new file mode 100755 index 0000000..a94715a --- /dev/null +++ b/application/samples/peripheral/spi/spi.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/spi" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/spi/spi_master_demo.c b/application/samples/peripheral/spi/spi_master_demo.c new file mode 100755 index 0000000..90d8954 --- /dev/null +++ b/application/samples/peripheral/spi/spi_master_demo.c @@ -0,0 +1,187 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: SPI Sample Source. \n + * + * History: \n + * 2023-06-25, Create file. \n + */ +#include "pinctrl.h" +#include "spi.h" +#include "soc_osal.h" +#include "app_init.h" + +#define SPI_SLAVE_NUM 1 +#define SPI_FREQUENCY 2 +#define SPI_CLK_POLARITY 0 +#define SPI_CLK_PHASE 0 +#define SPI_FRAME_FORMAT 0 +#define SPI_FRAME_FORMAT_STANDARD 0 +#define SPI_FRAME_SIZE_8 0x1f +#define SPI_TMOD 0 +#define SPI_WAIT_CYCLES 0x10 +#if defined(CONFIG_SPI_SUPPORT_DMA) && !(defined(CONFIG_SPI_SUPPORT_POLL_AND_DMA_AUTO_SWITCH)) +#define SPI_DMA_WIDTH 2 +#endif +#if defined(CONFIG_SPI_MASTER_SUPPORT_QSPI) +#define QSPI_WRITE_CMD 0x38 +#define QSPI_WRITE_ADDR 0x123 +#endif +#define SPI_TASK_DURATION_MS 500 +#define SPI_TASK_PRIO 24 +#define SPI_TASK_STACK_SIZE 0x1000 + +static void app_spi_init_pin(void) +{ + uapi_pin_set_mode(CONFIG_SPI_DI_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_DO_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_CLK_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_CS_MASTER_PIN, CONFIG_SPI_MASTER_PIN_MODE); +#if defined(CONFIG_SPI_MASTER_SUPPORT_QSPI) + uapi_pin_set_mode(CONFIG_SPI_MASTER_D2_PIN, CONFIG_SPI_MASTER_D2_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_MASTER_D3_PIN, CONFIG_SPI_MASTER_D3_PIN_MODE); +#endif +} + +#if defined(CONFIG_SPI_SUPPORT_INTERRUPT) && (CONFIG_SPI_SUPPORT_INTERRUPT == 1) +static void app_spi_master_write_int_handler(const void *buffer, uint32_t length) +{ + unused(buffer); + unused(length); + osal_printk("spi master write interrupt start!\r\n"); +} + +static void app_spi_master_rx_callback(const void *buffer, uint32_t length, bool error) +{ + if (buffer == NULL || length == 0) { + osal_printk("spi master transfer illegal data!\r\n"); + return; + } + if (error) { + osal_printk("app_spi_master_read_int error!\r\n"); + return; + } + + uint8_t *buff = (uint8_t *)buffer; + for (uint32_t i = 0; i < length; i++) { + osal_printk("buff[%d] = %x\r\n", i, buff[i]); + } + osal_printk("app_spi_master_read_int success!\r\n"); +} +#endif /* CONFIG_SPI_SUPPORT_INTERRUPT */ + +static void app_spi_master_init_config(void) +{ + spi_attr_t config = { 0 }; + spi_extra_attr_t ext_config = { 0 }; + + config.is_slave = false; + config.slave_num = SPI_SLAVE_NUM; + config.bus_clk = SPI_CLK_FREQ; + config.freq_mhz = SPI_FREQUENCY; + config.clk_polarity = SPI_CLK_POLARITY; + config.clk_phase = SPI_CLK_PHASE; + config.frame_format = SPI_FRAME_FORMAT; + config.spi_frame_format = HAL_SPI_FRAME_FORMAT_STANDARD; + config.frame_size = SPI_FRAME_SIZE_8; + config.tmod = SPI_TMOD; + config.sste = 0; + + ext_config.qspi_param.wait_cycles = SPI_WAIT_CYCLES; +#if defined(CONFIG_SPI_MASTER_SUPPORT_QSPI) + config.tmod = HAL_SPI_TRANS_MODE_TX; + config.sste = 0; + config.spi_frame_format = HAL_SPI_FRAME_FORMAT_QUAD; + ext_config.qspi_param.trans_type = HAL_SPI_TRANS_TYPE_INST_S_ADDR_Q; + ext_config.qspi_param.inst_len = HAL_SPI_INST_LEN_8; + ext_config.qspi_param.addr_len = HAL_SPI_ADDR_LEN_24; + ext_config.qspi_param.wait_cycles = 0; +#endif + + uapi_spi_init(CONFIG_SPI_MASTER_BUS_ID, &config, &ext_config); +#if defined(CONFIG_SPI_SUPPORT_DMA) && (CONFIG_SPI_SUPPORT_DMA == 1) + uapi_dma_init(); + uapi_dma_open(); +#ifndef CONFIG_SPI_SUPPORT_POLL_AND_DMA_AUTO_SWITCH + spi_dma_config_t dma_cfg = { + .src_width = SPI_DMA_WIDTH, + .dest_width = SPI_DMA_WIDTH, + .burst_length = 0, + .priority = 0 + }; + if (uapi_spi_set_dma_mode(CONFIG_SPI_MASTER_BUS_ID, true, &dma_cfg) != ERRCODE_SUCC) { + osal_printk("spi%d master set dma mode fail!\r\n"); + } +#endif +#endif /* CONFIG_SPI_SUPPORT_DMA */ + +#if defined(CONFIG_SPI_SUPPORT_INTERRUPT) && (CONFIG_SPI_SUPPORT_INTERRUPT == 1) + if (uapi_spi_set_irq_mode(CONFIG_SPI_MASTER_BUS_ID, true, app_spi_master_rx_callback, + app_spi_master_write_int_handler) == ERRCODE_SUCC) { + osal_printk("spi%d master set irq mode succ!\r\n", CONFIG_SPI_MASTER_BUS_ID); + } +#endif /* CONFIG_SPI_SUPPORT_INTERRUPT */ +} + +static void *spi_master_task(const char *arg) +{ + unused(arg); + /* SPI pinmux. */ + app_spi_init_pin(); + + /* SPI master init config. */ + app_spi_master_init_config(); + + /* SPI data config. */ + uint8_t tx_data[CONFIG_SPI_TRANSFER_LEN] = { 0 }; + for (uint32_t loop = 0; loop < CONFIG_SPI_TRANSFER_LEN; loop++) { + tx_data[loop] = (loop & 0xFF); + } + uint8_t rx_data[CONFIG_SPI_TRANSFER_LEN] = { 0 }; + spi_xfer_data_t data = { + .tx_buff = tx_data, + .tx_bytes = CONFIG_SPI_TRANSFER_LEN, + .rx_buff = rx_data, + .rx_bytes = CONFIG_SPI_TRANSFER_LEN, +#if defined(CONFIG_SPI_MASTER_SUPPORT_QSPI) + .cmd = QSPI_WRITE_CMD, + .addr = QSPI_WRITE_ADDR, +#endif + }; + + while (1) { + osal_msleep(SPI_TASK_DURATION_MS); + osal_printk("spi%d master send start!\r\n", CONFIG_SPI_MASTER_BUS_ID); + if (uapi_spi_master_write(CONFIG_SPI_MASTER_BUS_ID, &data, 0xFFFFFFFF) == ERRCODE_SUCC) { + osal_printk("spi%d master send succ!\r\n", CONFIG_SPI_MASTER_BUS_ID); + } else { + continue; + } + osal_printk("spi%d master receive start!\r\n", CONFIG_SPI_MASTER_BUS_ID); + if (uapi_spi_master_read(CONFIG_SPI_MASTER_BUS_ID, &data, 0xFFFFFFFF) == ERRCODE_SUCC) { +#ifndef CONFIG_SPI_SUPPORT_INTERRUPT + for (uint32_t i = 0; i < data.rx_bytes; i++) { + osal_printk("spi%d master receive data is %x\r\n", CONFIG_SPI_MASTER_BUS_ID, data.rx_buff[i]); + } +#endif + osal_printk("spi%d master receive succ!\r\n", CONFIG_SPI_MASTER_BUS_ID); + } + } + + return NULL; +} + +static void spi_master_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)spi_master_task, 0, "SpiMasterTask", SPI_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, SPI_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the spi_master_entry. */ +app_run(spi_master_entry); \ No newline at end of file diff --git a/application/samples/peripheral/spi/spi_slave_demo.c b/application/samples/peripheral/spi/spi_slave_demo.c new file mode 100755 index 0000000..e6fa3e1 --- /dev/null +++ b/application/samples/peripheral/spi/spi_slave_demo.c @@ -0,0 +1,167 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: SPI Sample Source. \n + * + * History: \n + * 2023-06-25, Create file. \n + */ +#include "pinctrl.h" +#include "spi.h" +#include "soc_osal.h" +#include "app_init.h" + +#define SPI_SLAVE_NUM 1 +#define SPI_FREQUENCY 2 +#define SPI_CLK_POLARITY 0 +#define SPI_CLK_PHASE 0 +#define SPI_FRAME_FORMAT 0 +#define SPI_FRAME_FORMAT_STANDARD 0 +#define SPI_FRAME_SIZE_8 0x1f +#define SPI_TMOD 0 +#define SPI_WAIT_CYCLES 0x10 +#if defined(CONFIG_SPI_SUPPORT_DMA) && !(defined(CONFIG_SPI_SUPPORT_POLL_AND_DMA_AUTO_SWITCH)) +#define SPI_DMA_WIDTH 2 +#endif + +#define SPI_TASK_DURATION_MS 500 +#define SPI_TASK_PRIO 24 +#define SPI_TASK_STACK_SIZE 0x1000 + +static void app_spi_init_pin(void) +{ + uapi_pin_set_mode(CONFIG_SPI_DI_SLAVE_PIN, CONFIG_SPI_SLAVE_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_DO_SLAVE_PIN, CONFIG_SPI_SLAVE_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_CLK_SLAVE_PIN, CONFIG_SPI_SLAVE_PIN_MODE); + uapi_pin_set_mode(CONFIG_SPI_CS_SLAVE_PIN, CONFIG_SPI_SLAVE_PIN_MODE); +} + +#if defined(CONFIG_SPI_SUPPORT_INTERRUPT) && (CONFIG_SPI_SUPPORT_INTERRUPT == 1) +static void app_spi_slave_write_int_handler(const void *buffer, uint32_t length) +{ + unused(buffer); + unused(length); + osal_printk("spi slave write interrupt start!\r\n"); +} + +static void app_spi_slave_rx_callback(const void *buffer, uint32_t length, bool error) +{ + if (buffer == NULL || length == 0) { + osal_printk("spi slave transfer illegal data!\r\n"); + return; + } + if (error) { + osal_printk("app_spi_slave_read_int error!\r\n"); + return; + } + + uint8_t *buff = (uint8_t *)buffer; + for (uint32_t i = 0; i < length; i++) { + osal_printk("buff[%d] = %x\r\n", i, buff[i]); + } + osal_printk("app_spi_slave_read_int success!\r\n"); +} +#endif /* CONFIG_SPI_SUPPORT_INTERRUPT */ + +static void app_spi_slave_init_config(void) +{ + spi_attr_t config = { 0 }; + spi_extra_attr_t ext_config = { 0 }; + + config.is_slave = true; + config.slave_num = SPI_SLAVE_NUM; + config.bus_clk = SPI_CLK_FREQ; + config.freq_mhz = SPI_FREQUENCY; + config.clk_polarity = SPI_CLK_POLARITY; + config.clk_phase = SPI_CLK_PHASE; + config.frame_format = SPI_FRAME_FORMAT; + config.spi_frame_format = HAL_SPI_FRAME_FORMAT_STANDARD; + config.frame_size = SPI_FRAME_SIZE_8; + config.tmod = SPI_TMOD; + config.sste = 0; + + ext_config.qspi_param.wait_cycles = SPI_WAIT_CYCLES; + + uapi_spi_init(CONFIG_SPI_SLAVE_BUS_ID, &config, &ext_config); +#if defined(CONFIG_SPI_SUPPORT_DMA) && (CONFIG_SPI_SUPPORT_DMA == 1) + uapi_dma_init(); + uapi_dma_open(); +#ifndef CONFIG_SPI_SUPPORT_POLL_AND_DMA_AUTO_SWITCH + spi_dma_config_t dma_cfg = { + .src_width = SPI_DMA_WIDTH, + .dest_width = SPI_DMA_WIDTH, + .burst_length = 0, + .priority = 0 + }; + if (uapi_spi_set_dma_mode(CONFIG_SPI_SLAVE_BUS_ID, true, &dma_cfg) != ERRCODE_SUCC) { + osal_printk("spi%d slave set dma mode fail!\r\n"); + } +#endif +#endif /* CONFIG_SPI_SUPPORT_DMA */ + +#if defined(CONFIG_SPI_SUPPORT_INTERRUPT) && (CONFIG_SPI_SUPPORT_INTERRUPT == 1) + if (uapi_spi_set_irq_mode(CONFIG_SPI_SLAVE_BUS_ID, true, app_spi_slave_rx_callback, + app_spi_slave_write_int_handler) == ERRCODE_SUCC) { + osal_printk("spi%d slave set irq mode succ!\r\n", CONFIG_SPI_SLAVE_BUS_ID); + } +#endif /* CONFIG_SPI_SUPPORT_INTERRUPT */ +} + +static void *spi_slave_task(const char *arg) +{ + unused(arg); + /* SPI pinmux. */ + app_spi_init_pin(); + + /* SPI slave init config. */ + app_spi_slave_init_config(); + + /* SPI data config. */ + uint8_t tx_data[CONFIG_SPI_TRANSFER_LEN] = { 0 }; + for (uint32_t loop = 0; loop < CONFIG_SPI_TRANSFER_LEN; loop++) { + tx_data[loop] = (loop & 0xFF); + } + uint8_t rx_data[CONFIG_SPI_TRANSFER_LEN] = { 0 }; + spi_xfer_data_t data = { + .tx_buff = tx_data, + .tx_bytes = CONFIG_SPI_TRANSFER_LEN, + .rx_buff = rx_data, + .rx_bytes = CONFIG_SPI_TRANSFER_LEN, + }; + + while (1) { + osal_msleep(SPI_TASK_DURATION_MS); + osal_printk("spi%d slave receive start!\r\n", CONFIG_SPI_SLAVE_BUS_ID); + if (uapi_spi_slave_read(CONFIG_SPI_SLAVE_BUS_ID, &data, 0xFFFFFFFF) == ERRCODE_SUCC) { +#ifndef CONFIG_SPI_SUPPORT_INTERRUPT + for (uint32_t i = 0; i < data.rx_bytes; i++) { + osal_printk("spi%d slave receive data is %x\r\n", CONFIG_SPI_SLAVE_BUS_ID, data.rx_buff[i]); + } +#endif + osal_printk("spi%d slave receive succ!\r\n", CONFIG_SPI_SLAVE_BUS_ID); + } else { + continue; + } + osal_printk("spi%d slave send start!\r\n", CONFIG_SPI_SLAVE_BUS_ID); + if (uapi_spi_slave_write(CONFIG_SPI_SLAVE_BUS_ID, &data, 0xFFFFFFFF) == ERRCODE_SUCC) { + osal_printk("spi%d slave send succ!\r\n", CONFIG_SPI_SLAVE_BUS_ID); + } + } + + return NULL; +} + +static void spi_slave_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)spi_slave_task, 0, "SpiSlaveTask", SPI_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, SPI_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the spi_slave_entry. */ +app_run(spi_slave_entry); \ No newline at end of file diff --git a/application/samples/peripheral/systick/CMakeLists.txt b/application/samples/peripheral/systick/CMakeLists.txt new file mode 100755 index 0000000..826fc87 --- /dev/null +++ b/application/samples/peripheral/systick/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/systick_demo.c" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/peripheral/systick/systick.code-workspace b/application/samples/peripheral/systick/systick.code-workspace new file mode 100755 index 0000000..d60a852 --- /dev/null +++ b/application/samples/peripheral/systick/systick.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/systick" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/systick/systick_demo.c b/application/samples/peripheral/systick/systick_demo.c new file mode 100755 index 0000000..3b2b2a4 --- /dev/null +++ b/application/samples/peripheral/systick/systick_demo.c @@ -0,0 +1,87 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: SYSTICK Sample Source. \n + * + * History: \n + * 2023-07-17, Create file. \n + */ +#include "pinctrl.h" +#include "systick.h" +#include "common_def.h" +#include "soc_osal.h" +#include "app_init.h" + +#define SYSTICK_DELAY_S 2 +#define SYSTICK_DELAY_MS 1000 +#define SYSTICK_DELAY_US 20000 +#define SYSTICK_TASK_DURATION_MS 500 + +#define SYSTICK_TASK_PRIO 24 +#define SYSTICK_TASK_STACK_SIZE 0x1000 + +static void *systick_task(const char *arg) +{ + unused(arg); + uint64_t count_before_get_s; + uint64_t count_after_get_s; + uint64_t count_before_get_ms; + uint64_t count_after_get_ms; + uint64_t count_before_get_us; + uint64_t count_after_get_us; + + /* SYSTICK init. */ + uapi_systick_init(); + + while (1) { + osal_msleep(SYSTICK_TASK_DURATION_MS); + osal_printk("systick delay %ds!\r\n", SYSTICK_DELAY_S); + count_before_get_s = uapi_systick_get_s(); + uapi_systick_delay_s(SYSTICK_DELAY_S); + count_after_get_s = uapi_systick_get_s(); + osal_printk("count_after_get_s = %llu, count_before_get_s = %llu\r\n", count_after_get_s, count_before_get_s); + osal_printk("count_s = %llu\r\n", count_after_get_s - count_before_get_s); + if (count_after_get_s > count_before_get_s) { + osal_printk("systick get s work normall.\r\n"); + } + + osal_printk("systick delay %dms!\r\n", SYSTICK_DELAY_MS); + count_before_get_ms = uapi_systick_get_ms(); + uapi_systick_delay_ms(SYSTICK_DELAY_MS); + count_after_get_ms = uapi_systick_get_ms(); + osal_printk("count_after_get_ms = %llu, count_before_get_ms = %llu\r\n", count_after_get_ms, + count_before_get_ms); + osal_printk("count_ms = %llu\r\n", count_after_get_ms - count_before_get_ms); + if (count_after_get_ms > count_before_get_ms) { + osal_printk("systick get ms work normall.\r\n"); + } + + osal_printk("systick delay %dus!\r\n", SYSTICK_DELAY_US); + count_before_get_us = uapi_systick_get_us(); + uapi_systick_delay_us(SYSTICK_DELAY_US); + count_after_get_us = uapi_systick_get_us(); + osal_printk("count_after_get_us = %llu, count_before_get_us = %llu\r\n", count_after_get_us, + count_before_get_us); + osal_printk("count_us = %llu\r\n", count_after_get_us - count_before_get_us); + if (count_after_get_us > count_before_get_us) { + osal_printk("systick get us work normall.\r\n"); + } + } + + return NULL; +} + +static void systick_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)systick_task, 0, "SystickTask", SYSTICK_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, SYSTICK_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the systick_entry. */ +app_run(systick_entry); \ No newline at end of file diff --git a/application/samples/peripheral/tasks/CMakeLists.txt b/application/samples/peripheral/tasks/CMakeLists.txt new file mode 100755 index 0000000..f60ac72 --- /dev/null +++ b/application/samples/peripheral/tasks/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/tasks.c" PARENT_SCOPE) diff --git a/application/samples/peripheral/tasks/tasks.c b/application/samples/peripheral/tasks/tasks.c new file mode 100755 index 0000000..c250a6b --- /dev/null +++ b/application/samples/peripheral/tasks/tasks.c @@ -0,0 +1,43 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: Tasks Sample Source. \n + * + * History: \n + * 2023-04-03, Create file. \n + */ +#include "common_def.h" +#include "soc_osal.h" +#include "app_init.h" + +#define TASKS_TEST_DURATION_MS 5000 +#define TASKS_TEST_TASK_PRIO 24 +#define TASKS_TEST_TASK_STACK_SIZE 0x1000 + +static void *tasks_test_task(const char *arg) +{ + unused(arg); + + while (1) { + osal_msleep(TASKS_TEST_DURATION_MS); + osal_printk("Hello BS25, Now you can develop SLE Product!\r\n"); + } + + return NULL; +} + +static void tasks_test_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)tasks_test_task, 0, "TasksTask", + TASKS_TEST_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, TASKS_TEST_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the tasks_test_entry. */ +app_run(tasks_test_entry); \ No newline at end of file diff --git a/application/samples/peripheral/tasks/tasks.code-workspace b/application/samples/peripheral/tasks/tasks.code-workspace new file mode 100755 index 0000000..9c48ecd --- /dev/null +++ b/application/samples/peripheral/tasks/tasks.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/tasks" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/tcxo/CMakeLists.txt b/application/samples/peripheral/tcxo/CMakeLists.txt new file mode 100755 index 0000000..ecb8bb7 --- /dev/null +++ b/application/samples/peripheral/tcxo/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/tcxo_demo.c" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/peripheral/tcxo/tcxo.code-workspace b/application/samples/peripheral/tcxo/tcxo.code-workspace new file mode 100755 index 0000000..1e16363 --- /dev/null +++ b/application/samples/peripheral/tcxo/tcxo.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/tcxo" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/tcxo/tcxo_demo.c b/application/samples/peripheral/tcxo/tcxo_demo.c new file mode 100755 index 0000000..1720423 --- /dev/null +++ b/application/samples/peripheral/tcxo/tcxo_demo.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: TCXO Sample Source. \n + * + * History: \n + * 2023-07-17, Create file. \n + */ +#include "tcxo.h" +#include "common_def.h" +#include "soc_osal.h" +#include "app_init.h" + +#define TCXO_DELAY_MS 1000 +#define TCXO_DELAY_US 20000 +#define TCXO_TASK_DURATION_MS 500 + +#define TCXO_TASK_PRIO 24 +#define TCXO_TASK_STACK_SIZE 0x1000 + +static void *tcxo_task(const char *arg) +{ + unused(arg); + uint64_t count_before_get_ms; + uint64_t count_after_get_ms; + uint64_t count_before_get_us; + uint64_t count_after_get_us; + + /* TCXO init. */ + uapi_tcxo_init(); + + while (1) { + osal_msleep(TCXO_TASK_DURATION_MS); + osal_printk("tcxo delay %dms!\r\n", TCXO_DELAY_MS); + count_before_get_ms = uapi_tcxo_get_ms(); + uapi_tcxo_delay_ms(TCXO_DELAY_MS); + count_after_get_ms = uapi_tcxo_get_ms(); + osal_printk("count_after_get_ms = %llu, count_before_get_ms = %llu\r\n", count_after_get_ms, + count_before_get_ms); + osal_printk("count_ms = %llu\r\n", count_after_get_ms - count_before_get_ms); + if (count_after_get_ms > count_before_get_ms) { + osal_printk("tcxo get ms work normall.\r\n"); + } + + osal_printk("tcxo delay %dus!\r\n", TCXO_DELAY_US); + count_before_get_us = uapi_tcxo_get_us(); + uapi_tcxo_delay_us(TCXO_DELAY_US); + count_after_get_us = uapi_tcxo_get_us(); + osal_printk("count_after_get_us = %llu, count_before_get_us = %llu\r\n", count_after_get_us, + count_before_get_us); + osal_printk("count_us = %llu\r\n", count_after_get_us - count_before_get_us); + if (count_after_get_us > count_before_get_us) { + osal_printk("tcxo get us work normall.\r\n"); + } + } + + return NULL; +} + +static void tcxo_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)tcxo_task, 0, "TcxoTask", TCXO_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, TCXO_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the tcxo_entry. */ +app_run(tcxo_entry); \ No newline at end of file diff --git a/application/samples/peripheral/timer/CMakeLists.txt b/application/samples/peripheral/timer/CMakeLists.txt new file mode 100755 index 0000000..de134e6 --- /dev/null +++ b/application/samples/peripheral/timer/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/timer_demo.c" PARENT_SCOPE) diff --git a/application/samples/peripheral/timer/Kconfig b/application/samples/peripheral/timer/Kconfig new file mode 100755 index 0000000..359cbf5 --- /dev/null +++ b/application/samples/peripheral/timer/Kconfig @@ -0,0 +1,4 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== \ No newline at end of file diff --git a/application/samples/peripheral/timer/timer.code-workspace b/application/samples/peripheral/timer/timer.code-workspace new file mode 100755 index 0000000..0c1e106 --- /dev/null +++ b/application/samples/peripheral/timer/timer.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/timer" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/timer/timer_demo.c b/application/samples/peripheral/timer/timer_demo.c new file mode 100755 index 0000000..660b877 --- /dev/null +++ b/application/samples/peripheral/timer/timer_demo.c @@ -0,0 +1,91 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: Timer Sample Source. \n + * + * History: \n + * 2023-07-18, Create file. \n + */ +#include "timer.h" +#include "tcxo.h" +#include "chip_core_irq.h" +#include "common_def.h" +#include "soc_osal.h" +#include "app_init.h" + +#define TIMER_TIMERS_NUM 4 +#define TIMER_INDEX 1 +#define TIMER_PRIO 1 +#define TIMER_DELAY_INT 5 +#define TIMER1_DELAY_1000US 1000 +#define TIMER2_DELAY_2000US 2000 +#define TIMER3_DELAY_3000US 3000 +#define TIMER4_DELAY_4000US 4000 +#define TIMER_MS_2_US 1000 + +#define TIMER_TASK_PRIO 24 +#define TIMER_TASK_STACK_SIZE 0x1000 + +typedef struct timer_info { + uint32_t start_time; + uint32_t end_time; + uint32_t delay_time; +} timer_info_t; + +static uint32_t g_timer_int_count = 0; +static timer_info_t g_timers_info[TIMER_TIMERS_NUM] = { + {0, 0, TIMER1_DELAY_1000US}, + {0, 0, TIMER2_DELAY_2000US}, + {0, 0, TIMER3_DELAY_3000US}, + {0, 0, TIMER4_DELAY_4000US} +}; + +/* Timed task callback function list. */ +static void timer_timeout_callback(uintptr_t data) +{ + uint32_t timer_index = (uint32_t)data; + g_timers_info[timer_index].end_time = uapi_tcxo_get_ms(); + g_timer_int_count++; +} + +static void *timer_task(const char *arg) +{ + unused(arg); + timer_handle_t timer_index[TIMER_TIMERS_NUM] = { 0 }; + uapi_timer_init(); + uapi_timer_adapter(TIMER_INDEX, TIMER_1_IRQN, TIMER_PRIO); + + for (uint32_t i = 0; i < TIMER_TIMERS_NUM; i++) { + uapi_timer_create(TIMER_INDEX, &timer_index[i]); + g_timers_info[i].start_time = uapi_tcxo_get_ms(); + uapi_timer_start(timer_index[i], g_timers_info[i].delay_time, timer_timeout_callback, i); + osal_msleep(TIMER_DELAY_INT); + } + + while (g_timer_int_count < TIMER_TIMERS_NUM) { + osal_msleep(TIMER_DELAY_INT); + } + + for (uint32_t i = 0; i < TIMER_TIMERS_NUM; i++) { + uapi_timer_stop(timer_index[i]); + uapi_timer_delete(timer_index[i]); + osal_printk("real time[%d] = %dms ", i, (g_timers_info[i].end_time - g_timers_info[i].start_time)); + osal_printk(" delay = %dms\r\n", g_timers_info[i].delay_time / TIMER_MS_2_US); + } + return NULL; +} + +static void timer_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)timer_task, 0, "TimerTask", TIMER_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, TIMER_TASK_PRIO); + osal_kfree(task_handle); + } + osal_kthread_unlock(); +} + +/* Run the timer_entry. */ +app_run(timer_entry); \ No newline at end of file diff --git a/application/samples/peripheral/uart/CMakeLists.txt b/application/samples/peripheral/uart/CMakeLists.txt new file mode 100755 index 0000000..9e47ca2 --- /dev/null +++ b/application/samples/peripheral/uart/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/uart_demo.c" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/peripheral/uart/Kconfig b/application/samples/peripheral/uart/Kconfig new file mode 100755 index 0000000..ccc0d0b --- /dev/null +++ b/application/samples/peripheral/uart/Kconfig @@ -0,0 +1,45 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +config UART_BUS_ID + int + prompt "Choose UART bus id." + depends on SAMPLE_SUPPORT_UART + default 1 + +config UART_TXD_PIN + int + prompt "Choose UART TXD pin." + depends on SAMPLE_SUPPORT_UART + default 17 + +config UART_RXD_PIN + int + prompt "Choose UART RXD pin." + depends on SAMPLE_SUPPORT_UART + default 18 + +config UART_TXD_PIN_MODE + int + prompt "Choose UART TXD pin mode." + depends on SAMPLE_SUPPORT_UART + default 25 + +config UART_RXD_PIN_MODE + int + prompt "Choose UART RXD pin mode." + depends on SAMPLE_SUPPORT_UART + default 24 + +config UART_SUPPORT_INT_MODE + bool + prompt "UART support interrupt mode." + depends on SAMPLE_SUPPORT_UART + default n + +config UART_TRANSFER_SIZE + int + prompt "Config UART transfer size." + depends on SAMPLE_SUPPORT_UART + default 64 \ No newline at end of file diff --git a/application/samples/peripheral/uart/uart.code-workspace b/application/samples/peripheral/uart/uart.code-workspace new file mode 100755 index 0000000..974f6da --- /dev/null +++ b/application/samples/peripheral/uart/uart.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../../" + } + ], + "settings": { + "debug.onTaskErrors": "debugAnyway", + "workspace.samplePath": "./samples/peripheral/uart" + } +} \ No newline at end of file diff --git a/application/samples/peripheral/uart/uart_demo.c b/application/samples/peripheral/uart/uart_demo.c new file mode 100755 index 0000000..ba7a37e --- /dev/null +++ b/application/samples/peripheral/uart/uart_demo.c @@ -0,0 +1,197 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: UART Sample Source. \n + * + * History: \n + * 2023-06-29, Create file. \n + */ +#include "pinctrl.h" +#include "uart.h" +#include "watchdog.h" +#include "soc_osal.h" +#include "app_init.h" +#if defined(CONFIG_UART_SUPPORT_DMA) +#include "dma.h" +#include "hal_dma.h" +#endif + +#define UART_BAUDRATE 115200 +#define CONFIG_UART_INT_WAIT_MS 5 + +#define UART_TASK_PRIO 24 +#define UART_TASK_STACK_SIZE 0x1000 + +static uint8_t g_app_uart_rx_buff[CONFIG_UART_TRANSFER_SIZE] = { 0 }; +#if defined(CONFIG_UART_SUPPORT_INT_MODE) +static uint8_t g_app_uart_int_rx_flag = 0; +static volatile uint8_t g_app_uart_int_index = 0; +static uint8_t g_app_uart_int_rx_buff[CONFIG_UART_TRANSFER_SIZE] = { 0 }; +#endif +static uart_buffer_config_t g_app_uart_buffer_config = { + .rx_buffer = g_app_uart_rx_buff, + .rx_buffer_size = CONFIG_UART_TRANSFER_SIZE +}; + +#if defined(CONFIG_UART_SUPPORT_DMA) +uart_write_dma_config_t g_app_dma_cfg = { + .src_width = HAL_DMA_TRANSFER_WIDTH_8, + .dest_width = HAL_DMA_TRANSFER_WIDTH_8, + .burst_length = HAL_DMA_BURST_TRANSACTION_LENGTH_1, + .priority = HAL_DMA_CH_PRIORITY_0 +}; +#endif + +static void app_uart_init_pin(void) +{ +#if defined(CONFIG_PINCTRL_SUPPORT_IE) + uapi_pin_set_ie(CONFIG_UART_RXD_PIN, PIN_IE_1); +#endif /* CONFIG_PINCTRL_SUPPORT_IE */ + uapi_pin_set_mode(CONFIG_UART_TXD_PIN, CONFIG_UART_TXD_PIN_MODE); + uapi_pin_set_mode(CONFIG_UART_RXD_PIN, CONFIG_UART_RXD_PIN_MODE); +} + +static void app_uart_init_config(void) +{ + uart_attr_t attr = { + .baud_rate = UART_BAUDRATE, + .data_bits = UART_DATA_BIT_8, + .stop_bits = UART_STOP_BIT_1, + .parity = UART_PARITY_NONE + }; + + uart_pin_config_t pin_config = { + .tx_pin = CONFIG_UART_TXD_PIN, + .rx_pin = CONFIG_UART_RXD_PIN, + .cts_pin = PIN_NONE, + .rts_pin = PIN_NONE + }; + +#if defined(CONFIG_UART_SUPPORT_DMA) + uart_extra_attr_t extra_attr = { + .tx_dma_enable = true, + .tx_int_threshold = UART_FIFO_INT_TX_LEVEL_EQ_0_CHARACTER, + .rx_dma_enable = true, + .rx_int_threshold = UART_FIFO_INT_RX_LEVEL_1_CHARACTER + }; + uapi_dma_init(); + uapi_dma_open(); + uapi_uart_deinit(CONFIG_UART_BUS_ID); + uapi_uart_init(CONFIG_UART_BUS_ID, &pin_config, &attr, &extra_attr, &g_app_uart_buffer_config); +#else + uapi_uart_deinit(CONFIG_UART_BUS_ID); + uapi_uart_init(CONFIG_UART_BUS_ID, &pin_config, &attr, NULL, &g_app_uart_buffer_config); +#endif +} + +#if defined(CONFIG_UART_SUPPORT_INT_MODE) +static void app_uart_read_int_handler(const void *buffer, uint16_t length, bool error) +{ + unused(error); + if (buffer == NULL || length == 0) { + osal_printk("uart%d int mode transfer illegal data!\r\n", CONFIG_UART_BUS_ID); + return; + } + + uint8_t *buff = (uint8_t *)buffer; + if (memcpy_s(g_app_uart_rx_buff, length, buff, length) != EOK) { + osal_printk("uart%d int mode data copy fail!\r\n", CONFIG_UART_BUS_ID); + return; + } + if (memcpy_s(g_app_uart_int_rx_buff + g_app_uart_int_index, length, g_app_uart_rx_buff, length) != EOK) { + g_app_uart_int_index = 0; + osal_printk("uart%d int mode data2 copy fail!\r\n", CONFIG_UART_BUS_ID); + } + g_app_uart_int_index += length; + g_app_uart_int_rx_flag = 1; +} + +static void app_uart_write_int_handler(const void *buffer, uint32_t length, const void *params) +{ + unused(params); + uint8_t *buff = (void *)buffer; + for (uint8_t i = 0; i < length; i++) { + osal_printk("uart%d write data[%d] = %d\r\n", CONFIG_UART_BUS_ID, i, buff[i]); + } +} + +static void app_uart_register_rx_callback(void) +{ + osal_printk("uart%d int mode register receive callback start!\r\n", CONFIG_UART_BUS_ID); + if (uapi_uart_register_rx_callback(CONFIG_UART_BUS_ID, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE, + 1, app_uart_read_int_handler) == ERRCODE_SUCC) { + osal_printk("uart%d int mode register receive callback succ!\r\n", CONFIG_UART_BUS_ID); + } +} +#endif + +static void *uart_task(const char *arg) +{ + unused(arg); +#if defined(CONFIG_UART_SUPPORT_DMA) + int32_t ret = CONFIG_UART_TRANSFER_SIZE; +#if defined(CONFIG_UART_USING_V151) + ret = ERRCODE_SUCC; +#endif +#endif + /* UART pinmux. */ + app_uart_init_pin(); + + /* UART init config. */ + app_uart_init_config(); + +#if defined(CONFIG_UART_SUPPORT_INT_MODE) + app_uart_register_rx_callback(); +#endif + + while (1) { +#if defined(CONFIG_UART_SUPPORT_INT_MODE) + while (g_app_uart_int_rx_flag != 1) { osal_msleep(CONFIG_UART_INT_WAIT_MS); } + g_app_uart_int_rx_flag = 0; + osal_printk("uart%d int mode send back!\r\n", CONFIG_UART_BUS_ID); + if (uapi_uart_write_int(CONFIG_UART_BUS_ID, g_app_uart_int_rx_buff, CONFIG_UART_TRANSFER_SIZE, 0, + app_uart_write_int_handler) == ERRCODE_SUCC) { + osal_printk("uart%d int mode send back succ!\r\n", CONFIG_UART_BUS_ID); + } +#elif defined(CONFIG_UART_SUPPORT_DMA) + osal_printk("uart%d dma mode receive start!\r\n", CONFIG_UART_BUS_ID); + if (uapi_uart_read_by_dma(CONFIG_UART_BUS_ID, g_app_uart_rx_buff, CONFIG_UART_TRANSFER_SIZE, + &g_app_dma_cfg) == ret) { + osal_printk("uart%d dma mode receive succ!\r\n", CONFIG_UART_BUS_ID); + } + osal_printk("uart%d dma mode send back!\r\n", CONFIG_UART_BUS_ID); + if (uapi_uart_write_by_dma(CONFIG_UART_BUS_ID, g_app_uart_rx_buff, CONFIG_UART_TRANSFER_SIZE, + &g_app_dma_cfg) == ret) { + osal_printk("uart%d dma mode send back succ!\r\n", CONFIG_UART_BUS_ID); + } +#else + osal_printk("uart%d poll mode receive start!\r\n", CONFIG_UART_BUS_ID); + (void)uapi_watchdog_kick(); + if (uapi_uart_read(CONFIG_UART_BUS_ID, g_app_uart_rx_buff, CONFIG_UART_TRANSFER_SIZE, + 0) == CONFIG_UART_TRANSFER_SIZE) { + osal_printk("uart%d poll mode receive succ!\r\n", CONFIG_UART_BUS_ID); + } + osal_printk("uart%d poll mode send back!\r\n", CONFIG_UART_BUS_ID); + if (uapi_uart_write(CONFIG_UART_BUS_ID, g_app_uart_rx_buff, CONFIG_UART_TRANSFER_SIZE, + 0) == CONFIG_UART_TRANSFER_SIZE) { + osal_printk("uart%d poll mode send back succ!\r\n", CONFIG_UART_BUS_ID); + } +#endif + } + + return NULL; +} + +static void uart_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)uart_task, 0, "UartTask", UART_TASK_STACK_SIZE); + if (task_handle != NULL) { + osal_kthread_set_priority(task_handle, UART_TASK_PRIO); + } + osal_kthread_unlock(); +} + +/* Run the uart_entry. */ +app_run(uart_entry); \ No newline at end of file diff --git a/application/samples/peripheral/uflash/CMakeLists.txt b/application/samples/peripheral/uflash/CMakeLists.txt new file mode 100755 index 0000000..d073d85 --- /dev/null +++ b/application/samples/peripheral/uflash/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/hfuflash_demo.c" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/peripheral/uflash/hfuflash_demo.c b/application/samples/peripheral/uflash/hfuflash_demo.c new file mode 100755 index 0000000..c0f7064 --- /dev/null +++ b/application/samples/peripheral/uflash/hfuflash_demo.c @@ -0,0 +1,94 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. + * + * Description: WDT Sample Source. \n + * + * History: \n + * 2023-06-29, Create file. \n + */ +#include "hsf.h" +#define UFLASH_TASK_STACK_SIZE 0x1000 +USER_FUNC int test_uflash_one_page(uint32_t addr) +{ + static char test_data[4096]; + int i; + + hfuflash_erase_page(addr,1); + memset(test_data, 0, sizeof(test_data)); + hfuflash_read(addr,test_data,4096); + for(i=0;i<4096;i++) + { + if(test_data[i]!=0xFF) + return 1; + } + + memset(test_data,0x55,4096); + hfuflash_write(addr,test_data,4096); + memset(test_data, 0, sizeof(test_data)); + hfuflash_read(addr,test_data,4096); + for(i=0;i<4096;i++) + { + if(test_data[i]!=0x55) + return 2; + } + + memset(test_data,0xAA,4096); + hfuflash_erase_page(addr,1); + hfuflash_write(addr,test_data,4096); + memset(test_data, 0, sizeof(test_data)); + hfuflash_read(addr,test_data,4096); + for(i=0;i<4096;i++) + { + if(test_data[i]!=0xAA) + return 3; + } + return 0; +} + +USER_FUNC int test_uflash(void) +{ + uint32_t addr = 0; + for(addr=0; addrlower_boundary, res->upper_boundary, res->is_human_presence); +} + +// 维测信息依次为: +// 1.告知上层是否需要写入flash +// 2.LNA * 10 + VGA +// 3.原始回波峰值 +// 4.过去period帧的平均MO1底噪 +// 5.过去period帧的平均MO2底噪 +// 6.过去period帧的平均DP底噪 +// 7.过去period帧的平均帧间隔 +// 8.过去period帧中帧间隔超过Xms的帧数 +// 9.过去period帧中bitmap数量超过X门限的帧数 +// 10.过去period帧中bitmap比例超过X门限的帧数 +// 11.过去period帧中是在参与统计的帧数 +// 12.过去period帧中帧间隔最大值 +// 13.过去period帧中帧间隔最大值下标 +// 14.当前所使用的算法参数MO1门限 +// 15.当前所使用的算法参数MO2门限 +// 16.当前所使用的算法参数DP门限 +static void radar_print_dbg_info(int16_t *arr, uint8_t len) +{ + if (len > RADAR_DBG_INFO_LEN || len == 0) { + return; + } + + PRINT("dbg_info: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", + arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8], arr[9], arr[10], + arr[11], arr[12], arr[13], arr[14], arr[15]); +} + +static void radar_init_para(void) +{ + radar_dbg_para_t dbg_para; + dbg_para.times = RADAR_DEFAULT_TIMES; + dbg_para.loop = RADAR_DEFAULT_LOOP; + dbg_para.ant = RADAR_DEFAULT_ANT; + dbg_para.wave = RADAR_DEFAULT_WAVE; + dbg_para.dbg_type = RADAR_DEFAULT_DBG_TYPE; + dbg_para.period = RADAR_DEFAULT_PERIOD; + uapi_radar_set_debug_para(&dbg_para); + + radar_sel_para_t sel_para; + sel_para.height = RADAR_HEIGHT_2M; + sel_para.scenario = RADAR_SCENARIO_TYPE_HOME; + sel_para.material = RADAR_MATERIAL_SINGLE; + sel_para.fusion_track = true; + sel_para.fusion_ai = true; + uapi_radar_select_alg_para(&sel_para); + + // 算法门限, 前三个使用tools/bin/radar_tool/radar_para_gen_tool工具标定, 后面五个使用本sample给出的默认值即可 + radar_alg_para_t alg_para; + alg_para.d_th_1m = 32; + alg_para.d_th_2m = 25; + alg_para.p_th = 25; + alg_para.t_th_1m = 13; + alg_para.t_th_2m = 26; + alg_para.b_th_ratio = 20; + alg_para.b_th_cnt = 4; + alg_para.a_th = 70; + uapi_radar_set_alg_para(&alg_para, 0); + + int16_t dly_time = RADAR_QUIT_DELAY_TIME; + uapi_radar_set_delay_time(dly_time); +} + +int radar_demo_init(void *param) +{ + PRINT("[RADAR_SAMPLE] radar_demo_init softap!\r\n"); + + param = param; + radar_start_softap(); + uapi_radar_register_result_cb(radar_print_res); + uapi_radar_register_debug_info_cb(radar_print_dbg_info, RADAR_DBG_INFO_RPT_COEF); + radar_init_para(); + // 启动雷达 + (void)osDelay(WIFI_START_SOFTAP_DELAY); + uapi_radar_set_status(RADAR_STATUS_START); + + for (;;) { + (void)osDelay(RADAR_STATUS_QUERY_DELAY); + uint8_t sts; + uapi_radar_get_status(&sts); + uapi_radar_get_hardware_status(&sts); + uint16_t time; + uapi_radar_get_delay_time(&time); + uint16_t iso; + uapi_radar_get_isolation(&iso); + radar_result_t res = {0}; + uapi_radar_get_result(&res); + int16_t arr[RADAR_DBG_INFO_LEN] = {0}; + uapi_radar_get_debug_info(arr, RADAR_DBG_INFO_LEN); + radar_print_dbg_info(arr, RADAR_DBG_INFO_LEN); + } + + return 0; +} diff --git a/application/samples/radar/sta_sample/CMakeLists.txt b/application/samples/radar/sta_sample/CMakeLists.txt new file mode 100755 index 0000000..f49248d --- /dev/null +++ b/application/samples/radar/sta_sample/CMakeLists.txt @@ -0,0 +1,13 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES + "${SOURCES}" + "${CMAKE_CURRENT_SOURCE_DIR}/radar_sta_sample.c" + PARENT_SCOPE) + +set(PUBLIC_HEADER + "${PUBLIC_HEADER}" + "${CMAKE_CURRENT_SOURCE_DIR}/../../../include/middleware/services/radar/radar_service.h" + PARENT_SCOPE) diff --git a/application/samples/radar/sta_sample/radar_sta_sample.c b/application/samples/radar/sta_sample/radar_sta_sample.c new file mode 100755 index 0000000..dcc4fc8 --- /dev/null +++ b/application/samples/radar/sta_sample/radar_sta_sample.c @@ -0,0 +1,241 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Radar samples function \n + * + */ + +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "td_base.h" +#include "td_type.h" +#include "stdlib.h" +#include "uart.h" +#include "cmsis_os2.h" +#include "soc_osal.h" +#include "radar_service.h" +#include "gpio.h" +#include "pinctrl.h" + +#define WIFI_IFNAME_MAX_SIZE 16 +#define WIFI_MAX_SSID_LEN 33 +#define WIFI_SCAN_AP_LIMIT 64 +#define WIFI_MAC_LEN 6 +#define WIFI_INIT_WAIT_TIME 500 // 5s +#define WIFI_START_STA_DELAY 100 // 1s + +#define RADAR_STATUS_START 1 +#define RADAR_STATUS_QUERY_DELAY 1000 // 10s +#define RADAR_QUIT_DELAY_TIME 12 // 12s + +#define RADAR_DEFAULT_TIMES 0 +#define RADAR_DEFAULT_LOOP 8 +#define RADAR_DEFAULT_ANT 0 +#define RADAR_DEFAULT_PERIOD 5000 +#define RADAR_DEFAULT_DBG_TYPE 3 +#define RADAR_DEFAULT_WAVE 2 + +#define RADAR_API_NO_HUMAN 0 +#define RADAR_API_RANGE_CLOSE 50 +#define RADAR_API_RANGE_NEAR 100 +#define RADAR_API_RANGE_MEDIUM 200 +#define RADAR_API_RANGE_FAR 600 + +#define RADAR_DBG_INFO_RPT_COEF 100 +#define RADAR_DBG_INFO_LEN 16 + +// led档位控制参数 +typedef enum { + RADAR_INSIDE_1M, + RADAR_INSIDE_2M, + RADAR_INSIDE_6M, +} radar_led_gear_t; + +radar_led_gear_t g_radar_led_gear = RADAR_INSIDE_1M; + +/***************************************************************************** + STA 扫描-关联 sample用例 +*****************************************************************************/ +void radar_set_led_gear(radar_led_gear_t gear) +{ + PRINT("[RADAR_SAMPLE] SET LED GEAR:%u!\r\n", gear); + g_radar_led_gear = gear; +} + +static void radar_led_init(void) +{ + // 1. 初始化所有GPIO并设置GPIO的类型 + uapi_gpio_init(); + // 2. 设置GPIO为输出 + errcode_t ret = uapi_gpio_set_dir(GPIO_13, GPIO_DIRECTION_OUTPUT); + if (ret != ERRCODE_SUCC) { + PRINT("[RADAR_SAMPLE] led uapi_gpio_set_dir failed %u!\r\n", ret); + } + // 3. 设置GPIO PIN模式为0,普通模式 + ret = uapi_pin_set_mode(GPIO_13, PIN_MODE_0); + if (ret != ERRCODE_SUCC) { + PRINT("[RADAR_SAMPLE] led uapi_pin_set_mode failed %u!\r\n", ret); + } +} + +static void radar_set_led_on(void) +{ + errcode_t ret = uapi_gpio_set_val(GPIO_13, GPIO_LEVEL_HIGH); + if (ret!= ERRCODE_SUCC) { + PRINT("[RADAR_SAMPLE] led ctrl failed %u!\r\n", ret); + } +} + +static void radar_set_led_off(void) +{ + errcode_t ret = uapi_gpio_set_val(GPIO_13, GPIO_LEVEL_LOW); + if (ret!= ERRCODE_SUCC) { + PRINT("[RADAR_SAMPLE] led ctrl failed %u!\r\n", ret); + } +} + +static void radar_ctrl_led(radar_result_t *res) +{ + switch (g_radar_led_gear) { + case RADAR_INSIDE_1M: + if (res->lower_boundary == 0 && res->upper_boundary == RADAR_API_RANGE_NEAR) { + radar_set_led_on(); + } else { + radar_set_led_off(); + } + break; + case RADAR_INSIDE_2M: + if ((res->lower_boundary == RADAR_API_RANGE_NEAR && + res->upper_boundary == RADAR_API_RANGE_MEDIUM) || + (res->lower_boundary == 0 && res->upper_boundary == RADAR_API_RANGE_NEAR)) { + radar_set_led_on(); + } else { + radar_set_led_off(); + } + break; + default: // 默认6M档位 + if (res->is_human_presence == 1) { + radar_set_led_on(); + } else { + radar_set_led_off(); + } + } +} + +td_s32 radar_start_sta(td_void) +{ + (void)osDelay(WIFI_INIT_WAIT_TIME); /* 500: 延时0.5s, 等待wifi初始化完毕 */ + PRINT("STA try enable.\r\n"); + /* 创建STA接口 */ + if (wifi_sta_enable() != 0) { + PRINT("sta enbale fail !\r\n"); + return -1; + } + + /* 连接成功 */ + PRINT("STA connect success.\r\n"); + return 0; +} + +static void radar_print_res(radar_result_t *res) +{ + PRINT("[RADAR_SAMPLE] lb:%u, hb:%u, hm:%u\r\n", res->lower_boundary, res->upper_boundary, res->is_human_presence); + + radar_ctrl_led(res); +} + +// 维测信息依次为: +// 1.告知上层是否需要写入flash +// 2.LNA * 10 + VGA +// 3.原始回波峰值 +// 4.过去period帧的平均MO1底噪 +// 5.过去period帧的平均MO2底噪 +// 6.过去period帧的平均DP底噪 +// 7.过去period帧的平均帧间隔 +// 8.过去period帧中帧间隔超过Xms的帧数 +// 9.过去period帧中bitmap数量超过X门限的帧数 +// 10.过去period帧中bitmap比例超过X门限的帧数 +// 11.过去period帧中是在参与统计的帧数 +// 12.过去period帧中帧间隔最大值 +// 13.过去period帧中帧间隔最大值下标 +// 14.当前所使用的算法参数MO1门限 +// 15.当前所使用的算法参数MO2门限 +// 16.当前所使用的算法参数DP门限 +static void radar_print_dbg_info(int16_t *arr, uint8_t len) +{ + if (len > RADAR_DBG_INFO_LEN || len == 0) { + return; + } + + PRINT("dbg_info: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", + arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8], arr[9], arr[10], + arr[11], arr[12], arr[13], arr[14], arr[15]); +} + +static void radar_init_para(void) +{ + radar_dbg_para_t dbg_para; + dbg_para.times = RADAR_DEFAULT_TIMES; + dbg_para.loop = RADAR_DEFAULT_LOOP; + dbg_para.ant = RADAR_DEFAULT_ANT; + dbg_para.wave = RADAR_DEFAULT_WAVE; + dbg_para.dbg_type = RADAR_DEFAULT_DBG_TYPE; + dbg_para.period = RADAR_DEFAULT_PERIOD; + uapi_radar_set_debug_para(&dbg_para); + + radar_sel_para_t sel_para; + sel_para.height = RADAR_HEIGHT_2M; + sel_para.scenario = RADAR_SCENARIO_TYPE_HOME; + sel_para.material = RADAR_MATERIAL_SINGLE; + sel_para.fusion_track = true; + sel_para.fusion_ai = true; + uapi_radar_select_alg_para(&sel_para); + + // 算法门限, 前三个使用tools/bin/radar_tool/radar_para_gen_tool工具标定, 后面五个使用本sample给出的默认值即可 + radar_alg_para_t alg_para; + alg_para.d_th_1m = 32; + alg_para.d_th_2m = 25; + alg_para.p_th = 25; + alg_para.t_th_1m = 13; + alg_para.t_th_2m = 26; + alg_para.b_th_ratio = 20; + alg_para.b_th_cnt = 4; + alg_para.a_th = 70; + uapi_radar_set_alg_para(&alg_para, 0); + + int16_t dly_time = RADAR_QUIT_DELAY_TIME; + uapi_radar_set_delay_time(dly_time); +} + +int radar_demo_init(void *param) +{ + PRINT("[RADAR_SAMPLE] radar_demo_init sta!\r\n"); + param = param; + radar_led_init(); + radar_start_sta(); + uapi_radar_register_result_cb(radar_print_res); + uapi_radar_register_debug_info_cb(radar_print_dbg_info, RADAR_DBG_INFO_RPT_COEF); + radar_init_para(); + // 启动雷达 + (void)osDelay(WIFI_START_STA_DELAY); + uapi_radar_set_status(RADAR_STATUS_START); + + for (;;) { + (void)osDelay(RADAR_STATUS_QUERY_DELAY); + uint8_t sts; + uapi_radar_get_status(&sts); + uapi_radar_get_hardware_status(&sts); + uint16_t time; + uapi_radar_get_delay_time(&time); + uint16_t iso; + uapi_radar_get_isolation(&iso); + radar_result_t res = {0}; + uapi_radar_get_result(&res); + int16_t arr[RADAR_DBG_INFO_LEN] = {0}; + uapi_radar_get_debug_info(arr, RADAR_DBG_INFO_LEN); + radar_print_dbg_info(arr, RADAR_DBG_INFO_LEN); + } + + return 0; +} diff --git a/application/samples/wifi/CMakeLists.txt b/application/samples/wifi/CMakeLists.txt new file mode 100755 index 0000000..2fbcf95 --- /dev/null +++ b/application/samples/wifi/CMakeLists.txt @@ -0,0 +1,37 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +if(DEFINED CONFIG_SAMPLE_SUPPORT_STA_SAMPLE) + add_subdirectory_if_exist(sta_sample) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_ALILINK_SAMPLE) + add_subdirectory_if_exist(alilink_sample) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_SOFTAP_SAMPLE) + add_subdirectory_if_exist(softap_sample) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_WIFI_CFG_SAMPLE) + add_subdirectory_if_exist(ble_wifi_cfg_sample) +endif() + +if(DEFINED CONFIG_SAMPLE_SUPPORT_SYSCHANNEL_DEV) + add_subdirectory_if_exist(syschannel_dev) +endif() + +if(DEFINED CONFIG_SUPPORT_HILINK) + add_subdirectory_if_exist(ohos_connect) +endif() + +if (DEFINES MATCHES "CONFIG_SUPPORT_HILINK_INDIE_UPGRADE") + add_subdirectory_if_exist(hilink_indie_upgrade) +endif() + +if(DEFINED CONFIG_SUPPORT_UAPI) + add_subdirectory_if_exist(uhapi) +endif() + +set(SOURCES "${SOURCES}" PARENT_SCOPE) \ No newline at end of file diff --git a/application/samples/wifi/Kconfig b/application/samples/wifi/Kconfig new file mode 100755 index 0000000..1fd2dbe --- /dev/null +++ b/application/samples/wifi/Kconfig @@ -0,0 +1,32 @@ +#=============================================================================== +# @brief Kconfig file. +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +choice + prompt "Sample" + +config SAMPLE_SUPPORT_STA_SAMPLE + bool "Support WIFI STA Sample" + +config SAMPLE_SUPPORT_ALILINK_SAMPLE + bool "Support ALILINK Sample" + +config SAMPLE_SUPPORT_SOFTAP_SAMPLE + bool "Support WIFI SoftAP Sample." + +config SAMPLE_SUPPORT_BLE_WIFI_CFG_SAMPLE + bool "Support BLE WIFI CFG Sample" + +config SUPPORT_HILINK + bool "Support HILINK" + +config SUPPORT_UAPI + bool "Support UAPI." +endchoice + +config SAMPLE_SUPPORT_SYSCHANNEL_DEV + bool + prompt "Support Syschannel dev Sample." + default n + help + This option means support Syschannel Dev Sample. \ No newline at end of file diff --git a/application/samples/wifi/alilink_sample/CMakeLists.txt b/application/samples/wifi/alilink_sample/CMakeLists.txt new file mode 100755 index 0000000..e30498d --- /dev/null +++ b/application/samples/wifi/alilink_sample/CMakeLists.txt @@ -0,0 +1,70 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "alilink") + +if (DEFINED CONFIG_SAMPLE_SUPPORT_ALILINK_SAMPLE) +set(CMAKE_ALILINK_SOURCE_DIR + ${CMAKE_CURRENT_SOURCE_DIR}) + +set(SOURCES + ${CMAKE_ALILINK_SOURCE_DIR}/alilink_sample.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/demos/mqtt_basic_demo.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/aiot_mqtt_api.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/sysdep/core_adapter.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/sysdep/core_sysdep.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/aiot_state_api.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/utils/core_sha256.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/utils/core_auth.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/utils/core_global.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/utils/core_log.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/utils/core_string.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/utils/core_diag.c + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/portfiles/aiot_port/posix_port.c +) + +set(PUBLIC_HEADER + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/ + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/utils/ + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/sysdep/ +) + +set(PRIVATE_HEADER + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/ + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/utils/ + ${CMAKE_ALILINK_SOURCE_DIR}/LinkSDK/core/sysdep/ +) +endif() +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -Wno-error=logical-op + -Wno-error=sign-compare + -Wno-error=jump-misses-init + -Wno-sign-compare + -Wno-jump-misses-init + -Wno-error=unused-parameter + -Wno-unused-parameter + -Wno-unused-but-set-variable + -Wno-error=unused-variable +) + +set(PRIVATE_DEFINES +) + +set(PUBLIC_DEFINES +) +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + false +) + +set(LIB_OUT_PATH ${BIN_DIR}/${CHIP}/libs/wifi/${TARGET_COMMAND}) + +build_component() \ No newline at end of file diff --git a/application/samples/wifi/alilink_sample/alilink.patch b/application/samples/wifi/alilink_sample/alilink.patch new file mode 100755 index 0000000..c53e3c5 --- /dev/null +++ b/application/samples/wifi/alilink_sample/alilink.patch @@ -0,0 +1,665 @@ +diff -Naru LinkSDK_origin/core/sysdep/core_adapter.c LinkSDK/core/sysdep/core_adapter.c +--- LinkSDK_origin/core/sysdep/core_adapter.c 2024-07-22 13:24:22.000000000 +0800 ++++ LinkSDK/core/sysdep/core_adapter.c 2024-09-30 11:32:33.706049558 +0800 +@@ -15,7 +15,7 @@ + * 虽然物联网平台接收TCP方式的连接, 但我们不推荐这样做, TLS是更安全的通信方式 + * + */ +-#define CORE_ADAPTER_MBEDTLS_ENABLED ++//#define CORE_ADAPTER_MBEDTLS_ENABLED + + /* + * CORE_ADAPTER_DTLS_ENABLED 不是一个用户需要关心的编译开关,用于关闭DTLS相关功能 +diff -Naru LinkSDK_origin/demos/mqtt_basic_demo.c LinkSDK/demos/mqtt_basic_demo.c +--- LinkSDK_origin/demos/mqtt_basic_demo.c 2024-07-22 13:24:22.000000000 +0800 ++++ LinkSDK/demos/mqtt_basic_demo.c 2024-09-30 13:56:51.997601919 +0800 +@@ -9,18 +9,27 @@ + */ + #include + #include +-#include +-#include + ++#include "osal_types.h" ++#include "osal_task.h" ++#include "osal_debug.h" ++#include "debug_print.h" + #include "aiot_state_api.h" + #include "aiot_sysdep_api.h" + #include "aiot_mqtt_api.h" ++#include "securec.h" + +-/* TODO: 替换为自己设备的三元组 */ +-const char *product_key = "${YourProductKey}"; +-const char *device_name = "${YourDeviceName}"; +-const char *device_secret = "${YourDeviceSecret}"; +- ++#define ALILINK_KEEPALIVE_TASK_SIZE 0x1000 ++#define ALILINK_KEEPALIVE_TASK_PRIO 26 ++#define ALILINK_RECV_TASK_SIZE 0x1000 ++#define ALILINK_RECV_TASK_PRIO 27 ++#define ALILINK_TASK_SIZE 0x1000 ++#define ALILINK_TASK_PRIO 25 ++ ++/* 请替换为自己设备的三元组 */ ++static char *g_product_key = "k09491MwNWT"; ++static char *g_device_name = "hi_damon"; ++static char *g_device_secret = "9e31e56acf977bdf8e878d2f6a971262"; + /* + TODO: 替换为自己实例的接入点 + +@@ -31,21 +40,12 @@ + 对于2021年07月30日之前(不含当日)开通的物联网平台服务下公共实例,请使用旧版接入点。 + 详情请见: https://help.aliyun.com/document_detail/147356.html + */ +-const char *mqtt_host = "${YourInstanceId}.mqtt.iothub.aliyuncs.com"; +-/* +- 原端口:1883/443,对应的证书(GlobalSign R1),于2028年1月过期,届时可能会导致设备不能建连。 +- (推荐)新端口:8883,将搭载新证书,由阿里云物联网平台自签证书,于2053年7月过期。 +-*/ +-const uint16_t port = 8883; ++static char *g_mqtt_host = "iot-06z00fusvxnphyj.mqtt.iothub.aliyuncs.com"; + + /* 位于portfiles/aiot_port文件夹下的系统适配函数集合 */ + extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile; + + /* 位于external/ali_ca_cert.c中的服务器证书 */ +-extern const char *ali_ca_cert; +- +-static pthread_t g_mqtt_process_thread; +-static pthread_t g_mqtt_recv_thread; + static uint8_t g_mqtt_process_thread_running = 0; + static uint8_t g_mqtt_recv_thread_running = 0; + +@@ -60,7 +60,7 @@ + /* 日志回调函数, SDK的日志会从这里输出 */ + int32_t demo_state_logcb(int32_t code, char *message) + { +- printf("%s", message); ++ osal_printk("%s\n", message); + return 0; + } + +@@ -70,14 +70,14 @@ + switch (event->type) { + /* SDK因为用户调用了aiot_mqtt_connect()接口, 与mqtt服务器建立连接已成功 */ + case AIOT_MQTTEVT_CONNECT: { +- printf("AIOT_MQTTEVT_CONNECT\n"); ++ osal_printk("AIOT_MQTTEVT_CONNECT\n"); + /* TODO: 处理SDK建连成功, 不可以在这里调用耗时较长的阻塞函数 */ + } + break; + + /* SDK因为网络状况被动断连后, 自动发起重连已成功 */ + case AIOT_MQTTEVT_RECONNECT: { +- printf("AIOT_MQTTEVT_RECONNECT\n"); ++ osal_printk("AIOT_MQTTEVT_RECONNECT\n"); + /* TODO: 处理SDK重连成功, 不可以在这里调用耗时较长的阻塞函数 */ + } + break; +@@ -86,7 +86,7 @@ + case AIOT_MQTTEVT_DISCONNECT: { + char *cause = (event->data.disconnect == AIOT_MQTTDISCONNEVT_NETWORK_DISCONNECT) ? ("network disconnect") : + ("heartbeat disconnect"); +- printf("AIOT_MQTTEVT_DISCONNECT: %s\n", cause); ++ osal_printk("AIOT_MQTTEVT_DISCONNECT: %s\n", cause); + /* TODO: 处理SDK被动断连, 不可以在这里调用耗时较长的阻塞函数 */ + } + break; +@@ -102,27 +102,27 @@ + { + switch (packet->type) { + case AIOT_MQTTRECV_HEARTBEAT_RESPONSE: { +- printf("heartbeat response\n"); ++ osal_printk("heartbeat response\n"); + /* TODO: 处理服务器对心跳的回应, 一般不处理 */ + } + break; + + case AIOT_MQTTRECV_SUB_ACK: { +- printf("suback, res: -0x%04X, packet id: %d, max qos: %d\n", ++ osal_printk("suback, res: -0x%04X, packet id: %d, max qos: %d\n", + -packet->data.sub_ack.res, packet->data.sub_ack.packet_id, packet->data.sub_ack.max_qos); + /* TODO: 处理服务器对订阅请求的回应, 一般不处理 */ + } + break; + + case AIOT_MQTTRECV_PUB: { +- printf("pub, qos: %d, topic: %.*s\n", packet->data.pub.qos, packet->data.pub.topic_len, packet->data.pub.topic); +- printf("pub, payload: %.*s\n", packet->data.pub.payload_len, packet->data.pub.payload); ++ osal_printk("pub, qos: %d, topic: %.*s\n", packet->data.pub.qos, packet->data.pub.topic_len, packet->data.pub.topic); ++ osal_printk("pub, payload: %.*s\n", packet->data.pub.payload_len, packet->data.pub.payload); + /* TODO: 处理服务器下发的业务报文 */ + } + break; + + case AIOT_MQTTRECV_PUB_ACK: { +- printf("puback, packet id: %d\n", packet->data.pub_ack.packet_id); ++ osal_printk("puback, packet id: %d\n", packet->data.pub_ack.packet_id); + /* TODO: 处理服务器对QoS1上报消息的回应, 一般不处理 */ + } + break; +@@ -134,7 +134,7 @@ + } + + /* 执行aiot_mqtt_process的线程, 包含心跳发送和QoS1消息重发 */ +-void *demo_mqtt_process_thread(void *args) ++int demo_mqtt_process_thread(void *args) + { + int32_t res = STATE_SUCCESS; + +@@ -143,13 +143,13 @@ + if (res == STATE_USER_INPUT_EXEC_DISABLED) { + break; + } +- sleep(1); ++ osal_msleep(1000); /* 1000:睡眠1秒 */ + } +- return NULL; ++ return 0; + } + + /* 执行aiot_mqtt_recv的线程, 包含网络自动重连和从服务器收取MQTT消息 */ +-void *demo_mqtt_recv_thread(void *args) ++int demo_mqtt_recv_thread(void *args) + { + int32_t res = STATE_SUCCESS; + +@@ -159,16 +159,17 @@ + if (res == STATE_USER_INPUT_EXEC_DISABLED) { + break; + } +- sleep(1); ++ osal_msleep(1000); /* 1000:睡眠1秒 */ + } + } +- return NULL; ++ return 0; + } + +-int main(int argc, char *argv[]) ++int alilink_thread(void *data) + { + int32_t res = STATE_SUCCESS; + void *mqtt_handle = NULL; ++ uint16_t port = 443; /* 无论设备是否使用TLS连接阿里云平台, 目的端口都是443 */ + aiot_sysdep_network_cred_t cred; /* 安全凭据结构体, 如果要用TLS, 这个结构体中配置CA证书等参数 */ + + /* 配置SDK的底层依赖 */ +@@ -176,39 +177,31 @@ + /* 配置SDK的日志输出 */ + aiot_state_set_logcb(demo_state_logcb); + +- /* 创建SDK的安全凭据, 用于建立TLS连接 */ +- memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t)); +- cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA; /* 使用RSA证书校验MQTT服务端 */ +- cred.max_tls_fragment = 16384; /* 最大的分片长度为16K, 其它可选值还有4K, 2K, 1K, 0.5K */ +- cred.sni_enabled = 1; /* TLS建连时, 支持Server Name Indicator */ +- cred.x509_server_cert = ali_ca_cert; /* 用来验证MQTT服务端的RSA根证书 */ +- cred.x509_server_cert_len = strlen(ali_ca_cert); /* 用来验证MQTT服务端的RSA根证书长度 */ +- + /* 创建1个MQTT客户端实例并内部初始化默认参数 */ + mqtt_handle = aiot_mqtt_init(); + if (mqtt_handle == NULL) { +- printf("aiot_mqtt_init failed\n"); ++ osal_printk("aiot_mqtt_init failed\n"); + return -1; + } + + /* TODO: 如果以下代码不被注释, 则例程会用TCP而不是TLS连接云平台 */ +- /* ++ + { + memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t)); + cred.option = AIOT_SYSDEP_NETWORK_CRED_NONE; + } +- */ ++ + + /* 配置MQTT服务器地址 */ +- aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)mqtt_host); ++ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_HOST, (void *)g_mqtt_host); + /* 配置MQTT服务器端口 */ + aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PORT, (void *)&port); + /* 配置设备productKey */ +- aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)product_key); ++ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_PRODUCT_KEY, (void *)g_product_key); + /* 配置设备deviceName */ +- aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)device_name); ++ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_NAME, (void *)g_device_name); + /* 配置设备deviceSecret */ +- aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)device_secret); ++ aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_DEVICE_SECRET, (void *)g_device_secret); + /* 配置网络连接的安全凭据, 上面已经创建好了 */ + aiot_mqtt_setopt(mqtt_handle, AIOT_MQTTOPT_NETWORK_CRED, (void *)&cred); + /* 配置MQTT默认消息接收回调函数 */ +@@ -221,76 +214,95 @@ + if (res < STATE_SUCCESS) { + /* 尝试建立连接失败, 销毁MQTT实例, 回收资源 */ + aiot_mqtt_deinit(&mqtt_handle); +- printf("aiot_mqtt_connect failed: -0x%04X\n\r\n", -res); +- printf("please check variables like mqtt_host, produt_key, device_name, device_secret in demo\r\n"); ++ osal_printk("aiot_mqtt_connect failed: -0x%04X\n\n", -res); ++ osal_printk("please check variables like g_mqtt_host, produt_key, g_device_name, g_device_secret in demo\r\n"); + return -1; + } + + /* MQTT 订阅topic功能示例, 请根据自己的业务需求进行使用 */ +- /* { +- char *sub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/+/post_reply"; +- +- res = aiot_mqtt_sub(mqtt_handle, sub_topic, NULL, 1, NULL); +- if (res < 0) { +- printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res); +- return -1; +- } +- } */ ++ char *sub_topic = "/sys/k09491MwNWT/hi_damon/thing/deviceinfo/update_reply"; ++ res = aiot_mqtt_sub(mqtt_handle, sub_topic, NULL, 1, NULL); ++ if (res < STATE_SUCCESS) { ++ aiot_mqtt_deinit(&mqtt_handle); ++ osal_printk("aiot_mqtt_sub failed, res: -0x%04X\n", -res); ++ return -1; ++ } + + /* MQTT 发布消息功能示例, 请根据自己的业务需求进行使用 */ +- /* { +- char *pub_topic = "/sys/${YourProductKey}/${YourDeviceName}/thing/event/property/post"; +- char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LightSwitch\":0}}"; +- +- res = aiot_mqtt_pub(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0); +- if (res < 0) { +- printf("aiot_mqtt_sub failed, res: -0x%04X\n", -res); +- return -1; +- } +- } */ ++ char *pub_topic = "/sys/k09491MwNWT/hi_damon/thing/event/property/post"; ++ char *pub_payload = "{\"id\":\"1\",\"version\":\"1.0\",\"params\":{\"LLLLLightSwitch\":0}}"; ++ res = aiot_mqtt_pub(mqtt_handle, pub_topic, (uint8_t *)pub_payload, (uint32_t)strlen(pub_payload), 0); ++ if (res < STATE_SUCCESS) { ++ aiot_mqtt_deinit(&mqtt_handle); ++ osal_printk("aiot_mqtt_pub failed, res: -0x%04X\n", -res); ++ return -1; ++ } + + /* 创建一个单独的线程, 专用于执行aiot_mqtt_process, 它会自动发送心跳保活, 以及重发QoS1的未应答报文 */ + g_mqtt_process_thread_running = 1; +- res = pthread_create(&g_mqtt_process_thread, NULL, demo_mqtt_process_thread, mqtt_handle); +- if (res < 0) { +- printf("pthread_create demo_mqtt_process_thread failed: %d\n", res); +- return -1; ++ osal_task *alink_keepalive_task = OSAL_NULL; ++ alink_keepalive_task = osal_kthread_create(demo_mqtt_process_thread, (void *)mqtt_handle, "alink_keepalive", ++ ALILINK_KEEPALIVE_TASK_SIZE); ++ if (alink_keepalive_task == OSAL_NULL) { ++ aiot_mqtt_deinit(&mqtt_handle); ++ osal_printk("Create alink keepalive kthread failed\n"); ++ return OSAL_NOK; + } ++ osal_kthread_set_priority(alink_keepalive_task, ALILINK_KEEPALIVE_TASK_PRIO); ++ osal_printk("Create alink keepalive kthread SUCCESS!\n"); + + /* 创建一个单独的线程用于执行aiot_mqtt_recv, 它会循环收取服务器下发的MQTT消息, 并在断线时自动重连 */ + g_mqtt_recv_thread_running = 1; +- res = pthread_create(&g_mqtt_recv_thread, NULL, demo_mqtt_recv_thread, mqtt_handle); +- if (res < 0) { +- printf("pthread_create demo_mqtt_recv_thread failed: %d\n", res); +- return -1; ++ osal_task *alink_recv_task = OSAL_NULL; ++ alink_recv_task = osal_kthread_create(demo_mqtt_recv_thread, (void *)mqtt_handle, "alink_recv", ++ ALILINK_RECV_TASK_SIZE); ++ if (alink_recv_task == OSAL_NULL) { ++ aiot_mqtt_deinit(&mqtt_handle); ++ osal_kthread_destroy(alink_keepalive_task, OSAL_TRUE); ++ osal_printk("Create alink recv kthread failed\n"); ++ return OSAL_NOK; + } ++ osal_kthread_set_priority(alink_recv_task, ALILINK_RECV_TASK_PRIO); ++ osal_printk("Create alink recv kthread SUCCESS!\n"); + + /* 主循环进入休眠 */ + while (1) { +- sleep(1); ++ osal_msleep(1000); /* 睡眠1000毫秒 */ + } + + /* 断开MQTT连接, 一般不会运行到这里 */ + g_mqtt_process_thread_running = 0; + g_mqtt_recv_thread_running = 0; +- sleep(1); +- pthread_join(g_mqtt_process_thread, NULL); +- pthread_join(g_mqtt_recv_thread, NULL); ++ osal_msleep(1000); /* 睡眠1000毫秒 */ + ++ osal_kthread_destroy(alink_keepalive_task, OSAL_TRUE); ++ osal_kthread_destroy(alink_recv_task, OSAL_TRUE); + res = aiot_mqtt_disconnect(mqtt_handle); + if (res < STATE_SUCCESS) { + aiot_mqtt_deinit(&mqtt_handle); +- printf("aiot_mqtt_disconnect failed: -0x%04X\n", -res); ++ osal_printk("aiot_mqtt_disconnect failed: -0x%04X\n", -res); + return -1; + } + + /* 销毁MQTT实例, 一般不会运行到这里 */ + res = aiot_mqtt_deinit(&mqtt_handle); + if (res < STATE_SUCCESS) { +- printf("aiot_mqtt_deinit failed: -0x%04X\n", -res); ++ osal_printk("aiot_mqtt_deinit failed: -0x%04X\n", -res); + return -1; + } + + return 0; + } + ++int alilink_task_start(void) ++{ ++ osal_task *alilink_task = OSAL_NULL; ++ alilink_task = osal_kthread_create(alilink_thread, OSAL_NULL, "alilink", ALILINK_TASK_SIZE); ++ if (alilink_task == OSAL_NULL) { ++ osal_printk("Create alilink kthread failed\n"); ++ return -1; ++ } ++ ++ osal_kthread_set_priority(alilink_task, ALILINK_TASK_PRIO); ++ return 0; ++} +diff -Naru LinkSDK_origin/portfiles/aiot_port/posix_port.c LinkSDK/portfiles/aiot_port/posix_port.c +--- LinkSDK_origin/portfiles/aiot_port/posix_port.c 2024-07-22 13:24:22.000000000 +0800 ++++ LinkSDK/portfiles/aiot_port/posix_port.c 2024-09-30 11:32:33.706049558 +0800 +@@ -1,4 +1,4 @@ +-/* ++/* + * 这个移植示例适用于`Linux`这类支持pthread的POSIX设备,它实现了移植SDK所需要的接口。 + * 移植接口大体可以分为两类:网络接口(TCP)、系统接口(OS) + * +@@ -27,6 +27,13 @@ + #include "aiot_state_api.h" + #include "aiot_sysdep_api.h" + ++#include "osal_addr.h" ++#include "osal_task.h" ++#include "lwip/sockets.h" ++#include "lwip/netdb.h" ++#include "soc_osal.h" ++#include "osal_debug.h" ++#include "trng.h" + + /* socket建联时间默认最大值 */ + #define CORE_SYSDEP_DEFAULT_CONNECT_TIMEOUT_MS (10 * 1000) +@@ -195,7 +202,7 @@ + struct addrinfo hints; + struct addrinfo *addrInfoList = NULL, *pos = NULL; + struct sockaddr_in loc_addr; +- socklen_t len = sizeof(sizeof(loc_addr)); ++ socklen_t len = sizeof(loc_addr); + fd_set write_sets; + struct timeval timeselect; + +@@ -206,26 +213,20 @@ + hints.ai_flags = 0; + _port_uint2str(port, service); + +- signal(SIGPIPE, SIG_IGN); +- +- res = getaddrinfo(host, service, &hints, &addrInfoList); ++ res = lwip_getaddrinfo(host, service, &hints, &addrInfoList); + if (res == 0) { + for (pos = addrInfoList; pos != NULL; pos = pos->ai_next) { +- fd = socket(pos->ai_family, pos->ai_socktype, pos->ai_protocol); ++ fd = lwip_socket(pos->ai_family, pos->ai_socktype, pos->ai_protocol); + if (fd < 0) { +- _core_printf("create socket error\n"); ++ _core_printf("create socket error\n"); + res = STATE_PORT_NETWORK_SOCKET_CREATE_FAILED; + continue; + } + +- res = fcntl(fd, F_GETFL); +- if (res != -1) { +- res = fcntl(fd, F_SETFL, sock_option | O_NONBLOCK); +- } +- ++ res = lwip_fcntl(fd, F_SETFL, sock_option | O_NONBLOCK); + if (res == -1) { + /* block connect */ +- if (connect(fd, pos->ai_addr, pos->ai_addrlen) == 0) { ++ if (lwip_connect(fd, pos->ai_addr, pos->ai_addrlen) == 0) { + *fd_out = fd; + res = STATE_SUCCESS; + break; +@@ -240,21 +241,21 @@ + timeselect.tv_sec = timeout_ms / 1000; + timeselect.tv_usec = timeout_ms % 1000 * 1000; + +- if (connect(fd, pos->ai_addr, pos->ai_addrlen) == 0) { ++ if (lwip_connect(fd, pos->ai_addr, pos->ai_addrlen) == 0) { + *fd_out = fd; + res = STATE_SUCCESS; + break; + } else if (errno != EINPROGRESS) { + res = STATE_PORT_NETWORK_CONNECT_FAILED; + } else { +- res = select(fd + 1, NULL, &write_sets, NULL, ×elect); ++ res = lwip_select(fd + 1, NULL, &write_sets, NULL, ×elect); + if (res == 0) { + res = STATE_MQTT_LOG_CONNECT_TIMEOUT; + } else if (res < 0) { + res = STATE_PORT_NETWORK_CONNECT_FAILED; + } else { + if (FD_ISSET(fd, &write_sets)) { +- res = connect(fd, pos->ai_addr, pos->ai_addrlen); ++ res = lwip_connect(fd, pos->ai_addr, pos->ai_addrlen); + if ((res != 0 && errno == EISCONN) || res == 0) { + *fd_out = fd; + res = STATE_SUCCESS; +@@ -267,7 +268,7 @@ + } + } + +- close(fd); ++ lwip_close(fd); + _core_printf("connect error, errno: %d\n", errno); + } + } else { +@@ -289,7 +290,7 @@ + } + + if(addrInfoList) { +- freeaddrinfo(addrInfoList); ++ lwip_freeaddrinfo(addrInfoList); + } + + return res; +@@ -317,15 +318,15 @@ + struct sockaddr_in servaddr; + int opt_val = 1; + +- sockfd = socket(AF_INET, SOCK_DGRAM, 0); ++ sockfd = lwip_socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) { + _core_printf("create socket error, errno: %d, %s\n", errno, strerror(errno)); + return STATE_PORT_NETWORK_SOCKET_CREATE_FAILED; + } + +- if (0 != setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val))) { ++ if (0 != lwip_setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val))) { + _core_printf("setsockopt(SO_REUSEADDR) falied, errno: %d, %s\n", errno, strerror(errno)); +- close(sockfd); ++ lwip_close(sockfd); + return STATE_PORT_NETWORK_SOCKET_CONFIG_FAILED; + } + +@@ -334,9 +335,9 @@ + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(network_handle->port); + +- if (-1 == bind(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in))) { ++ if (-1 == lwip_bind(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in))) { + _core_printf("bind(%d) falied, errno: %d, %s\n", (int)sockfd, errno, strerror(errno)); +- close(sockfd); ++ lwip_close(sockfd); + return STATE_PORT_NETWORK_SOCKET_BIND_FAILED; + } + +@@ -403,6 +404,7 @@ + } + + timeselect_ms = timeout_ms - (timenow_ms - timestart_ms); ++ timeselect_ms = 20000ULL; /* 200000:lwip_select最多等待20秒 */ + timeselect.tv_sec = timeselect_ms / 1000; + timeselect.tv_usec = timeselect_ms % 1000 * 1000; + +@@ -411,16 +413,17 @@ + /* _core_printf("_core_sysdep_network_recv, nwk select timeout\n"); */ + continue; + } else if (res < 0) { +- _core_printf("_core_sysdep_network_recv, errno: %d, %s\n", errno, strerror(errno)); ++ _core_printf("_core_sysdep_network_recv, fd %d\n", network_handle->fd); + return STATE_PORT_NETWORK_SELECT_FAILED; + } else { + if (FD_ISSET(network_handle->fd, &recv_sets)) { +- recv_res = recv(network_handle->fd, buffer + recv_bytes, len - recv_bytes, 0); ++ _core_printf("_core_sysdep_network_recv, network_handle->fd %d\n", network_handle->fd); ++ recv_res = lwip_recv(network_handle->fd, buffer + recv_bytes, len - recv_bytes, 0); + if (recv_res == 0) { + _core_printf("_core_sysdep_network_recv, nwk connection closed\n"); + return STATE_PORT_NETWORK_RECV_CONNECTION_CLOSED; + } else if (recv_res < 0) { +- _core_printf("_core_sysdep_network_recv, errno: %d, %s\n", errno, strerror(errno)); ++ _core_printf("_core_sysdep_network_recv\n"); + if (errno == EINTR) { + continue; + } +@@ -453,7 +456,7 @@ + FD_ZERO(&read_fds); + FD_SET(network_handle->fd, &read_fds); + +- res = select(network_handle->fd + 1, &read_fds, NULL, NULL, &timeout); ++ res = lwip_select(network_handle->fd + 1, &read_fds, NULL, NULL, &timeout); + if (res == 0) { + _core_printf("select timeout\n"); + return 0; +@@ -536,7 +539,7 @@ + timeselect.tv_sec = timeselect_ms / 1000; + timeselect.tv_usec = timeselect_ms % 1000 * 1000; + +- res = select(network_handle->fd + 1, NULL, &send_sets, NULL, ×elect); ++ res = lwip_select(network_handle->fd + 1, NULL, &send_sets, NULL, ×elect); + if (res == 0) { + _core_printf("_core_sysdep_network_send, nwk select timeout\n"); + continue; +@@ -545,7 +548,7 @@ + return STATE_PORT_NETWORK_SELECT_FAILED; + } else { + if (FD_ISSET(network_handle->fd, &send_sets)) { +- send_res = send(network_handle->fd, buffer + send_bytes, len - send_bytes, 0); ++ send_res = lwip_send(network_handle->fd, buffer + send_bytes, len - send_bytes, 0); + if (send_res == 0) { + _core_printf("_core_sysdep_network_send, nwk connection closed\n"); + return STATE_PORT_NETWORK_SEND_CONNECTION_CLOSED; +@@ -643,8 +646,9 @@ + { + /* 仅仅对正常的fd 进行close操作 */ + if (network_handle->fd >= 0) { +- shutdown(network_handle->fd, 2); +- close(network_handle->fd); ++ osal_printk("_core_sysdep_network_tcp_disconnect! fd %d\r\n", network_handle->fd); ++ lwip_shutdown(network_handle->fd, 2); /* 2:同时关闭发送和接收 */ ++ lwip_close(network_handle->fd); + } + } + +@@ -665,11 +669,11 @@ + } + + if (network_handle->host != NULL) { +- free(network_handle->host); ++ osal_kfree(network_handle->host); + network_handle->host = NULL; + } + +- free(network_handle); ++ osal_kfree(network_handle); + *handle = NULL; + + return 0; +@@ -677,38 +681,21 @@ + + void core_sysdep_rand(uint8_t *output, uint32_t output_len) + { +- uint32_t idx = 0, bytes = 0, rand_num = 0; +- struct timeval time; +- +- memset(&time, 0, sizeof(struct timeval)); +- gettimeofday(&time, NULL); +- +- srand((unsigned int)(time.tv_sec * 1000 + time.tv_usec / 1000) + rand()); +- +- for (idx = 0; idx < output_len;) { +- if (output_len - idx < 4) { +- bytes = output_len - idx; +- } else { +- bytes = 4; +- } +- rand_num = rand(); +- while (bytes-- > 0) { +- output[idx++] = (uint8_t)(rand_num >> bytes * 8); +- } +- } ++ uapi_drv_cipher_trng_get_random_bytes(output, output_len); + } + + void *core_sysdep_mutex_init(void) + { + int res = 0; +- pthread_mutex_t *mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); ++ osal_mutex *mutex = (osal_mutex *)osal_kmalloc(sizeof(osal_mutex), 0); + if (NULL == mutex) { + return NULL; + } + +- if (0 != (res = pthread_mutex_init(mutex, NULL))) { ++ memset_s(mutex, sizeof(osal_mutex), 0, sizeof(osal_mutex)); ++ if (osal_mutex_init(mutex) != OSAL_SUCCESS) { + _core_printf("create mutex failed \n"); +- free(mutex); ++ osal_kfree(mutex); + return NULL; + } + /* _core_printf("init mutex: %p\n",mutex); */ +@@ -720,8 +707,8 @@ + { + int res = 0; + if (mutex != NULL) { +- if (0 != (res = pthread_mutex_lock((pthread_mutex_t *)mutex))) { +- _core_printf("lock mutex failed: - '%s' (%d)\n", strerror(res), res); ++ if (osal_mutex_lock((osal_mutex *)mutex) != OSAL_SUCCESS) { ++ osal_printk("lock mutex failed: - '%s' (%d)\n", strerror(res), res); + } + } + } +@@ -730,9 +717,7 @@ + { + int res = 0; + if (mutex != NULL) { +- if (0 != (res = pthread_mutex_unlock((pthread_mutex_t *)mutex))) { +- _core_printf("unlock mutex failed - '%s' (%d)\n", strerror(res), res); +- } ++ osal_mutex_unlock((osal_mutex *)mutex); + } + } + +@@ -741,10 +726,8 @@ + int err_num = 0; + if (mutex != NULL) { + /* _core_printf("deinit mutex: %p\n",mutex); */ +- if (0 != (err_num = pthread_mutex_destroy(*(pthread_mutex_t **)mutex))) { +- _core_printf("destroy mutex failed\n"); +- } +- free(*(pthread_mutex_t **)mutex); ++ osal_mutex_destroy(*(osal_mutex **)mutex); ++ osal_kfree(*(osal_mutex **)mutex); + *mutex = NULL; + } + } diff --git a/application/samples/wifi/alilink_sample/alilink_sample.c b/application/samples/wifi/alilink_sample/alilink_sample.c new file mode 100755 index 0000000..f96f283 --- /dev/null +++ b/application/samples/wifi/alilink_sample/alilink_sample.c @@ -0,0 +1,261 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: alilink sample include wifi sta auto connect and then connect to ali cloud \n + * + * History: \n + * 2024-09-19, Create file. \n + */ + +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "td_base.h" +#include "td_type.h" +#include "stdlib.h" +#include "uart.h" +#include "cmsis_os2.h" +#include "app_init.h" +#include "soc_osal.h" + +#define ALILINK_IFNAME_MAX_SIZE 16 +#define ALILINK_MAX_SSID_LEN 33 +#define ALILINK_SCAN_AP_LIMIT 64 +#define ALILINK_MAC_LEN 6 +#define ALILINK_SAMPLE_LOG "[ALILINK_SAMPLE]" +#define ALILINK_NOT_AVALLIABLE 0 +#define ALILINK_AVALLIABLE 1 +#define ALILINK_GET_IP_MAX_COUNT 300 + +#define ALILINK_TASK_PRIO (osPriority_t)(13) +#define ALILINK_TASK_DURATION_MS 2000 +#define ALILINK_TASK_STACK_SIZE 0x2000 + +extern td_s32 alilink_task_start(td_void); +static td_void alilink_scan_state_changed(td_s32 state, td_s32 size); +static td_void alilink_connection_changed(td_s32 state, const wifi_linked_info_stru *info, td_s32 reason_code); + +static wifi_event_stru g_alilink_wifi_event_cb = { + .wifi_event_connection_changed = alilink_connection_changed, + .wifi_event_scan_state_changed = alilink_scan_state_changed, +}; + +enum { + ALILINK_SAMPLE_INIT = 0, /* 0:初始态 */ + ALILINK_SAMPLE_SCANING, /* 1:扫描中 */ + ALILINK_SAMPLE_SCAN_DONE, /* 2:扫描完成 */ + ALILINK_SAMPLE_FOUND_TARGET, /* 3:匹配到目标AP */ + ALILINK_SAMPLE_CONNECTING, /* 4:连接中 */ + ALILINK_SAMPLE_CONNECT_DONE, /* 5:关联成功 */ + ALILINK_SAMPLE_GET_IP, /* 6:获取IP */ +} wifi_state_enum; + +static td_u8 g_alilink_wifi_state = ALILINK_SAMPLE_INIT; + +/***************************************************************************** + STA 扫描事件回调函数 +*****************************************************************************/ +static td_void alilink_scan_state_changed(td_s32 state, td_s32 size) +{ + UNUSED(state); + UNUSED(size); + PRINT("%s::Scan done!.\r\n", ALILINK_SAMPLE_LOG); + g_alilink_wifi_state = ALILINK_SAMPLE_SCAN_DONE; + return; +} + +/***************************************************************************** + STA 关联事件回调函数 +*****************************************************************************/ +static td_void alilink_connection_changed(td_s32 state, const wifi_linked_info_stru *info, td_s32 reason_code) +{ + UNUSED(info); + UNUSED(reason_code); + + if (state == ALILINK_NOT_AVALLIABLE) { + PRINT("%s::Connect fail!. try agin !\r\n", ALILINK_SAMPLE_LOG); + g_alilink_wifi_state = ALILINK_SAMPLE_INIT; + } else { + PRINT("%s::Connect succ!.\r\n", ALILINK_SAMPLE_LOG); + g_alilink_wifi_state = ALILINK_SAMPLE_CONNECT_DONE; + } +} + +/***************************************************************************** + STA 匹配目标AP +*****************************************************************************/ +static td_s32 alilink_get_match_network(wifi_sta_config_stru *expected_bss) +{ + td_s32 ret; + td_u32 num = 64; /* 64:扫描到的Wi-Fi网络数量 */ + td_char expected_ssid[] = "my_softAP"; + td_char key[] = "my_password"; /* 待连接的网络接入密码 */ + td_bool find_ap = TD_FALSE; + td_u8 bss_index; + /* 获取扫描结果 */ + td_u32 scan_len = sizeof(wifi_scan_info_stru) * ALILINK_SCAN_AP_LIMIT; + wifi_scan_info_stru *result = osal_kmalloc(scan_len, OSAL_GFP_ATOMIC); + if (result == TD_NULL) { + return -1; + } + (td_void)memset_s(result, scan_len, 0, scan_len); + ret = wifi_sta_get_scan_info(result, &num); + if (ret != 0) { + osal_kfree(result); + return -1; + } + /* 筛选扫描到的Wi-Fi网络,选择待连接的网络 */ + for (bss_index = 0; bss_index < num; bss_index ++) { + if (strlen(expected_ssid) == strlen(result[bss_index].ssid)) { + if (memcmp(expected_ssid, result[bss_index].ssid, strlen(expected_ssid)) == 0) { + find_ap = TD_TRUE; + break; + } + } + } + /* 未找到待连接AP,可以继续尝试扫描或者退出 */ + if (find_ap == TD_FALSE) { + osal_kfree(result); + return -1; + } + /* 找到网络后复制网络信息和接入密码 */ + if (memcpy_s(expected_bss->ssid, ALILINK_MAX_SSID_LEN, expected_ssid, strlen(expected_ssid)) != 0) { + osal_kfree(result); + return -1; + } + if (memcpy_s(expected_bss->bssid, ALILINK_MAC_LEN, result[bss_index].bssid, ALILINK_MAC_LEN) != 0) { + osal_kfree(result); + return -1; + } + expected_bss->security_type = result[bss_index].security_type; + if (memcpy_s(expected_bss->pre_shared_key, sizeof(expected_bss->pre_shared_key), key, strlen(key)) != 0) { + osal_kfree(result); + return -1; + } + expected_bss->ip_type = 1; /* 1:IP类型为动态DHCP获取 */ + osal_kfree(result); + return 0; +} + +/***************************************************************************** + STA DHCP状态查询 +*****************************************************************************/ +static td_bool alilink_check_dhcp_status(struct netif *netif_p, td_u32 *wait_count) +{ + if ((ip_addr_isany(&(netif_p->ip_addr)) == 0) && (*wait_count <= ALILINK_GET_IP_MAX_COUNT)) { + /* DHCP成功 */ + PRINT("%s::STA DHCP success.\r\n", ALILINK_SAMPLE_LOG); + return 0; + } + + if (*wait_count > ALILINK_GET_IP_MAX_COUNT) { + PRINT("%s::STA DHCP timeout, try again !.\r\n", ALILINK_SAMPLE_LOG); + *wait_count = 0; + g_alilink_wifi_state = ALILINK_SAMPLE_INIT; + } + return -1; +} + +static td_s32 alilink_sta_function(td_void) +{ + td_char ifname[ALILINK_IFNAME_MAX_SIZE + 1] = "wlan0"; /* 创建的STA接口名 */ + wifi_sta_config_stru expected_bss = {0}; /* 连接请求信息 */ + struct netif *netif_p = TD_NULL; + td_u32 wait_count = 0; + + /* 创建STA接口 */ + if (wifi_sta_enable() != 0) { + return -1; + } + PRINT("%s::STA enable succ.\r\n", ALILINK_SAMPLE_LOG); + + do { + (void)osDelay(1); /* 1: 等待10ms后判断状态 */ + if (g_alilink_wifi_state == ALILINK_SAMPLE_INIT) { + PRINT("%s::Scan start!\r\n", ALILINK_SAMPLE_LOG); + g_alilink_wifi_state = ALILINK_SAMPLE_SCANING; + /* 启动STA扫描 */ + if (wifi_sta_scan() != 0) { + g_alilink_wifi_state = ALILINK_SAMPLE_INIT; + continue; + } + } else if (g_alilink_wifi_state == ALILINK_SAMPLE_SCAN_DONE) { + /* 获取待连接的网络 */ + if (alilink_get_match_network(&expected_bss) != 0) { + PRINT("%s::Do not find AP, try again !\r\n", ALILINK_SAMPLE_LOG); + g_alilink_wifi_state = ALILINK_SAMPLE_INIT; + continue; + } + g_alilink_wifi_state = ALILINK_SAMPLE_FOUND_TARGET; + } else if (g_alilink_wifi_state == ALILINK_SAMPLE_FOUND_TARGET) { + PRINT("%s::Connect start.\r\n", ALILINK_SAMPLE_LOG); + g_alilink_wifi_state = ALILINK_SAMPLE_CONNECTING; + /* 启动连接 */ + if (wifi_sta_connect(&expected_bss) != 0) { + g_alilink_wifi_state = ALILINK_SAMPLE_INIT; + continue; + } + } else if (g_alilink_wifi_state == ALILINK_SAMPLE_CONNECT_DONE) { + PRINT("%s::DHCP start.\r\n", ALILINK_SAMPLE_LOG); + g_alilink_wifi_state = ALILINK_SAMPLE_GET_IP; + netif_p = netifapi_netif_find(ifname); + if (netif_p == TD_NULL || netifapi_dhcp_start(netif_p) != 0) { + PRINT("%s::find netif or start DHCP fail, try again !\r\n", ALILINK_SAMPLE_LOG); + g_alilink_wifi_state = ALILINK_SAMPLE_INIT; + continue; + } + } else if (g_alilink_wifi_state == ALILINK_SAMPLE_GET_IP) { + if (alilink_check_dhcp_status(netif_p, &wait_count) == 0) { + break; + } + wait_count++; + } + } while (1); + + return 0; +} + +int alilink_sample_init(void *param) +{ + UNUSED(param); + + /* 注册事件回调 */ + if (wifi_register_event_cb(&g_alilink_wifi_event_cb) != 0) { + PRINT("%s::g_alilink_wifi_event_cb register fail.\r\n", ALILINK_SAMPLE_LOG); + return -1; + } + PRINT("%s::g_alilink_wifi_event_cb register succ.\r\n", ALILINK_SAMPLE_LOG); + + /* 等待wifi初始化完成 */ + while (wifi_is_wifi_inited() == 0) { + (void)osDelay(10); /* 10: 等待100ms后判断状态 */ + } + PRINT("%s::wifi init succ.\r\n", ALILINK_SAMPLE_LOG); + + if (alilink_sta_function() != 0) { + PRINT("%s::alilink_sta_function fail.\r\n", ALILINK_SAMPLE_LOG); + return -1; + } + + alilink_task_start(); + return 0; +} + +static void alilink_sample_entry(void) +{ + osThreadAttr_t attr; + attr.name = "alilink_sample_task"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = ALILINK_TASK_STACK_SIZE; + attr.priority = ALILINK_TASK_PRIO; + if (osThreadNew((osThreadFunc_t)alilink_sample_init, NULL, &attr) == NULL) { + PRINT("%s::Create alilink_sample_task fail.\r\n", ALILINK_SAMPLE_LOG); + } + PRINT("%s::Create alilink_sample_task succ.\r\n", ALILINK_SAMPLE_LOG); +} + +/* Run the sta_sample_task. */ +app_run(alilink_sample_entry); \ No newline at end of file diff --git a/application/samples/wifi/ble_wifi_cfg_sample/CMakeLists.txt b/application/samples/wifi/ble_wifi_cfg_sample/CMakeLists.txt new file mode 100755 index 0000000..4a6a4e8 --- /dev/null +++ b/application/samples/wifi/ble_wifi_cfg_sample/CMakeLists.txt @@ -0,0 +1,10 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/ble_wifi_cfg_sample.c" PARENT_SCOPE) + +set(PRIVATE_HEADER + ${ROOT_DIR}/samples/bt/ble/ble_wifi_cfg_server/inc + ${ROOT_DIR}/samples/bt/ble/ble_wifi_cfg_client/inc +) \ No newline at end of file diff --git a/application/samples/wifi/ble_wifi_cfg_sample/ble_wifi_cfg_sample.c b/application/samples/wifi/ble_wifi_cfg_sample/ble_wifi_cfg_sample.c new file mode 100755 index 0000000..e358efd --- /dev/null +++ b/application/samples/wifi/ble_wifi_cfg_sample/ble_wifi_cfg_sample.c @@ -0,0 +1,494 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * + * Description: Application core main function for standard \n + * + * History: \n + * 2022-07-27, Create file. \n + */ + +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "td_base.h" +#include "td_type.h" +#include "stdlib.h" +#include "uart.h" +#include "cmsis_os2.h" +#include "soc_osal.h" +#include "app_init.h" + +#include "ble_wifi_cfg_scan.h" +#include "ble_wifi_cfg_adv.h" +#include "ble_wifi_cfg_server.h" +#include "ble_wifi_cfg_client.h" + +#define WIFI_IFNAME_MAX_SIZE 16 +#define WIFI_MAX_KEY_LEN 65 +#define WIFI_MAX_SSID_LEN 33 +#define WIFI_SCAN_AP_LIMIT 64 +#define WIFI_MAC_LEN 6 +#define WIFI_GET_IP_MAX_TIMES 100 +#define WIFI_MAX_CONFIG_INFO_LEN 64 +#define WIFI_CONFIG_INFO_SSID_LEN 32 +#define WIFI_CONFIG_INFO_KEY_LEN 32 +#define BGLE_WIFI_CFG_LOG "[BGLE_WIFI_DEBUG]" +#define WIFI_AP_LIST_MAX_NUM 10 +/* 前2字节为上报类型和ap个数 */ +#define WIFI_AP_LIST_PREFIX_LEN 2 + +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_MICHAEL_MIC_FAILURE 14 +#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 +#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16 +#define WLAN_DISCONN_BY_AP_BIT 15 + +#define WLAN_STATUS_CHALLENGE_FAIL 15 + +#define MAC_JOIN_RSP_TIMEOUT 5200 +#define MAC_AUTH_RSP2_TIMEOUT 5201 +#define MAC_AUTH_RSP4_TIMEOUT 5202 +#define MAC_ASOC_RSP_TIMEOUT 5203 +#define WLAN_DISASOC_MISC_LINKLOSS 5206 +#define WIFI_NETWORK_NOT_FOUND_ERROR 5300 +#define MAC_STATUS_MAX 7000 + + +enum { + CONFIG_DEMO_INIT = 0, /* 0:初始态 */ + CONFIG_DEMO_WIFI_INIT, /* 1:重新连接设备 待配网 */ + CONFIG_DEMO_WIFI_SCAN_DOING, /* 2:扫描中 */ + CONFIG_DEMO_WIFI_SCAN_DONE, /* 3:扫描完成 */ + CONFIG_DEMO_WIFI_CONNECT_DOING, /* 4:WiFi连接中 */ + CONFIG_DEMO_WIFI_CONNECT_DONE, /* 5:Wifi连接完成 */ + CONFIG_DEMO_WIFI_DHCP_DONE, +} bgwc_state_enum; + +enum { + CFG_TYPE_WIFI_STATE = 1, /* WiFi关联状态 */ + CFG_TYPE_AP_LIST = 2 /* 扫描到的AP列表信息 */ +} bgwc_cfg_type; + +typedef enum { + WIFI_ERRCODE_NONE = 0, + WIFI_ERRCODE_SSID_NOT_FOUND, + WIFI_ERRCODE_PWD_ERROR, + WIFI_ERRCODE_DHCP_FAILED, + WIFI_ERRCODE_BEACON_LOST, + WIFI_ERRCODE_OTHERS +} bgwc_wifi_errcode; + +typedef struct { + char ssid[WIFI_MAX_SSID_LEN]; + int8_t rssi; +} bgwc_wifi_bss; + +td_char g_data[WIFI_MAX_CONFIG_INFO_LEN] = {0}; +static td_u8 g_bgwc_state = CONFIG_DEMO_INIT; +uint8_t g_wifi_cfg_info_flag = 0; /* 0:no info 1:save info */ +uint8_t g_wifi_list_req_flag = 0; /* 0:recv req 1:no req */ +int8_t g_errcode = WIFI_ERRCODE_NONE; + +static int8_t get_wifi_errcode(void) +{ + return g_errcode; +} + +uint8_t get_wifi_cfg_info_flag(void) +{ + return g_wifi_cfg_info_flag; +} + +void set_wifi_cfg_info_flag(uint8_t flag) +{ + g_wifi_cfg_info_flag = flag; +} + +uint8_t get_wifi_list_req_flag(void) +{ + return g_wifi_list_req_flag; +} + +void set_wifi_list_req_flag(uint8_t flag) +{ + g_wifi_list_req_flag = flag; +} + +void set_wifi_cfg_info(uint8_t *info, uint16_t info_len) +{ + set_wifi_cfg_info_flag(1); + (void)memcpy_s(g_data, WIFI_MAX_CONFIG_INFO_LEN, info, info_len); +} + +int bgwc_wifi_list_resp_send(uint16_t handle) +{ + set_wifi_list_req_flag(1); + uint8_t result = 0x01; + errcode_t ret = ble_wifi_cfg_server_send_report_by_handle(handle, (const uint8_t *)&result, sizeof(uint8_t)); + if (ret != ERRCODE_BT_SUCCESS) { + PRINT("bgwc_wifi_list_resp_send fail, ret:%x.\n", ret); + } + return ret; +} + +td_s32 example_get_match_network(wifi_sta_config_stru *expected_bss) +{ + td_s32 ret; + td_u32 num = 64; /* 最大扫描到网络数量64 */ + td_char expected_ssid[WIFI_CONFIG_INFO_SSID_LEN] = {0}; + td_char key[WIFI_CONFIG_INFO_KEY_LEN] = {0}; /* 待连接的网络接入密码 */ + td_bool find_ap = TD_FALSE; + td_u8 bss_index; + /* 获取扫描结果 */ + td_u32 scan_len = sizeof(wifi_scan_info_stru) * WIFI_SCAN_AP_LIMIT; + wifi_scan_info_stru *result = osal_kmalloc(scan_len, OSAL_GFP_ATOMIC); + if (result == NULL) { + return -1; + } + memset_s(result, scan_len, 0, scan_len); + ret = wifi_sta_get_scan_info(result, &num); + if (ret != 0) { + osal_kfree(result); + return -1; + } + + memcpy_s(expected_ssid, WIFI_CONFIG_INFO_SSID_LEN, g_data, WIFI_CONFIG_INFO_SSID_LEN); + memcpy_s(key, WIFI_CONFIG_INFO_SSID_LEN, g_data + WIFI_CONFIG_INFO_SSID_LEN, WIFI_CONFIG_INFO_KEY_LEN); + + PRINT("%s expected_ssid :%s, key:%s\r\n", BGLE_WIFI_CFG_LOG, expected_ssid, key); + + /* 筛选扫描到的Wi-Fi网络,选择待连接的网络 */ + for (bss_index = 0; bss_index < num; bss_index++) { + if (strlen(expected_ssid) == strlen(result[bss_index].ssid)) { + if (memcmp(expected_ssid, result[bss_index].ssid, strlen(expected_ssid)) == 0) { + find_ap = TD_TRUE; + break; + } + } + } + /* 未找到待连接AP,可以继续尝试扫描或者退出 */ + if (find_ap == TD_FALSE) { + osal_kfree(result); + return -1; + } + /* 找到网络后复制网络信息和接入密码 */ + if (memcpy_s(expected_bss->ssid, WIFI_MAX_SSID_LEN, expected_ssid, strlen(expected_ssid)) != 0) { + osal_kfree(result); + return -1; + } + if (memcpy_s(expected_bss->bssid, WIFI_MAC_LEN, result[bss_index].bssid, WIFI_MAC_LEN) != 0) { + osal_kfree(result); + return -1; + } + expected_bss->security_type = result[bss_index].security_type; + if (memcpy_s(expected_bss->pre_shared_key, WIFI_MAX_SSID_LEN, key, strlen(key)) != 0) { + osal_kfree(result); + return -1; + } + expected_bss->ip_type = 1; + osal_kfree(result); + return 0; +} + +td_bool example_check_connect_status(td_void) +{ + td_u8 index; + wifi_linked_info_stru wifi_status; + /* 获取网络连接状态,共查询5次 */ + for (index = 0; index < 5; index++) { + (td_void)osDelay(50); /* 每次间隔50 tick */ + memset_s(&wifi_status, sizeof(wifi_linked_info_stru), 0, sizeof(wifi_linked_info_stru)); + if (wifi_sta_get_ap_info(&wifi_status) != 0) { + continue; + } + if (wifi_status.conn_state == 1) { + return 0; /* 连接成功退出循环 */ + } + } + return -1; +} + +static td_void bgwc_get_ap_list_info(wifi_scan_info_stru *scan_ret, uint32_t real_ap_number, uint8_t *report_data) +{ + bgwc_wifi_bss bss = { 0 }; + uint8_t *bss_data = NULL; + uint32_t count = 0; + + report_data[0] = CFG_TYPE_AP_LIST; + bss_data = report_data + WIFI_AP_LIST_PREFIX_LEN; + for (uint32_t idx = 0; idx < real_ap_number; idx++) { + if (strlen(scan_ret[idx].ssid) == 0) { + continue; + } + if (memcpy_s(bss.ssid, sizeof(bss.ssid), scan_ret[idx].ssid, sizeof(scan_ret[idx].ssid) - 1) != EOK) { + return; + } + bss.rssi = (int8_t)scan_ret[idx].rssi; + if (memcpy_s(bss_data, sizeof(bgwc_wifi_bss), &bss, sizeof(bss)) != EOK) { + return; + } + PRINT("%d:ssid[%s]\trssi[%d] \t\r\n", count, bss.ssid, bss.rssi); + bss_data += sizeof(bgwc_wifi_bss); + count++; + /* report max num: 10 */ + if (count >= WIFI_AP_LIST_MAX_NUM) { + break; + } + } + report_data[1] = (uint8_t)count; +} + +static td_void bgwc_scan_state_changed(td_s32 state, td_s32 size) +{ + wifi_scan_info_stru *scan_ret = NULL; + uint32_t real_ap_number = (uint32_t)size; + uint8_t *report_data = NULL; + uint32_t max_len; + PRINT("%s bgwc_scan_state_changed enter.\n", BGLE_WIFI_CFG_LOG); + UNUSED(state); + + g_bgwc_state = CONFIG_DEMO_WIFI_SCAN_DONE; + if ((get_wifi_list_req_flag() == 0) || (size <= 0)) { + return; + } + + scan_ret = (wifi_scan_info_stru *)malloc(sizeof(wifi_scan_info_stru) * real_ap_number); + if (scan_ret == NULL) { + return; + } + memset_s(scan_ret, sizeof(wifi_scan_info_stru) * real_ap_number, 0, sizeof(wifi_scan_info_stru) * real_ap_number); + if (wifi_sta_get_scan_info(scan_ret, &real_ap_number) != ERRCODE_SUCC) { + free(scan_ret); + return; + } + + max_len = sizeof(bgwc_wifi_bss) * WIFI_AP_LIST_MAX_NUM + WIFI_AP_LIST_PREFIX_LEN; + report_data = (uint8_t *)malloc(max_len); + if (report_data == NULL) { + free(scan_ret); + return; + } + memset_s(report_data, max_len, 0, max_len); + bgwc_get_ap_list_info(scan_ret, real_ap_number, report_data); + ble_wifi_cfg_server_send_report_by_uuid((const uint8_t *)report_data, + sizeof(bgwc_wifi_bss) * report_data[1] + WIFI_AP_LIST_PREFIX_LEN); /* 真实写入数据的长度 */ + /* 恢复初始值 */ + set_wifi_list_req_flag(0); + free(scan_ret); + free(report_data); + return; +} + +static void bgwc_wifi_reason_code(td_s32 reason_code, int8_t *err_code) +{ + int disconn_by_ap = (reason_code >> WLAN_DISCONN_BY_AP_BIT) & 1; + + reason_code = reason_code & ~(1 << WLAN_DISCONN_BY_AP_BIT); + /* 密码错误由对端AP校验并返回错误码 */ + if (disconn_by_ap == 1) { + switch (reason_code) { + case 0: + *err_code = WIFI_ERRCODE_NONE; + break; + case WLAN_REASON_PREV_AUTH_NOT_VALID: + case WLAN_REASON_MICHAEL_MIC_FAILURE: + case WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT: + case WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT: + *err_code = WIFI_ERRCODE_PWD_ERROR; + break; + default: + *err_code = WIFI_ERRCODE_OTHERS; + break; + } + return; + } + /* 自身主动断开场景, 错误码转换 */ + if (reason_code >= MAC_STATUS_MAX) { + reason_code -= MAC_STATUS_MAX; + } + + if (reason_code == WLAN_DISASOC_MISC_LINKLOSS) { + *err_code = WIFI_ERRCODE_BEACON_LOST; + return; + } else if (reason_code == WIFI_NETWORK_NOT_FOUND_ERROR) { + *err_code = WIFI_ERRCODE_SSID_NOT_FOUND; + return; + } + switch (reason_code) { + case WLAN_STATUS_CHALLENGE_FAIL: + *err_code = WIFI_ERRCODE_PWD_ERROR; + break; + default: + *err_code = WIFI_ERRCODE_OTHERS; + break; + } + return; +} + +static td_void bgwc_connection_changed(td_s32 state, const wifi_linked_info_stru *info, td_s32 reason_code) +{ + UNUSED(state); + PRINT("%s bgwc_connection_changed enter.\n", BGLE_WIFI_CFG_LOG); + + g_errcode = WIFI_ERRCODE_NONE; + if (info->conn_state == WIFI_DISCONNECTED) { + bgwc_wifi_reason_code(reason_code, &g_errcode); + } + g_bgwc_state = CONFIG_DEMO_WIFI_CONNECT_DONE; + return; +} + +static td_void bgwc_softap_state_changed(td_s32 state) +{ + UNUSED(state); + PRINT("%s bgwc_softap_state_changed enter.\n", BGLE_WIFI_CFG_LOG); + return; +} + +wifi_event_stru ble_wifi_cfg_event_cb = { + .wifi_event_scan_state_changed = bgwc_scan_state_changed, + .wifi_event_connection_changed = bgwc_connection_changed, + .wifi_event_softap_state_changed = bgwc_softap_state_changed +}; + +int bgwc_wifi_connect(void) +{ + wifi_sta_config_stru expected_bss = { 0 }; /* 连接请求信息 */ + /* 获取待连接的网络 */ + if (example_get_match_network(&expected_bss) != 0) { + PRINT("Do not find AP, try again !\r\n"); + g_errcode = WIFI_ERRCODE_SSID_NOT_FOUND; + return -1; + } + + /* 启动连接 */ + if (wifi_sta_connect(&expected_bss) != 0) { + PRINT("STA connect fail.\r\n"); + g_errcode = WIFI_ERRCODE_OTHERS; + return -1; + } + return 0; +} + +static void bgwc_ble_start(void) +{ + errcode_t ret = ERRCODE_SUCC; + /* 调用BLE起广播接口与注册回调接口 */ + ret |= ble_wifi_cfg_server_init(); + PRINT("%s Ble Init State:%d.\r\n", BGLE_WIFI_CFG_LOG, ret); + ret |= ble_wifi_cfg_start_adv(); + PRINT("%s Ble Adv State:%d.\r\n", BGLE_WIFI_CFG_LOG, ret); +} + +static int bgwc_wifi_start(void) +{ + g_bgwc_state = CONFIG_DEMO_WIFI_INIT; + + if (wifi_sta_enable() != 0) { + PRINT("%s sta enbale fail !\r\n", BGLE_WIFI_CFG_LOG); + return -1; + } + + if (wifi_register_event_cb(&ble_wifi_cfg_event_cb) != 0) { + PRINT("%s wifi_register_event_cb fail.\r\n", BGLE_WIFI_CFG_LOG); + return -1; + } + return 0; +} + +static void *ble_wifi_cfg_example_task(const char *arg) +{ + td_char ifname[WIFI_IFNAME_MAX_SIZE + 1] = "wlan0"; /* 创建的STA接口名 */ + struct netif *netif_p = NULL; + uint8_t result[WIFI_AP_LIST_PREFIX_LEN] = {CFG_TYPE_WIFI_STATE, 0}; + UNUSED(arg); + (td_void)osDelay(200); /* 初始化等待200 tick */ + + bgwc_ble_start(); + bgwc_wifi_start(); + + while (1) { + (td_void)osDelay(10); /* 等待10 tick */ + /* 兼容主动和被动配网方案 */ + if (get_wifi_cfg_info_flag() || get_wifi_list_req_flag()) { + PRINT("wifi cfg flag:%d, wifi list flag:%d.\n", get_wifi_cfg_info_flag(), get_wifi_list_req_flag()); + /* 启动STA扫描 */ + if (wifi_sta_scan() != 0) { + printf("wifi_sta_scan fail.\n"); + g_bgwc_state = CONFIG_DEMO_WIFI_INIT; + } else { + break; + } + } + } + + while (1) { + (td_void)osDelay(10); /* 等待10 tick */ + /* 检测是否下发配置信息 */ + if (get_wifi_cfg_info_flag() && (g_bgwc_state == CONFIG_DEMO_WIFI_SCAN_DONE)) { + if (bgwc_wifi_connect() == 0) { + g_bgwc_state = CONFIG_DEMO_WIFI_CONNECT_DOING; + } else { + printf("bgwc_wifi_connect fail.\n"); + g_bgwc_state = CONFIG_DEMO_WIFI_INIT; + break; + } + } + /* 完成WiFi连接 尝试DHCP */ + if (g_bgwc_state == CONFIG_DEMO_WIFI_CONNECT_DONE) { + break; + } + } + result[1] = get_wifi_errcode(); + if (result[1] != WIFI_ERRCODE_NONE) { + PRINT("STA ASSOC Fail.\r\n"); + goto EXIT; + } + result[1] = WIFI_ERRCODE_DHCP_FAILED; + PRINT("STA DHCP start.\r\n"); + /* DHCP获取IP地址 */ + netif_p = netifapi_netif_find(ifname); + if (netif_p == NULL) { + PRINT("not find %s.\r\n", ifname); + goto EXIT; + } + if (netifapi_dhcp_start(netif_p) != 0) { + PRINT("STA DHCP Fail.\r\n"); + goto EXIT; + } + + for (td_char i = 0; i < WIFI_GET_IP_MAX_TIMES; i++) { + (td_void)osDelay(10); /* 等待10 tick */ + if (ip_addr_isany(&(netif_p->ip_addr)) == 0) { + PRINT("STA DHCP Succ.\r\n"); + result[1] = WIFI_ERRCODE_NONE; + break; + } + } +EXIT: + PRINT("result code:%d.\r\n", result[1]); + ble_wifi_cfg_server_send_report_by_uuid((const uint8_t *)result, sizeof(result)); + return NULL; +} + +#define BGWC_TASK_PRIO (osPriority_t)(26) +#define BGWC_TASK_STACK_SIZE 0x1000 + +static void bgle_wifi_cfg_entry(void) +{ + osal_kthread_lock(); + osal_task *g_wifi_cfg_task = osal_kthread_create((osal_kthread_handler)ble_wifi_cfg_example_task, 0, + "bgle_wifi_cfg_task", BGWC_TASK_STACK_SIZE); + if (g_wifi_cfg_task != NULL) { + osal_kthread_set_priority(g_wifi_cfg_task, BGWC_TASK_PRIO); + osal_kfree(g_wifi_cfg_task); + } + osal_kthread_unlock(); +} + +/* Run the ble_wifi_cfg_entry. */ +app_run(bgle_wifi_cfg_entry); \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/CMakeLists.txt b/application/samples/wifi/hilink_indie_upgrade/CMakeLists.txt new file mode 100755 index 0000000..98fd9cc --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/CMakeLists.txt @@ -0,0 +1,6 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(address_mapping/application) +add_subdirectory_if_exist(address_mapping/hilinksdk) diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/CMakeLists.txt b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/CMakeLists.txt new file mode 100755 index 0000000..da91a19 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/CMakeLists.txt @@ -0,0 +1,68 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "app_addr_map") + +set(CMAKE_HILINK_SOURCE_DIR + ${CMAKE_CURRENT_SOURCE_DIR}) + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/app_call_entry.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_function_mapping.c + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_hilink.c + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_hilink_log_manage.c + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_hilink_device_ext.c + + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_ble_cfg_net_api.c + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_hilink_bt_function.c + + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_hilink_network_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_hilink_socket_adapter.c + + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_hilink_custom.c + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_hilink_sle_api.c + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/uapi_hilink_quick_netcfg_api.c +) + +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/ +) + +set(PRIVATE_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/../../../ohos_connect/hilink_adapt/product/ + ${CMAKE_CURRENT_SOURCE_DIR}/../../../ohos_connect/hilink_adapt/include/ + ${CMAKE_CURRENT_SOURCE_DIR}/../../../ohos_connect/hilink_adapt/adapter/include/ + + ${CMAKE_CURRENT_SOURCE_DIR}/ + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_uapi/ + ${CMAKE_CURRENT_SOURCE_DIR}/../include/ +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -Wno-error=logical-op + -Wno-error=sign-compare + -Wno-error=jump-misses-init + -Wno-sign-compare + -Wno-jump-misses-init + -Wno-error=unused-parameter + -Wno-unused-parameter + -Wno-unused-but-set-variable + -Wno-error=unused-variable +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + false +) + +set(LIB_OUT_PATH ${BIN_DIR}/${CHIP}/libs/wifi/${TARGET_COMMAND}) + +build_component() \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_call_entry.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_call_entry.c new file mode 100755 index 0000000..98d5278 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_call_entry.c @@ -0,0 +1,87 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: app call entry. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call_entry.h" +#include +#include "app_function_mapping.h" +#include "func_call.h" + +#define BITS_PER_BYTES 8 +#define CRC32_TBL_SIZE 256 + +unsigned int g_crc32_tbl[CRC32_TBL_SIZE] = { 0 }; + +static api_get g_hilink_api_get = NULL; + +static struct hilink_info_stru *g_hilink_info = (struct hilink_info_stru *)&hilink_info_addr; + +void *get_hilink_api_addr(unsigned int index, const char *prototype) +{ + return g_hilink_api_get == NULL ? NULL : g_hilink_api_get(index, prototype); +} + +static void init_crc32_table(void) +{ + for (unsigned int i = 0; i < CRC32_TBL_SIZE; i++) { + unsigned int tmp = i; + for (unsigned char bit = 0; bit < BITS_PER_BYTES; bit++) { + if ((tmp & 1) != 0) { + /* 0xEDB88320 为 CRC32 的生成多项式的反转 */ + tmp = (tmp >> 1) ^ 0xEDB88320; + } else { + tmp = tmp >> 1; + } + } + g_crc32_tbl[i] = tmp; + } +} + +static unsigned int prototype_cal_crc32(const char *input) +{ + unsigned int checksum = 0xFFFFFFFF; + for (unsigned int i = 0; input[i] != 0; i++) { + if (input[i] == ' ') { + continue; + } + checksum = (checksum >> BITS_PER_BYTES) ^ (g_crc32_tbl[(checksum ^ input[i]) & 0xFF]); + } + return ~checksum; +} + +static void *app_api_get(unsigned int index, const char *prototype) +{ + const struct mapping_tbl *app_call_tbl = get_app_mapping_tbl(); + unsigned int size = get_app_mapping_tbl_size(); + if (app_call_tbl == NULL || size == 0) { + return NULL; + } + + unsigned int checksum = prototype_cal_crc32(prototype); + if ((index < size) && (app_call_tbl[index].checksum == checksum)) { + return app_call_tbl[index].addr; + } + /* 对应校验和不匹配,尝试全部匹配 */ + for (unsigned int i = 0; i < size; i++) { + if (app_call_tbl[i].checksum == checksum) { + return app_call_tbl[i].addr; + } + } + return NULL; +} + +void hilink_func_map_init(void) +{ + // printf("%s %d, 0x%x\r\n", __FUNCTION__, __LINE__, g_hilink_info); + + init_crc32_table(); + if (g_hilink_info->entry != NULL) { + // printf("%s %d, 0x%x\r\n", __FUNCTION__, __LINE__, g_hilink_info->entry); + g_hilink_info->entry(&g_hilink_api_get, app_api_get); + } +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_call_entry.h b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_call_entry.h new file mode 100755 index 0000000..ef93e28 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_call_entry.h @@ -0,0 +1,25 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: app call entry. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#ifndef APP_CALL_ENTRY_H +#define APP_CALL_ENTRY_H + +#ifdef __cplusplus +extern "C" { +#endif + +void *get_hilink_api_addr(unsigned int index, const char *prototype); +void hilink_func_map_init(void); + +extern char hilink_info_addr; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_function_mapping.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_function_mapping.c new file mode 100755 index 0000000..97f16b1 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_function_mapping.c @@ -0,0 +1,417 @@ + +#include "app_function_mapping.h" +#include "func_call.h" +#include "func_call_list.h" +#include "hilink_kv_adapter.h" +#include "hilink_mbedtls_utils.h" +#include "hilink_mem_adapter.h" +#include "hilink_network_adapter.h" +#include "hilink_open_ota_adapter.h" +#include "hilink_open_ota_mcu_adapter.h" +#include "hilink_sal_aes.h" +#include "hilink_sal_base64.h" +#include "hilink_sal_defines.h" +#include "hilink_sal_drbg.h" +#include "hilink_sal_kdf.h" +#include "hilink_sal_md.h" +#include "hilink_sal_mpi.h" +#include "hilink_sal_rsa.h" +#include "hilink_socket_adapter.h" +#include "hilink_softap_adapter.h" +#include "hilink_stdio_adapter.h" +#include "hilink_str_adapter.h" +#include "hilink_sys_adapter.h" +#include "hilink_thread_adapter.h" +#include "hilink_time_adapter.h" +#include "hilink_tls_client.h" +#include "hilink_device.h" +#include "ohos_bt_gatt.h" +#include "ohos_bt_def.h" +#include "ohos_bt_gatt_server.h" +#include "hilink_bt_api.h" +#include "hilink_bt_function.h" +#include "ohos_bt_gap.h" +#include "oh_sle_common.h" +#include "oh_sle_connection_manager.h" +#include "oh_sle_device_discovery.h" +#include "oh_sle_ssap_server.h" +#include "hichain.h" +#include "cmsis_os2.h" +#include "cJSON.h" +#include "mbedtls/md.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/bignum.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/hkdf.h" +#include "mbedtls/entropy.h" +#include "mbedtls/sha256.h" +#include "mbedtls/ecp.h" + +static const struct mapping_tbl g_app_call_tbl[APP_CALL_MAX] = { + [APP_CALL_HILINK_KVSTORE_INIT] = { HILINK_KVStoreInit, 0x3A23309A }, + [APP_CALL_HILINK_SET_VALUE] = { HILINK_SetValue, 0xAF0B6921 }, + [APP_CALL_HILINK_GET_VALUE] = { HILINK_GetValue, 0x88B9C567 }, + [APP_CALL_HILINK_DELETE_VALUE] = { HILINK_DeleteValue, 0x55C08452 }, + [APP_CALL_HILINK_GET_FILE_NAME] = { HILINK_GetFileName, 0x23541433 }, + [APP_CALL_HILINK_MALLOC] = { HILINK_Malloc, 0x82C5309A }, + [APP_CALL_HILINK_FREE] = { HILINK_Free, 0x2D3258C3 }, + [APP_CALL_HILINK_MEMCMP] = { HILINK_Memcmp, 0xE6C834A5 }, + [APP_CALL_HILINK_GET_ADDR_INFO] = { HILINK_GetAddrInfo, 0x00B53089 }, + [APP_CALL_HILINK_FREE_ADDR_INFO] = { HILINK_FreeAddrInfo, 0xC7A65C43 }, + [APP_CALL_HILINK_SOCKET] = { HILINK_Socket, 0x392D51DF }, + [APP_CALL_HILINK_CLOSE] = { HILINK_Close, 0xEF32BBC1 }, + [APP_CALL_HILINK_SET_SOCKET_OPT] = { HILINK_SetSocketOpt, 0x25B613C6 }, + [APP_CALL_HILINK_BIND] = { HILINK_Bind, 0xB37656F5 }, + [APP_CALL_HILINK_CONNECT] = { HILINK_Connect, 0x9E142F0D }, + [APP_CALL_HILINK_RECV] = { HILINK_Recv, 0x713AD611 }, + [APP_CALL_HILINK_SEND] = { HILINK_Send, 0x5955749E }, + [APP_CALL_HILINK_RECV_FROM] = { HILINK_RecvFrom, 0x72C53C3B }, + [APP_CALL_HILINK_SEND_TO] = { HILINK_SendTo, 0xA8CD96D2 }, + [APP_CALL_HILINK_SELECT] = { HILINK_Select, 0xC69CB534 }, + [APP_CALL_HILINK_GET_SOCKET_ERRNO] = { HILINK_GetSocketErrno, 0x231411DE }, + [APP_CALL_HILINK_HTONL] = { HILINK_Htonl, 0xAE5C4F17 }, + [APP_CALL_HILINK_NTOHL] = { HILINK_Ntohl, 0x82DA2760 }, + [APP_CALL_HILINK_HTONS] = { HILINK_Htons, 0xBB04E019 }, + [APP_CALL_HILINK_NTOHS] = { HILINK_Ntohs, 0x9813CAC4 }, + [APP_CALL_HILINK_INET_ATON] = { HILINK_InetAton, 0xCBA339BE }, + [APP_CALL_HILINK_INET_ADDR] = { HILINK_InetAddr, 0xBF3D734F }, + [APP_CALL_HILINK_INET_NTOA] = { HILINK_InetNtoa, 0xBF095523 }, + [APP_CALL_HILINK_VPRINTF] = { HILINK_Vprintf, 0x5DD160C0 }, + [APP_CALL_HILINK_RAND] = { HILINK_Rand, 0x387CA4AD }, + [APP_CALL_HILINK_TRNG] = { HILINK_Trng, 0x28BFC876 }, + [APP_CALL_HILINK_STRLEN] = { HILINK_Strlen, 0x6508F627 }, + [APP_CALL_HILINK_STRCHR] = { HILINK_Strchr, 0xD0B46BE4 }, + [APP_CALL_HILINK_STRRCHR] = { HILINK_Strrchr, 0x8319EAC3 }, + [APP_CALL_HILINK_ATOI] = { HILINK_Atoi, 0x71921D27 }, + [APP_CALL_HILINK_STRSTR] = { HILINK_Strstr, 0xD806C9F3 }, + [APP_CALL_HILINK_STRCMP] = { HILINK_Strcmp, 0x464BF4DF }, + [APP_CALL_HILINK_STRNCMP] = { HILINK_Strncmp, 0xBAE09ADB }, + [APP_CALL_HILINK_CREATE_TASK] = { HILINK_CreateTask, 0x95232386 }, + [APP_CALL_HILINK_THREAD_SUSPEND] = { HILINK_ThreadSuspend, 0xB021EEFB }, + [APP_CALL_HILINK_THREAD_RESUME] = { HILINK_ThreadResume, 0xD3FAD2C6 }, + [APP_CALL_HILINK_DELETE_TASK] = { HILINK_DeleteTask, 0xB405A1E9 }, + [APP_CALL_HILINK_GET_CURRENT_TASK_ID] = { HILINK_GetCurrentTaskId, 0xC13BB042 }, + [APP_CALL_HILINK_MUTEX_CREATE] = { HILINK_MutexCreate, 0x0CAB5EF0 }, + [APP_CALL_HILINK_MUTEX_LOCK] = { HILINK_MutexLock, 0x2D3D5430 }, + [APP_CALL_HILINK_MUTEX_UNLOCK] = { HILINK_MutexUnlock, 0x90162EB8 }, + [APP_CALL_HILINK_MUTEX_DESTROY] = { HILINK_MutexDestroy, 0xE51C2E1D }, + [APP_CALL_HILINK_SEM_CREATE] = { HILINK_SemCreate, 0x10F3EE4E }, + [APP_CALL_HILINK_SEM_WAIT] = { HILINK_SemWait, 0xE5FE71A0 }, + [APP_CALL_HILINK_SEM_POST] = { HILINK_SemPost, 0xBA8DF1E9 }, + [APP_CALL_HILINK_SEM_DESTROY] = { HILINK_SemDestroy, 0x5E4A3669 }, + [APP_CALL_HILINK_MILLI_SLEEP] = { HILINK_MilliSleep, 0x4908DDB1 }, + [APP_CALL_HILINK_SCHED_YIELD] = { HILINK_SchedYield, 0x6E08F54B }, + [APP_CALL_HILINK_GET_OS_TIME] = { HILINK_GetOsTime, 0x606E13CA }, + [APP_CALL_HILINK_GET_UTC_TIME] = { HILINK_GetUtcTime, 0xCB530F71 }, + [APP_CALL_HILINK_OTA_ADAPTER_FLASH_INIT] = { HILINK_OtaAdapterFlashInit, 0x320CC9DF }, + [APP_CALL_HILINK_OTA_ADAPTER_GET_UPDATE_INDEX] = { HILINK_OtaAdapterGetUpdateIndex, 0x6C3DCB70 }, + [APP_CALL_HILINK_OTA_ADAPTER_FLASH_ERASE] = { HILINK_OtaAdapterFlashErase, 0xDC6E54BD }, + [APP_CALL_HILINK_OTA_ADAPTER_FLASH_WRITE] = { HILINK_OtaAdapterFlashWrite, 0xA7B3C172 }, + [APP_CALL_HILINK_OTA_ADAPTER_FLASH_READ] = { HILINK_OtaAdapterFlashRead, 0x0E7ECCB5 }, + [APP_CALL_HILINK_OTA_ADAPTER_FLASH_FINISH] = { HILINK_OtaAdapterFlashFinish, 0x4E88950C }, + [APP_CALL_HILINK_OTA_ADAPTER_FLASH_MAX_SIZE] = { HILINK_OtaAdapterFlashMaxSize, 0xFC3D4D70 }, + [APP_CALL_HILINK_OTA_ADAPTER_RESTART] = { HILINK_OtaAdapterRestart, 0x0224AB40 }, + [APP_CALL_HILINK_OTA_START_PROCESS] = { HILINK_OtaStartProcess, 0xD9E568A8 }, + [APP_CALL_HILINK_OTA_END_PROCESS] = { HILINK_OtaEndProcess, 0x95713870 }, + [APP_CALL_HILINK_GET_REBOOT_FLAG] = { HILINK_GetRebootFlag, 0x53E9BB3D }, + [APP_CALL_HILINK_GET_MCU_VERSION] = { HILINK_GetMcuVersion, 0x77889DAA }, + [APP_CALL_HILINK_NOTIFY_OTA_STATUS] = { HILINK_NotifyOtaStatus, 0x102DB1FC }, + [APP_CALL_HILINK_NOTIFY_OTA_DATA] = { HILINK_NotifyOtaData, 0x4CE38751 }, + [APP_CALL_HILINK_RESTART] = { HILINK_Restart, 0xF2E6A0BD }, + [APP_CALL_HILINK_GET_SYSTEM_BOOT_REASON] = { HILINK_GetSystemBootReason, 0x27B0EC51 }, + [APP_CALL_HILINK_SAL_RSA_INIT] = { HILINK_SAL_RsaInit, 0xB8EA015C }, + [APP_CALL_HILINK_SAL_RSA_FREE] = { HILINK_SAL_RsaFree, 0xE0E475AD }, + [APP_CALL_HILINK_SAL_RSA_PARAM_IMPORT] = { HILINK_SAL_RsaParamImport, 0xF3E3CDB4 }, + [APP_CALL_HILINK_RSA_PKCS1_VERIFY] = { HILINK_RsaPkcs1Verify, 0x9580E84E }, + [APP_CALL_HILINK_RSA_PKCS1_DECRYPT] = { HILINK_RsaPkcs1Decrypt, 0x228803A6 }, + [APP_CALL_HILINK_RSA_PKCS1_ENCRYPT] = { HILINK_RsaPkcs1Encrypt, 0x91F39D95 }, + [APP_CALL_HILINK_TLS_CLIENT_CREATE] = { HILINK_TlsClientCreate, 0x8D3F28B0 }, + [APP_CALL_HILINK_SET_TLS_CLIENT_OPTION] = { HILINK_SetTlsClientOption, 0xE4D53C67 }, + [APP_CALL_HILINK_TLS_CLIENT_CONNECT] = { HILINK_TlsClientConnect, 0x0A27B5AB }, + [APP_CALL_HILINK_TLS_CLIENT_GET_CONTEXT_FD] = { HILINK_TlsClientGetContextFd, 0x436D11F8 }, + [APP_CALL_HILINK_TLS_CLIENT_READ] = { HILINK_TlsClientRead, 0x3A8AAEB6 }, + [APP_CALL_HILINK_TLS_CLIENT_WRITE] = { HILINK_TlsClientWrite, 0x538628D3 }, + [APP_CALL_HILINK_TLS_CLIENT_IS_VALID_CERT] = { HILINK_TlsClientIsValidCert, 0x2F674C39 }, + [APP_CALL_HILINK_TLS_CLIENT_FREE_RESOURCE] = { HILINK_TlsClientFreeResource, 0x8B6CF1C2 }, + [APP_CALL_HILINK_SAL_AES_GCM_ENCRYPT] = { HILINK_SAL_AesGcmEncrypt, 0x95BAB949 }, + [APP_CALL_HILINK_SAL_AES_GCM_DECRYPT] = { HILINK_SAL_AesGcmDecrypt, 0x9E19EA99 }, + [APP_CALL_HILINK_SAL_ADD_PADDING] = { HILINK_SAL_AddPadding, 0x3B11D075 }, + [APP_CALL_HILINK_SAL_GET_PADDING] = { HILINK_SAL_GetPadding, 0x24E025EF }, + [APP_CALL_HILINK_SAL_AES_CBC_ENCRYPT] = { HILINK_SAL_AesCbcEncrypt, 0x6FF88F42 }, + [APP_CALL_HILINK_SAL_AES_CBC_DECRYPT] = { HILINK_SAL_AesCbcDecrypt, 0x331C3BE3 }, + [APP_CALL_HILINK_SAL_AES_CCM_DECRYPT] = { HILINK_SAL_AesCcmDecrypt, 0x6689468D }, + [APP_CALL_HILINK_SAL_AES_CCM_ENCRYPT] = { HILINK_SAL_AesCcmEncrypt, 0xAF74C6B8 }, + [APP_CALL_HILINK_SAL_BASE64_ENCODE] = { HILINK_SAL_Base64Encode, 0x11187E2D }, + [APP_CALL_HILINK_SAL_BASE64_DECODE] = { HILINK_SAL_Base64Decode, 0x7953251B }, + [APP_CALL_HILINK_SAL_DRBG_INIT] = { HILINK_SAL_DrbgInit, 0x9228B8A8 }, + [APP_CALL_HILINK_SAL_DRBG_DEINIT] = { HILINK_SAL_DrbgDeinit, 0xC32422F9 }, + [APP_CALL_HILINK_SAL_DRBG_RANDOM] = { HILINK_SAL_DrbgRandom, 0x7C012233 }, + [APP_CALL_HILINK_SAL_HKDF] = { HILINK_SAL_Hkdf, 0x2BB295C1 }, + [APP_CALL_HILINK_SAL_PKCS5_PBKDF2_HMAC] = { HILINK_SAL_Pkcs5Pbkdf2Hmac, 0x10F36291 }, + [APP_CALL_HILINK_SAL_MD_CALC] = { HILINK_SAL_MdCalc, 0xA845CD2F }, + [APP_CALL_HILINK_SAL_HMAC_CALC] = { HILINK_SAL_HmacCalc, 0xA2D6BC34 }, + [APP_CALL_HILINK_SAL_MD_INIT] = { HILINK_SAL_MdInit, 0xE37B7CBE }, + [APP_CALL_HILINK_SAL_MD_UPDATE] = { HILINK_SAL_MdUpdate, 0x23083067 }, + [APP_CALL_HILINK_SAL_MD_FINISH] = { HILINK_SAL_MdFinish, 0xAE8AF934 }, + [APP_CALL_HILINK_SAL_MD_FREE] = { HILINK_SAL_MdFree, 0x6DEEEFCC }, + [APP_CALL_HILINK_SAL_MPI_INIT] = { HILINK_SAL_MpiInit, 0x168D2D46 }, + [APP_CALL_HILINK_SAL_MPI_FREE] = { HILINK_SAL_MpiFree, 0x58A94AB5 }, + [APP_CALL_HILINK_SAL_MPI_EXP_MOD] = { HILINK_SAL_MpiExpMod, 0x049858C1 }, + [APP_CALL_HILINK_SAL_MPI_CMP_INT] = { HILINK_SAL_MpiCmpInt, 0x1E8BE467 }, + [APP_CALL_HILINK_SAL_MPI_SUB_INT] = { HILINK_SAL_MpiSubInt, 0x2F492DE9 }, + [APP_CALL_HILINK_SAL_MPI_CMP_MPI] = { HILINK_SAL_MpiCmpMpi, 0xB4046E4B }, + [APP_CALL_HILINK_SAL_MPI_READ_STRING] = { HILINK_SAL_MpiReadString, 0x0EEEA5E3 }, + [APP_CALL_HILINK_SAL_MPI_WRITE_STRING] = { HILINK_SAL_MpiWriteString, 0xD6FE8809 }, + [APP_CALL_HILINK_SAL_MPI_READ_BINARY] = { HILINK_SAL_MpiReadBinary, 0x743B2B61 }, + [APP_CALL_HILINK_SAL_MPI_WRITE_BINARY] = { HILINK_SAL_MpiWriteBinary, 0x11718F20 }, + [APP_CALL_HILINK_GET_LOCAL_IP] = { HILINK_GetLocalIp, 0x38742D7C }, + [APP_CALL_HILINK_GET_MAC_ADDR] = { HILINK_GetMacAddr, 0x48EE81BB }, + [APP_CALL_HILINK_GET_WI_FI_SSID] = { HILINK_GetWiFiSsid, 0xD5D48537 }, + [APP_CALL_HILINK_SET_WI_FI_INFO] = { HILINK_SetWiFiInfo, 0x3D34C708 }, + [APP_CALL_HILINK_RECONNECT_WI_FI] = { HILINK_ReconnectWiFi, 0x68622D32 }, + [APP_CALL_HILINK_CONNECT_WI_FI] = { HILINK_ConnectWiFi, 0x33179ADE }, + [APP_CALL_HILINK_GET_NETWORK_STATE] = { HILINK_GetNetworkState, 0xD3E8C502 }, + [APP_CALL_HILINK_GET_WI_FI_BSSID] = { HILINK_GetWiFiBssid, 0x6A2217F6 }, + [APP_CALL_HILINK_GET_WI_FI_RSSI] = { HILINK_GetWiFiRssi, 0x938E85AA }, + [APP_CALL_HILINK_START_SOFT_AP] = { HILINK_StartSoftAp, 0x7A6754CE }, + [APP_CALL_HILINK_STOP_SOFT_AP] = { HILINK_StopSoftAp, 0x869A8127 }, + [APP_CALL_HILINK_GET_DEV_INFO] = { HILINK_GetDevInfo, 0x656D364C }, + [APP_CALL_HILINK_GET_SVC_INFO] = { HILINK_GetSvcInfo, 0x00F05E95 }, + [APP_CALL_HILINK_GET_AUTO_AC] = { HILINK_GetAutoAc, 0xFE7738AD }, + [APP_CALL_HILINK_PUT_CHAR_STATE] = { HILINK_PutCharState, 0x05E79CAC }, + [APP_CALL_HILINK_CONTROL_CHAR_STATE] = { HILINK_ControlCharState, 0xA11368FA }, + [APP_CALL_HILINK_GET_CHAR_STATE] = { HILINK_GetCharState, 0xE6717C71 }, + [APP_CALL_HILINK_GET_PIN_CODE] = { HILINK_GetPinCode, 0xC469FC93 }, + [APP_CALL_HILINK_NOTIFY_DEV_STATUS] = { HILINK_NotifyDevStatus, 0x4FF22195 }, + [APP_CALL_HILINK_PROCESS_BEFORE_RESTART] = { HILINK_ProcessBeforeRestart, 0x3E9F7CA3 }, + [APP_CALL_REGISTE_LOG] = { registe_log, 0x01D52266 }, + [APP_CALL_GET_INSTANCE] = { get_instance, 0xEA04E818 }, + [APP_CALL_DESTROY] = { destroy, 0x4A6D5AF6 }, + [APP_CALL_SET_CONTEXT] = { set_context, 0x6621F901 }, + [APP_CALL_RECEIVE_DATA] = { receive_data, 0x39D0642D }, + [APP_CALL_RECEIVE_DATA_WITH_JSON_OBJECT] = { receive_data_with_json_object, 0x0350FA3F }, + [APP_CALL_INIT_CENTER] = { init_center, 0x28ED49CF }, + [APP_CALL_START_PAKE] = { start_pake, 0x23AC20D0 }, + [APP_CALL_AUTHENTICATE_PEER] = { authenticate_peer, 0x3710992F }, + [APP_CALL_DELETE_LOCAL_AUTH_INFO] = { delete_local_auth_info, 0xBE7E3DBC }, + [APP_CALL_IMPORT_AUTH_INFO] = { import_auth_info, 0xEBD73738 }, + [APP_CALL_ADD_AUTH_INFO] = { add_auth_info, 0x5AE906D8 }, + [APP_CALL_REMOVE_AUTH_INFO] = { remove_auth_info, 0xD885A611 }, + [APP_CALL_IS_TRUST_PEER] = { is_trust_peer, 0x8F2416A4 }, + [APP_CALL_LIST_TRUST_PEERS] = { list_trust_peers, 0x5FFA93EC }, + [APP_CALL_SET_SELF_AUTH_ID] = { set_self_auth_id, 0x3483EDAD }, + [APP_CALL_GET_LOCAL_ADDRESS] = { GetLocalAddress, 0xE5864419 }, + [APP_CALL_GET_LOCAL_NAME] = { GetLocalName, 0xC4516893 }, + [APP_CALL_SET_LOCAL_NAME] = { SetLocalName, 0x82274A6D }, + [APP_CALL_BLUETOOTH_FACTORY_RESET] = { BluetoothFactoryReset, 0xEC6FD673 }, + [APP_CALL_GET_BT_SCAN_MODE] = { GetBtScanMode, 0x4D397519 }, + [APP_CALL_SET_BT_SCAN_MODE] = { SetBtScanMode, 0x9C9FFB56 }, + [APP_CALL_READ_BT_MAC_ADDR] = { ReadBtMacAddr, 0x1202FEAB }, + [APP_CALL_GET_PARIED_DEVICES_NUM] = { GetPariedDevicesNum, 0x34F195D5 }, + [APP_CALL_GET_PAIR_STATE] = { GetPairState, 0x95E791C4 }, + [APP_CALL_REMOVE_PAIR] = { RemovePair, 0x3315669E }, + [APP_CALL_REMOVE_ALL_PAIRS] = { RemoveAllPairs, 0x430FB9E7 }, + [APP_CALL_READ_REMOTE_RSSI_VALUE] = { ReadRemoteRssiValue, 0x288EF87B }, + [APP_CALL_IS_ACL_CONNECTED] = { IsAclConnected, 0xC4498A4D }, + [APP_CALL_DISCONNECT_REMOTE_DEVICE] = { DisconnectRemoteDevice, 0xF1A93918 }, + [APP_CALL_CONNECT_REMOTE_DEVICE] = { ConnectRemoteDevice, 0xFA7C7805 }, + [APP_CALL_INIT_BT_STACK] = { InitBtStack, 0xF7131CCF }, + [APP_CALL_ENABLE_BT_STACK] = { EnableBtStack, 0x092F762F }, + [APP_CALL_DISABLE_BT_STACK] = { DisableBtStack, 0x28C0A502 }, + [APP_CALL_SET_DEVICE_NAME] = { SetDeviceName, 0xEC955661 }, + [APP_CALL_BLE_SET_ADV_DATA] = { BleSetAdvData, 0xD19C624C }, + [APP_CALL_BLE_START_ADV] = { BleStartAdv, 0xD0B61E88 }, + [APP_CALL_BLE_STOP_ADV] = { BleStopAdv, 0xF81F9D57 }, + [APP_CALL_BLE_UPDATE_ADV] = { BleUpdateAdv, 0x108A971D }, + [APP_CALL_BLE_SET_SECURITY_IO_CAP] = { BleSetSecurityIoCap, 0x268273CE }, + [APP_CALL_BLE_SET_SECURITY_AUTH_REQ] = { BleSetSecurityAuthReq, 0xABEE8013 }, + [APP_CALL_BLE_GATT_SECURITY_RSP] = { BleGattSecurityRsp, 0xFF69661C }, + [APP_CALL_BLE_SCAN_FILTER_PARAM_SETUP] = { BleScanFilterParamSetup, 0x1A29BBD9 }, + [APP_CALL_BLE_SCAN_FILTER_ADD_REMOVE] = { BleScanFilterAddRemove, 0x95111C6A }, + [APP_CALL_BLE_SCAN_FILTER_CLEAR] = { BleScanFilterClear, 0x64314013 }, + [APP_CALL_BLE_SCAN_FILTER_ENABLE] = { BleScanFilterEnable, 0xFBA647F7 }, + [APP_CALL_BLE_SET_SCAN_PARAMETERS] = { BleSetScanParameters, 0x7B736AE8 }, + [APP_CALL_BLE_START_SCAN] = { BleStartScan, 0xE330F3D7 }, + [APP_CALL_BLE_STOP_SCAN] = { BleStopScan, 0x157E6C37 }, + [APP_CALL_BLE_GATT_REGISTER_CALLBACKS] = { BleGattRegisterCallbacks, 0x74AFBCC3 }, + [APP_CALL_BLE_START_ADV_EX] = { BleStartAdvEx, 0x8D643C71 }, + [APP_CALL_BLE_GATTS_REGISTER] = { BleGattsRegister, 0x08363127 }, + [APP_CALL_BLE_GATTS_UN_REGISTER] = { BleGattsUnRegister, 0xCB03B902 }, + [APP_CALL_BLE_GATTS_DISCONNECT] = { BleGattsDisconnect, 0xC6D32C20 }, + [APP_CALL_BLE_GATTS_ADD_SERVICE] = { BleGattsAddService, 0x2A73EE70 }, + [APP_CALL_BLE_GATTS_ADD_CHARACTERISTIC] = { BleGattsAddCharacteristic, 0x99A65902 }, + [APP_CALL_BLE_GATTS_ADD_DESCRIPTOR] = { BleGattsAddDescriptor, 0xA14959BA }, + [APP_CALL_BLE_GATTS_START_SERVICE] = { BleGattsStartService, 0x60D70D05 }, + [APP_CALL_BLE_GATTS_STOP_SERVICE] = { BleGattsStopService, 0x5A89A6C3 }, + [APP_CALL_BLE_GATTS_DELETE_SERVICE] = { BleGattsDeleteService, 0xE489489F }, + [APP_CALL_BLE_GATTS_CLEAR_SERVICES] = { BleGattsClearServices, 0x355E418A }, + [APP_CALL_BLE_GATTS_SEND_RESPONSE] = { BleGattsSendResponse, 0x02EF8A54 }, + [APP_CALL_BLE_GATTS_SEND_INDICATION] = { BleGattsSendIndication, 0x3D8DF826 }, + [APP_CALL_BLE_GATTS_SET_ENCRYPTION] = { BleGattsSetEncryption, 0xC59AD8FA }, + [APP_CALL_BLE_GATTS_REGISTER_CALLBACKS] = { BleGattsRegisterCallbacks, 0xBD1564AF }, + [APP_CALL_BLE_GATTS_START_SERVICE_EX] = { BleGattsStartServiceEx, 0x4FEE6224 }, + [APP_CALL_BLE_GATTS_STOP_SERVICE_EX] = { BleGattsStopServiceEx, 0xFCA67974 }, + [APP_CALL_HILINK_GET_DEVICE_SN] = { HILINK_GetDeviceSn, 0xF6F63E17 }, + [APP_CALL_HILINK_GET_SUB_PROD_ID] = { HILINK_GetSubProdId, 0xD3036A50 }, + [APP_CALL_HILINK_BT_GET_DEV_SURFACE_POWER] = { HILINK_BT_GetDevSurfacePower, 0x120E5449 }, + [APP_CALL_HILINK_BT_GET_DEV_INFO] = { HILINK_BT_GetDevInfo, 0x669A4D79 }, + [APP_CALL_HILINK_GET_CUSTOM_INFO] = { HILINK_GetCustomInfo, 0x2E919F88 }, + [APP_CALL_HILINK_GET_MANU_ID] = { HILINK_GetManuId, 0xC4BBEEC6 }, + [APP_CALL_HILINK_BT_GET_MAC_ADDR] = { HILINK_BT_GetMacAddr, 0x4E542216 }, + [APP_CALL_GET_DEVICE_VERSION] = { getDeviceVersion, 0xD35ED1DE }, + [APP_CALL_OS_KERNEL_GET_TICK_COUNT] = { osKernelGetTickCount, 0x5A21434F }, + [APP_CALL_OS_KERNEL_GET_TICK_FREQ] = { osKernelGetTickFreq, 0xC521776D }, + [APP_CALL_OS_DELAY] = { osDelay, 0x37F5C502 }, + [APP_CALL_OS_THREAD_NEW] = { osThreadNew, 0x57B639AA }, + [APP_CALL_OS_THREAD_TERMINATE] = { osThreadTerminate, 0x3F47D1CC }, + [APP_CALL_OS_THREAD_GET_ID] = { osThreadGetId, 0x1888A199 }, + [APP_CALL_OS_MUTEX_NEW] = { osMutexNew, 0x61CD6F5D }, + [APP_CALL_OS_MUTEX_DELETE] = { osMutexDelete, 0x7C9BEF30 }, + [APP_CALL_OS_MUTEX_ACQUIRE] = { osMutexAcquire, 0xD5EACE78 }, + [APP_CALL_OS_MUTEX_RELEASE] = { osMutexRelease, 0x5DB24268 }, + [APP_CALL_OS_SEMAPHORE_NEW] = { osSemaphoreNew, 0xE3605815 }, + [APP_CALL_OS_SEMAPHORE_ACQUIRE] = { osSemaphoreAcquire, 0x33F98458 }, + [APP_CALL_OS_SEMAPHORE_RELEASE] = { osSemaphoreRelease, 0x376DD1E7 }, + [APP_CALL_OS_SEMAPHORE_DELETE] = { osSemaphoreDelete, 0x70BF3612 }, + [APP_CALL_OS_THREAD_SUSPEND] = { osThreadSuspend, 0xB6D1F9C6 }, + [APP_CALL_OS_THREAD_RESUME] = { osThreadResume, 0x2395F48B }, + [APP_CALL_MALLOC] = { malloc, 0xEDE23AE1 }, + [APP_CALL_FREE] = { free, 0x514E24C7 }, + [APP_CALL_SLE_DISCONNECT_REMOTE_DEVICE] = { SleDisconnectRemoteDevice, 0x9360CE44 }, + [APP_CALL_SLE_CONNECTION_REGISTER_CALLBACKS] = { SleConnectionRegisterCallbacks, 0x291140AF }, + [APP_CALL_ENABLE_SLE] = { EnableSle, 0xEC557650 }, + [APP_CALL_DISABLE_SLE] = { DisableSle, 0x3E6EBBC1 }, + [APP_CALL_SLE_GET_LOCAL_ADDR] = { SleGetLocalAddr, 0xD453DC9E }, + [APP_CALL_SLE_SET_LOCAL_NAME] = { SleSetLocalName, 0xD772F6AA }, + [APP_CALL_SLE_SET_ANNOUNCE_DATA] = { SleSetAnnounceData, 0x506112D2 }, + [APP_CALL_SLE_SET_ANNOUNCE_PARAM] = { SleSetAnnounceParam, 0x6C5B806E }, + [APP_CALL_SLE_START_ANNOUNCE] = { SleStartAnnounce, 0xC4E0EAEC }, + [APP_CALL_SLE_STOP_ANNOUNCE] = { SleStopAnnounce, 0x6A98F6F1 }, + [APP_CALL_SLE_ANNOUNCE_SEEK_REGISTER_CALLBACKS] = { SleAnnounceSeekRegisterCallbacks, 0x683AC864 }, + [APP_CALL_SSAPS_REGISTER_SERVER] = { ssapsRegisterServer, 0x94FA565B }, + [APP_CALL_SSAPS_ADD_SERVICE_SYNC] = { SsapsAddServiceSync, 0x7CE2A054 }, + [APP_CALL_SSAPS_ADD_PROPERTY_SYNC] = { SsapsAddPropertySync, 0x0F45AC6A }, + [APP_CALL_SSAPS_ADD_DESCRIPTOR_SYNC] = { SsapsAddDescriptorSync, 0x8A556CDE }, + [APP_CALL_SSAPS_START_SERVICE] = { SsapsStartService, 0xE96B315E }, + [APP_CALL_SSAPS_DELETE_ALL_SERVICES] = { SsapsDeleteAllServices, 0xF45ED456 }, + [APP_CALL_SSAPS_SEND_RESPONSE] = { SsapsSendResponse, 0xEF46F1E5 }, + [APP_CALL_SSAPS_NOTIFY_INDICATE] = { SsapsNotifyIndicate, 0xC234ABF9 }, + [APP_CALL_SSAPS_REGISTER_CALLBACKS] = { SsapsRegisterCallbacks, 0x2B121CCE }, + [APP_CALL_C_JSON_VERSION] = { cJSON_Version, 0x688D2163 }, + [APP_CALL_C_JSON_INIT_HOOKS] = { cJSON_InitHooks, 0xBDF57FB6 }, + [APP_CALL_C_JSON_PARSE] = { cJSON_Parse, 0x098B4742 }, + [APP_CALL_C_JSON_PARSE_WITH_LENGTH] = { cJSON_ParseWithLength, 0xFBC504AC }, + [APP_CALL_C_JSON_PARSE_WITH_OPTS] = { cJSON_ParseWithOpts, 0x5E03230A }, + [APP_CALL_C_JSON_PARSE_WITH_LENGTH_OPTS] = { cJSON_ParseWithLengthOpts, 0xDF90428D }, + [APP_CALL_C_JSON_PRINT] = { cJSON_Print, 0x53F024F9 }, + [APP_CALL_C_JSON_PRINT_UNFORMATTED] = { cJSON_PrintUnformatted, 0xC20964CA }, + [APP_CALL_C_JSON_PRINT_BUFFERED] = { cJSON_PrintBuffered, 0x8AEA8A90 }, + [APP_CALL_C_JSON_PRINT_PREALLOCATED] = { cJSON_PrintPreallocated, 0x42D1CEF0 }, + [APP_CALL_C_JSON_DELETE] = { cJSON_Delete, 0xA2BA9C88 }, + [APP_CALL_C_JSON_GET_ARRAY_SIZE] = { cJSON_GetArraySize, 0xA011C100 }, + [APP_CALL_C_JSON_GET_ARRAY_ITEM] = { cJSON_GetArrayItem, 0x4A9B8F7F }, + [APP_CALL_C_JSON_GET_OBJECT_ITEM] = { cJSON_GetObjectItem, 0x9EBEDA36 }, + [APP_CALL_C_JSON_GET_OBJECT_ITEM_CASE_SENSITIVE] = { cJSON_GetObjectItemCaseSensitive, 0x5056947E }, + [APP_CALL_C_JSON_HAS_OBJECT_ITEM] = { cJSON_HasObjectItem, 0x9426D868 }, + [APP_CALL_C_JSON_GET_ERROR_PTR] = { cJSON_GetErrorPtr, 0x829904D7 }, + [APP_CALL_C_JSON_GET_STRING_VALUE] = { cJSON_GetStringValue, 0x0DA74B72 }, + [APP_CALL_C_JSON_GET_NUMBER_VALUE] = { cJSON_GetNumberValue, 0x76D93829 }, + [APP_CALL_C_JSON_IS_INVALID] = { cJSON_IsInvalid, 0xD151333F }, + [APP_CALL_C_JSON_IS_FALSE] = { cJSON_IsFalse, 0x3506E830 }, + [APP_CALL_C_JSON_IS_TRUE] = { cJSON_IsTrue, 0x32A8CF68 }, + [APP_CALL_C_JSON_IS_BOOL] = { cJSON_IsBool, 0x630BD5D0 }, + [APP_CALL_C_JSON_IS_NULL] = { cJSON_IsNull, 0xA39237FD }, + [APP_CALL_C_JSON_IS_NUMBER] = { cJSON_IsNumber, 0xF0BADD13 }, + [APP_CALL_C_JSON_IS_STRING] = { cJSON_IsString, 0x1AB77B60 }, + [APP_CALL_C_JSON_IS_ARRAY] = { cJSON_IsArray, 0x92987F07 }, + [APP_CALL_C_JSON_IS_OBJECT] = { cJSON_IsObject, 0x13958808 }, + [APP_CALL_C_JSON_IS_RAW] = { cJSON_IsRaw, 0x1D140EB2 }, + [APP_CALL_C_JSON_CREATE_NULL] = { cJSON_CreateNull, 0xA0CA25BF }, + [APP_CALL_C_JSON_CREATE_TRUE] = { cJSON_CreateTrue, 0x9267FBC8 }, + [APP_CALL_C_JSON_CREATE_FALSE] = { cJSON_CreateFalse, 0x09457528 }, + [APP_CALL_C_JSON_CREATE_BOOL] = { cJSON_CreateBool, 0xA7C5DFA1 }, + [APP_CALL_C_JSON_CREATE_NUMBER] = { cJSON_CreateNumber, 0x729552A8 }, + [APP_CALL_C_JSON_CREATE_STRING] = { cJSON_CreateString, 0xD76B3362 }, + [APP_CALL_C_JSON_CREATE_RAW] = { cJSON_CreateRaw, 0xB9915E84 }, + [APP_CALL_C_JSON_CREATE_ARRAY] = { cJSON_CreateArray, 0x795CD770 }, + [APP_CALL_C_JSON_CREATE_OBJECT] = { cJSON_CreateObject, 0xEB84A3AE }, + [APP_CALL_C_JSON_CREATE_STRING_REFERENCE] = { cJSON_CreateStringReference, 0x73DE78F0 }, + [APP_CALL_C_JSON_CREATE_OBJECT_REFERENCE] = { cJSON_CreateObjectReference, 0x4D37E8FC }, + [APP_CALL_C_JSON_CREATE_ARRAY_REFERENCE] = { cJSON_CreateArrayReference, 0x2F53E2F7 }, + [APP_CALL_C_JSON_CREATE_INT_ARRAY] = { cJSON_CreateIntArray, 0x2853D57F }, + [APP_CALL_C_JSON_CREATE_FLOAT_ARRAY] = { cJSON_CreateFloatArray, 0x170FC255 }, + [APP_CALL_C_JSON_CREATE_DOUBLE_ARRAY] = { cJSON_CreateDoubleArray, 0x1F7CBBB9 }, + [APP_CALL_C_JSON_CREATE_STRING_ARRAY] = { cJSON_CreateStringArray, 0xB63D119A }, + [APP_CALL_C_JSON_ADD_ITEM_TO_ARRAY] = { cJSON_AddItemToArray, 0xC4775120 }, + [APP_CALL_C_JSON_ADD_ITEM_TO_OBJECT] = { cJSON_AddItemToObject, 0x418F3865 }, + [APP_CALL_C_JSON_ADD_ITEM_TO_OBJECT_CS] = { cJSON_AddItemToObjectCS, 0x792FEFAA }, + [APP_CALL_C_JSON_ADD_ITEM_REFERENCE_TO_ARRAY] = { cJSON_AddItemReferenceToArray, 0xFF69038B }, + [APP_CALL_C_JSON_ADD_ITEM_REFERENCE_TO_OBJECT] = { cJSON_AddItemReferenceToObject, 0xFD3AA3C2 }, + [APP_CALL_C_JSON_DETACH_ITEM_VIA_POINTER] = { cJSON_DetachItemViaPointer, 0xC476B26D }, + [APP_CALL_C_JSON_DETACH_ITEM_FROM_ARRAY] = { cJSON_DetachItemFromArray, 0xFB2B48F3 }, + [APP_CALL_C_JSON_DELETE_ITEM_FROM_ARRAY] = { cJSON_DeleteItemFromArray, 0xB3904203 }, + [APP_CALL_C_JSON_DETACH_ITEM_FROM_OBJECT] = { cJSON_DetachItemFromObject, 0xC394782F }, + [APP_CALL_C_JSON_DETACH_ITEM_FROM_OBJECT_CASE_SENSITIVE] = { cJSON_DetachItemFromObjectCaseSensitive, 0xE1C40F71 }, + [APP_CALL_C_JSON_DELETE_ITEM_FROM_OBJECT] = { cJSON_DeleteItemFromObject, 0x8001C315 }, + [APP_CALL_C_JSON_DELETE_ITEM_FROM_OBJECT_CASE_SENSITIVE] = { cJSON_DeleteItemFromObjectCaseSensitive, 0x04539827 }, + [APP_CALL_C_JSON_INSERT_ITEM_IN_ARRAY] = { cJSON_InsertItemInArray, 0xDDC80900 }, + [APP_CALL_C_JSON_REPLACE_ITEM_VIA_POINTER] = { cJSON_ReplaceItemViaPointer, 0x966524DC }, + [APP_CALL_C_JSON_REPLACE_ITEM_IN_ARRAY] = { cJSON_ReplaceItemInArray, 0xE965006F }, + [APP_CALL_C_JSON_REPLACE_ITEM_IN_OBJECT] = { cJSON_ReplaceItemInObject, 0x86EBDA9C }, + [APP_CALL_C_JSON_REPLACE_ITEM_IN_OBJECT_CASE_SENSITIVE] = { cJSON_ReplaceItemInObjectCaseSensitive, 0x46226BC1 }, + [APP_CALL_C_JSON_DUPLICATE] = { cJSON_Duplicate, 0xDA2387E2 }, + [APP_CALL_C_JSON_COMPARE] = { cJSON_Compare, 0xAE9565DF }, + [APP_CALL_C_JSON_MINIFY] = { cJSON_Minify, 0xEE621F0D }, + [APP_CALL_C_JSON_ADD_NULL_TO_OBJECT] = { cJSON_AddNullToObject, 0xA9362983 }, + [APP_CALL_C_JSON_ADD_TRUE_TO_OBJECT] = { cJSON_AddTrueToObject, 0x71D1AD83 }, + [APP_CALL_C_JSON_ADD_FALSE_TO_OBJECT] = { cJSON_AddFalseToObject, 0x860B4E60 }, + [APP_CALL_C_JSON_ADD_BOOL_TO_OBJECT] = { cJSON_AddBoolToObject, 0x7BB473E4 }, + [APP_CALL_C_JSON_ADD_NUMBER_TO_OBJECT] = { cJSON_AddNumberToObject, 0x103ADF87 }, + [APP_CALL_C_JSON_ADD_STRING_TO_OBJECT] = { cJSON_AddStringToObject, 0x2D1A3CA9 }, + [APP_CALL_C_JSON_ADD_RAW_TO_OBJECT] = { cJSON_AddRawToObject, 0xEB171CF7 }, + [APP_CALL_C_JSON_ADD_OBJECT_TO_OBJECT] = { cJSON_AddObjectToObject, 0x3077B4AF }, + [APP_CALL_C_JSON_ADD_ARRAY_TO_OBJECT] = { cJSON_AddArrayToObject, 0xC2D7FC37 }, + [APP_CALL_C_JSON_SET_NUMBER_HELPER] = { cJSON_SetNumberHelper, 0x37FAE533 }, + [APP_CALL_C_JSON_SET_VALUESTRING] = { cJSON_SetValuestring, 0x7290D811 }, + [APP_CALL_C_JSON_MALLOC] = { cJSON_malloc, 0x6CE0826F }, + [APP_CALL_C_JSON_FREE] = { cJSON_free, 0x347C6215 }, + [APP_CALL_MBEDTLS_MD_INFO_FROM_TYPE] = { mbedtls_md_info_from_type, 0x02BA313E }, + [APP_CALL_MBEDTLS_CTR_DRBG_INIT] = { mbedtls_ctr_drbg_init, 0xEF20F1F6 }, + [APP_CALL_MBEDTLS_MPI_INIT] = { mbedtls_mpi_init, 0x7D00A7EB }, + [APP_CALL_MBEDTLS_ECDH_INIT] = { mbedtls_ecdh_init, 0x1BB555DE }, + [APP_CALL_MBEDTLS_CTR_DRBG_RANDOM] = { mbedtls_ctr_drbg_random, 0x7B0FCDD0 }, + [APP_CALL_MBEDTLS_MPI_READ_BINARY] = { mbedtls_mpi_read_binary, 0x5C747D76 }, + [APP_CALL_MBEDTLS_MPI_SUB_MPI] = { mbedtls_mpi_sub_mpi, 0x15136B35 }, + [APP_CALL_MBEDTLS_HKDF] = { mbedtls_hkdf, 0x079DA4BF }, + [APP_CALL_MBEDTLS_MD_GET_SIZE] = { mbedtls_md_get_size, 0x9A6EED5F }, + [APP_CALL_MBEDTLS_ENTROPY_INIT] = { mbedtls_entropy_init, 0x0C5448B8 }, + [APP_CALL_MBEDTLS_MPI_CMP_MPI] = { mbedtls_mpi_cmp_mpi, 0x364FB034 }, + [APP_CALL_MBEDTLS_ECDH_COMPUTE_SHARED] = { mbedtls_ecdh_compute_shared, 0x76275BD8 }, + [APP_CALL_MBEDTLS_MPI_EXP_MOD] = { mbedtls_mpi_exp_mod, 0x23C8C7F3 }, + [APP_CALL_MBEDTLS_MPI_MOD_MPI] = { mbedtls_mpi_mod_mpi, 0xCBCC1D0B }, + [APP_CALL_MBEDTLS_SHA256] = { mbedtls_sha256, 0xD41C5B49 }, + [APP_CALL_MBEDTLS_MPI_FREE] = { mbedtls_mpi_free, 0x538D65C0 }, + [APP_CALL_MBEDTLS_MPI_WRITE_BINARY] = { mbedtls_mpi_write_binary, 0x0C85F9C8 }, + [APP_CALL_MBEDTLS_MPI_MUL_MPI] = { mbedtls_mpi_mul_mpi, 0xD50201ED }, + [APP_CALL_MBEDTLS_MPI_ADD_MPI] = { mbedtls_mpi_add_mpi, 0xA6266D7A }, + [APP_CALL_MBEDTLS_ENTROPY_FUNC] = { mbedtls_entropy_func, 0x2A375141 }, + [APP_CALL_MBEDTLS_ECDH_FREE] = { mbedtls_ecdh_free, 0xF7F5E69E }, + [APP_CALL_MBEDTLS_MPI_INV_MOD] = { mbedtls_mpi_inv_mod, 0x1AD06932 }, + [APP_CALL_MBEDTLS_CTR_DRBG_SEED] = { mbedtls_ctr_drbg_seed, 0xC3A6C044 }, + [APP_CALL_MBEDTLS_CTR_DRBG_FREE] = { mbedtls_ctr_drbg_free, 0xEAE908D4 }, + [APP_CALL_MBEDTLS_MPI_COPY] = { mbedtls_mpi_copy, 0x3657EA22 }, + [APP_CALL_MBEDTLS_ENTROPY_FREE] = { mbedtls_entropy_free, 0xC5FA797F }, + [APP_CALL_MBEDTLS_ECP_GROUP_LOAD] = { mbedtls_ecp_group_load, 0xE8D04592 }, + [APP_CALL_MBEDTLS_MPI_SAFE_COND_SWAP] = { mbedtls_mpi_safe_cond_swap, 0x541477B3 }, + [APP_CALL_MBEDTLS_MPI_LSET] = { mbedtls_mpi_lset, 0x62753A05 }, +}; + +const struct mapping_tbl *get_app_mapping_tbl(void) +{ + return g_app_call_tbl; +} + +unsigned int get_app_mapping_tbl_size(void) +{ + return APP_CALL_MAX; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_function_mapping.h b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_function_mapping.h new file mode 100755 index 0000000..56d983c --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/app_function_mapping.h @@ -0,0 +1,23 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: app function mapping. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#ifndef APP_FUNCTION_MAPPING_H +#define APP_FUNCTION_MAPPING_H + +#ifdef __cplusplus +extern "C" { +#endif + +const struct mapping_tbl *get_app_mapping_tbl(void); +unsigned int get_app_mapping_tbl_size(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/hilink_call.h b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/hilink_call.h new file mode 100755 index 0000000..a91c876 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/hilink_call.h @@ -0,0 +1,123 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: hilink function mapping \n + * + * History: \n + * 2024-01-27, Create file. \n + */ +#ifndef HILINK_CALL_H +#define HILINK_CALL_H + +#include "func_call_list.h" +#include "app_call_entry.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0L +#else +#define NULL ((void*)0) +#endif +#endif + +#define hilink_call0(idx, nr, t) do { \ + void *call_addr = get_hilink_api_addr(idx, #t#nr"()"); \ + if (call_addr != NULL) { \ + return ((t (*)(void))call_addr)(); \ + } \ +} while (0) +#define hilink_call1(idx, nr, t, t1, p1) do { \ + void *call_addr = get_hilink_api_addr(idx, #t#nr"("#t1")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1))call_addr)(p1); \ + } \ +} while (0) +#define hilink_call2(idx, nr, t, t1, p1, t2, p2) do { \ + void *call_addr = get_hilink_api_addr(idx, #t#nr"("#t1","#t2")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2))call_addr)(p1, p2); \ + } \ +} while (0) +#define hilink_call3(idx, nr, t, t1, p1, t2, p2, t3, p3) do { \ + void *call_addr = get_hilink_api_addr(idx, #t#nr"("#t1","#t2","#t3")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2, t3))call_addr)(p1, p2, p3); \ + } \ +} while (0) +#define hilink_call4(idx, nr, t, t1, p1, t2, p2, t3, p3, t4, p4) do { \ + void *call_addr = get_hilink_api_addr(idx, #t#nr"("#t1","#t2","#t3","#t4")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2, t3, t4))call_addr)(p1, p2, p3, p4); \ + } \ +} while (0) +#define hilink_call5(idx, nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) do { \ + void *call_addr = get_hilink_api_addr(idx, #t#nr"("#t1","#t2","#t3","#t4","#t5")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2, t3, t4, t5))call_addr)(p1, p2, p3, p4, p5); \ + } \ +} while (0) +#define hilink_call6(idx, nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) do { \ + void *call_addr = get_hilink_api_addr(idx, #t#nr"("#t1","#t2","#t3","#t4","#t5","#t6")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2, t3, t4, t5, t6))call_addr)(p1, p2, p3, p4, p5, p6); \ + } \ +} while (0) + +#define hilink_call0_ret_void(idx, nr) do { \ + void *call_addr = get_hilink_api_addr(idx, "void"#nr"()"); \ + if (call_addr != NULL) { \ + ((void (*)(void))call_addr)(); \ + return; \ + } \ +} while (0) +#define hilink_call1_ret_void(idx, nr, t1, p1) do { \ + void *call_addr = get_hilink_api_addr(idx, "void"#nr"("#t1")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1))call_addr)(p1); \ + return; \ + } \ +} while (0) +#define hilink_call2_ret_void(idx, nr, t1, p1, t2, p2) do { \ + void *call_addr = get_hilink_api_addr(idx, "void"#nr"("#t1","#t2")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2))call_addr)(p1, p2); \ + return; \ + } \ +} while (0) +#define hilink_call3_ret_void(idx, nr, t1, p1, t2, p2, t3, p3) do { \ + void *call_addr = get_hilink_api_addr(idx, "void"#nr"("#t1","#t2","#t3")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2, t3))call_addr)(p1, p2, p3); \ + return; \ + } \ +} while (0) +#define hilink_call4_ret_void(idx, nr, t1, p1, t2, p2, t3, p3, t4, p4) do { \ + void *call_addr = get_hilink_api_addr(idx, "void"#nr"("#t1","#t2","#t3","#t4")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2, t3, t4))call_addr)(p1, p2, p3, p4); \ + return; \ + } \ +} while (0) +#define hilink_call5_ret_void(idx, nr, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) do { \ + void *call_addr = get_hilink_api_addr(idx, "void"#nr"("#t1","#t2","#t3","#t4","#t5")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2, t3, t4, t5))call_addr)(p1, p2, p3, p4, p5); \ + return; \ + } \ +} while (0) +#define hilink_call6_ret_void(idx, nr, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) do { \ + void *call_addr = get_hilink_api_addr(idx, "void"#nr"("#t1","#t2","#t3","#t4","#t5","#t6")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2, t3, t4, t5, t6))call_addr)(p1, p2, p3, p4, p5, p6); \ + return; \ + } \ +} while (0) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_ble_cfg_net_api.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_ble_cfg_net_api.c new file mode 100755 index 0000000..4592ea2 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_ble_cfg_net_api.c @@ -0,0 +1,93 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: ble cfg net api \n + * + * History: \n + * 2024-01-27, Create file. \n + */ +#include "hilink_call.h" +#include "ble_cfg_net_api.h" + +int BLE_CfgNetInit(const BLE_InitPara *para, const BLE_CfgNetCb *callback) +{ + hilink_call2(HILINK_CALL_BLE_CFG_NET_INIT, BLE_CfgNetInit, int, + const BLE_InitPara *, para, const BLE_CfgNetCb *, callback); + return 0; +} + +int BLE_CfgNetDeInit(const BLE_GattHandleList *handleList, unsigned int flag) +{ + hilink_call2(HILINK_CALL_BLE_CFG_NET_DE_INIT, BLE_CfgNetDeInit, int, + const BLE_GattHandleList *, handleList, unsigned int, flag); + return 0; +} + +int BLE_CfgNetAdvCtrl(unsigned int advSecond) +{ + hilink_call1(HILINK_CALL_BLE_CFG_NET_ADV_CTRL, BLE_CfgNetAdvCtrl, int, unsigned int, advSecond); + return 0; +} + +int BLE_CfgNetAdvUpdate(const BLE_AdvInfo *advInfo) +{ + hilink_call1(HILINK_CALL_BLE_CFG_NET_ADV_UPDATE, BLE_CfgNetAdvUpdate, int, const BLE_AdvInfo *, advInfo); + return 0; +} + +int BLE_CfgNetDisConnect(void) +{ + hilink_call0(HILINK_CALL_BLE_CFG_NET_DIS_CONNECT, BLE_CfgNetDisConnect, int); + return 0; +} + +int BLE_SendCustomData(BLE_DataType dataType, const unsigned char *buff, unsigned int len) +{ + hilink_call3(HILINK_CALL_BLE_SEND_CUSTOM_DATA, BLE_SendCustomData, int, + BLE_DataType, dataType, const unsigned char *, buff, unsigned int, len); + return 0; +} + +int BLE_GetAdvType(void) +{ + hilink_call0(HILINK_CALL_BLE_GET_ADV_TYPE, BLE_GetAdvType, int); + return 0; +} + +void BLE_SetAdvType(int type) +{ + hilink_call1_ret_void(HILINK_CALL_BLE_SET_ADV_TYPE, BLE_SetAdvType, int, type); +} + +int BLE_SetAdvNameMpp(const unsigned char *mpp, unsigned int len) +{ + hilink_call2(HILINK_CALL_BLE_SET_ADV_NAME_MPP, BLE_SetAdvNameMpp, int, + const unsigned char *, mpp, unsigned int, len); + return 0; +} + +int BLE_NearDiscoveryInit(const BLE_NearDiscoveryCb *cb) +{ + hilink_call1(HILINK_CALL_BLE_NEAR_DISCOVERY_INIT, BLE_NearDiscoveryInit, int, const BLE_NearDiscoveryCb *, cb); + return 0; +} + +int BLE_NearDiscoveryEnable(unsigned long waitTime) +{ + hilink_call1(HILINK_CALL_BLE_NEAR_DISCOVERY_ENABLE, BLE_NearDiscoveryEnable, int, unsigned long, waitTime); + return 0; +} + +int HILINK_BT_GetTaskStackSize(const char *name, unsigned long *stackSize) +{ + hilink_call2(HILINK_CALL_HILINK_BT_GET_TASK_STACK_SIZE, HILINK_BT_GetTaskStackSize, int, + const char *, name, unsigned long *, stackSize); + return 0; +} + +int HILINK_BT_SetTaskStackSize(const char *name, unsigned long stackSize) +{ + hilink_call2(HILINK_CALL_HILINK_BT_SET_TASK_STACK_SIZE, HILINK_BT_SetTaskStackSize, int, + const char *, name, unsigned long, stackSize); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink.c new file mode 100755 index 0000000..476b403 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink.c @@ -0,0 +1,163 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: HiLink function adaption \n + * + * History: \n + * 2024-01-27, Create file. \n + */ +#include "hilink_call.h" +#include "hilink.h" + +int HILINK_RegisterBaseCallback(const HiLinkBaseCallback *cb, unsigned int cbSize) +{ + hilink_call2(HILINK_CALL_HILINK_REGISTER_BASE_CALLBACK, HILINK_RegisterBaseCallback, int, + const HiLinkBaseCallback *, cb, unsigned int, cbSize); + return 0; +} + +int HILINK_Main(void) +{ + hilink_call0(HILINK_CALL_HILINK_MAIN, HILINK_Main, int); + return 0; +} + +void HILINK_Reset(void) +{ + hilink_call0_ret_void(HILINK_CALL_HILINK_RESET, HILINK_Reset); +} + +int HILINK_SetSdkAttr(HILINK_SdkAttr sdkAttr) +{ + hilink_call1(HILINK_CALL_HILINK_SET_SDK_ATTR, HILINK_SetSdkAttr, int, HILINK_SdkAttr, sdkAttr); + return 0; +} + +HILINK_SdkAttr *HILINK_GetSdkAttr(void) +{ + hilink_call0(HILINK_CALL_HILINK_GET_SDK_ATTR, HILINK_GetSdkAttr, HILINK_SdkAttr *); + return NULL; +} + +int HILINK_RestoreFactorySettings(void) +{ + hilink_call0(HILINK_CALL_HILINK_RESTORE_FACTORY_SETTINGS, HILINK_RestoreFactorySettings, int); + return 0; +} + +int HILINK_GetDevStatus(void) +{ + hilink_call0(HILINK_CALL_HILINK_GET_DEV_STATUS, HILINK_GetDevStatus, int); + return 0; +} + +const char *HILINK_GetSdkVersion(void) +{ + hilink_call0(HILINK_CALL_HILINK_GET_SDK_VERSION, HILINK_GetSdkVersion, const char *); + return NULL; +} + +int HILINK_ReportCharState(const char *svcId, const char *payload, unsigned int len) +{ + hilink_call3(HILINK_CALL_HILINK_REPORT_CHAR_STATE, HILINK_ReportCharState, int, + const char *, svcId, const char *, payload, unsigned int, len); + return 0; +} + +int HILINK_IsRegister(void) +{ + hilink_call0(HILINK_CALL_HILINK_IS_REGISTER, HILINK_IsRegister, int); + return 0; +} + +int HILINK_GetNetworkingMode(void) +{ + hilink_call0(HILINK_CALL_HILINK_GET_NETWORKING_MODE, HILINK_GetNetworkingMode, int); + return 0; +} + +int HILINK_GetRegisterStatus(void) +{ + hilink_call0(HILINK_CALL_HILINK_GET_REGISTER_STATUS, HILINK_GetRegisterStatus, int); + return 0; +} + +int HILINK_SetScheduleInterval(unsigned long interval) +{ + hilink_call1(HILINK_CALL_HILINK_SET_SCHEDULE_INTERVAL, HILINK_SetScheduleInterval, int, unsigned long, interval); + return 0; +} + +int HILINK_SetMonitorScheduleInterval(unsigned long interval) +{ + hilink_call1(HILINK_CALL_HILINK_SET_MONITOR_SCHEDULE_INTERVAL, HILINK_SetMonitorScheduleInterval, int, + unsigned long, interval); + return 0; +} + +int HILINK_SetNetConfigMode(enum HILINK_NetConfigMode netConfigMode) +{ + hilink_call1(HILINK_CALL_HILINK_SET_NET_CONFIG_MODE, HILINK_SetNetConfigMode, int, + enum HILINK_NetConfigMode, netConfigMode); + return 0; +} + +enum HILINK_NetConfigMode HILINK_GetNetConfigMode(void) +{ + hilink_call0(HILINK_CALL_HILINK_GET_NET_CONFIG_MODE, HILINK_GetNetConfigMode, enum HILINK_NetConfigMode); + return HILINK_NETCONFIG_BUTT; +} + +void HILINK_SetNetConfigTimeout(unsigned long netConfigTimeout) +{ + hilink_call1_ret_void(HILINK_CALL_HILINK_SET_NET_CONFIG_TIMEOUT, HILINK_SetNetConfigTimeout, + unsigned long, netConfigTimeout); +} + +int HILINK_SetOtaBootTime(unsigned int bootTime) +{ + hilink_call1(HILINK_CALL_HILINK_SET_OTA_BOOT_TIME, HILINK_SetOtaBootTime, int, unsigned int, bootTime); + return 0; +} + +void HILINK_EnableKitframework(void) +{ + hilink_call0_ret_void(HILINK_CALL_HILINK_ENABLE_KITFRAMEWORK, HILINK_EnableKitframework); +} + +void HILINK_EnableBatchControl(bool flag) +{ + hilink_call1_ret_void(HILINK_CALL_HILINK_ENABLE_BATCH_CONTROL, HILINK_EnableBatchControl, bool, flag); +} + +void HILINK_EnableProcessDelErrCode(int enable) +{ + hilink_call1_ret_void(HILINK_CALL_HILINK_ENABLE_PROCESS_DEL_ERR_CODE, HILINK_EnableProcessDelErrCode, int, enable); +} + +void HILINK_UnbindDevice(int type) +{ + hilink_call1_ret_void(HILINK_CALL_HILINK_UNBIND_DEVICE, HILINK_UnbindDevice, int, type); +} + +int HILINK_SetDeviceInstallType(int type) +{ + hilink_call1(HILINK_CALL_HILINK_SET_DEVICE_INSTALL_TYPE, HILINK_SetDeviceInstallType, int, int, type); + return 0; +} + +SetupType HILINK_GetDevSetupType(void) +{ + hilink_call0(HILINK_CALL_HILINK_GET_DEV_SETUP_TYPE, HILINK_GetDevSetupType, SetupType); + return SETUP_TYPE_UNREGISTER; +} + +void HILINK_EnableDevIdInherit(bool isEnbale) +{ + hilink_call1_ret_void(HILINK_CALL_HILINK_ENABLE_DEV_ID_INHERIT, HILINK_EnableDevIdInherit, bool, isEnbale); +} + +void HILINK_NotifyNetworkAvailable(bool status) +{ + hilink_call1_ret_void(HILINK_CALL_HILINK_NOTIFY_NETWORK_AVAILABLE, HILINK_NotifyNetworkAvailable, bool, status); +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_bt_function.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_bt_function.c new file mode 100755 index 0000000..5f54689 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_bt_function.c @@ -0,0 +1,23 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: hilink bt function \n + * + * History: \n + * 2024-01-27, Create file. \n + */ +#include "hilink_call.h" +#include "hilink_bt_function.h" + +int HILINK_BT_SetSdkEventCallback(HILINK_BT_SdkEventCallBack callback) +{ + hilink_call1(HILINK_CALL_HILINK_BT_SET_SDK_EVENT_CALLBACK, HILINK_BT_SetSdkEventCallback, int, + HILINK_BT_SdkEventCallBack, callback); + return 0; +} + +int HILINK_BT_HardRevoke(void) +{ + hilink_call0(HILINK_CALL_HILINK_BT_SET_SDK_EVENT_CALLBACK, HILINK_BT_HardRevoke, int); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_custom.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_custom.c new file mode 100755 index 0000000..b2ff7f1 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_custom.c @@ -0,0 +1,45 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: hilink sle api + * + * History: \n + * 2024-11-08, Create file. + */ +#include "hilink_call.h" +#include "hilink_sle_api.h" + +void HILINK_SetProtType(const int protType) +{ + hilink_call1_ret_void(HILINK_CALL_HILINK_SET_PROT_TYPE, HILINK_SetProtType, const int, protType); +} + +void HILINK_EnablePrescan(void) +{ + hilink_call0_ret_void(HILINK_CALL_HILINK_ENABLE_PRESCAN, HILINK_EnablePrescan); +} + +int HILINK_SetNetConfigInfo(const char *info) +{ + hilink_call1(HILINK_CALL_HILINK_SET_NET_CONFIG_INFO, HILINK_SetNetConfigInfo, int, const char *, info); + return 0; +} + +int HILINK_SetSoftAPMode(void) +{ + hilink_call0(HILINK_CALL_HILINK_SET_SOFT_APMODE, HILINK_SetSoftAPMode, int); + return 0; +} + +int HILINK_RequestRegInfo(unsigned int regInfoNums) +{ + hilink_call1(HILINK_CALL_HILINK_REQUEST_REG_INFO, HILINK_RequestRegInfo, int, unsigned int, regInfoNums); + return 0; +} + +int HILINK_DiagnosisInfoRecord(int errCode, const char *param) +{ + hilink_call2(HILINK_CALL_HILINK_DIAGNOSIS_INFO_RECORD, HILINK_DiagnosisInfoRecord, int, + int, errCode, const char *, param); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_device_ext.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_device_ext.c new file mode 100755 index 0000000..52fa7f2 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_device_ext.c @@ -0,0 +1,17 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: HiLink register to get function ACkeyV2 \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "hilink_call.h" +#include "hilink_device.h" + +void HILINK_RegisterGetAcV2Func(HILINK_GetAcKeyFunc func) +{ + hilink_call1_ret_void(HILINK_CALL_HILINK_REGISTER_GET_AC_V2_FUNC, HILINK_RegisterGetAcV2Func, + HILINK_GetAcKeyFunc, func); +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_log_manage.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_log_manage.c new file mode 100755 index 0000000..2f86a50 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_log_manage.c @@ -0,0 +1,24 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: HiLink log management \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "hilink_log_manage.h" +#include "hilink_call.h" + +#include + +void HILINK_SetLogLevel(HiLinkLogLevel level) +{ + hilink_call1_ret_void(HILINK_CALL_HILINK_SET_LOG_LEVEL, HILINK_SetLogLevel, HiLinkLogLevel, level); +} + +HiLinkLogLevel HILINK_GetLogLevel(void) +{ + hilink_call0(HILINK_CALL_HILINK_GET_LOG_LEVEL, HILINK_GetLogLevel, HiLinkLogLevel); + return HILINK_LOG_INVALID; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_network_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_network_adapter.c new file mode 100755 index 0000000..0b361db --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_network_adapter.c @@ -0,0 +1,17 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: hilink network adapter + * + * History: \n + * 2024-05-28, Create file. + */ +#include "hilink_call.h" +#include "hilink_network_adapter.h" + +int HILINK_RegWiFiRecoveryCallback(const WiFiRecoveryApi *cb, unsigned int cbSize) +{ + hilink_call2(HILINK_CALL_HILINK_REG_WI_FI_RECOVERY_CALLBACK, HILINK_RegWiFiRecoveryCallback, int, + const WiFiRecoveryApi *, cb, unsigned int, cbSize); + return 0; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_quick_netcfg_api.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_quick_netcfg_api.c new file mode 100755 index 0000000..b4ce21c --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_quick_netcfg_api.c @@ -0,0 +1,56 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: hilink network adapter + * + * History: \n + * 2024-05-28, Create file. + */ +#include "hilink_call.h" +#include "hilink_quick_netcfg_api.h" +#include "hilink_quick_netcfg_adapter.h" + +int HILINK_SetQuickCfgCommonLoader(QuickCfgCommonLoader *loader, unsigned int loaderSize) +{ + hilink_call2(HILINK_CALL_HILINK_SET_QUICK_CFG_COMMON_LOADER, HILINK_SetQuickCfgCommonLoader, int, + QuickCfgCommonLoader *, loader, unsigned int, loaderSize); + return 0; +} +int HILINK_StartQuickCfg(void) +{ + hilink_call0(HILINK_CALL_HILINK_START_QUICK_CFG, HILINK_StartQuickCfg, int); + return 0; +} + +int HILINK_FrameParse(const unsigned char *frame, unsigned int len) +{ + hilink_call2(HILINK_CALL_HILINK_FRAME_PARSE, HILINK_FrameParse, int, + const unsigned char *, frame, unsigned int, len); + return 0; +} + +int HILINK_QuickCfgCmdParse(const char *payload, unsigned int len) +{ + hilink_call2(HILINK_CALL_HILINK_QUICK_CFG_CMD_PARSE, HILINK_QuickCfgCmdParse, int, + const char *, payload, unsigned int, len); + return 0; +} + +int HILINK_SetDeviceType(DevType type) +{ + hilink_call1(HILINK_CALL_HILINK_SET_DEVICE_TYPE, HILINK_SetDeviceType, int, + DevType, type); + return 0; +} + +int HILINK_SetQuickCfgWifiLoader(QuickCfgWifiLoader *loader, unsigned int loaderSize) +{ + hilink_call2(HILINK_CALL_HILINK_SET_QUICK_CFG_WIFI_LOADER, HILINK_SetQuickCfgWifiLoader, int, + QuickCfgWifiLoader *, loader, unsigned int, loaderSize); + return 0; +} + +void HILINK_EnableQuickNetCfg(void) +{ + hilink_call0_ret_void(HILINK_CALL_HILINK_ENABLE_QUICK_NET_CFG, HILINK_EnableQuickNetCfg); +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_sle_api.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_sle_api.c new file mode 100755 index 0000000..aac07fb --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_sle_api.c @@ -0,0 +1,15 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: hilink sle api + * + * History: \n + * 2024-11-08, Create file. + */ +#include "hilink_call.h" +#include "hilink_sle_api.h" + +void HILINK_EnableSle(void) +{ + hilink_call0_ret_void(HILINK_CALL_HILINK_ENABLE_SLE, HILINK_EnableSle); +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_socket_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_socket_adapter.c new file mode 100755 index 0000000..dc6d55e --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/application/hilink_uapi/uapi_hilink_socket_adapter.c @@ -0,0 +1,16 @@ + /** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: hilink socket adapter + * + * History: \n + * 2024-05-28, Create file. + */ +#include "hilink_call.h" +#include "hilink_socket_adapter.h" + +int HILINK_RegisterErrnoCallback(GetErrno cb) +{ + hilink_call1(HILINK_CALL_HILINK_REGISTER_ERRNO_CALLBACK, HILINK_RegisterErrnoCallback, int, GetErrno, cb); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/CMakeLists.txt b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/CMakeLists.txt new file mode 100755 index 0000000..878a624 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/CMakeLists.txt @@ -0,0 +1,131 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "hilinkdevicesdk") + +set(LIBS ${ROOT_DIR}/application/samples/wifi/libhilink/lib${COMPONENT_NAME}.a) +set(WHOLE_LINK + true +) +build_component() + +set(COMPONENT_NAME "hilinkota") + +set(LIBS ${ROOT_DIR}/application/samples/wifi/libhilink/lib${COMPONENT_NAME}.a) +set(WHOLE_LINK + true +) +build_component() + +set(COMPONENT_NAME "hilinkbtsdk") + +set(LIBS ${ROOT_DIR}/application/samples/wifi/libhilink/lib${COMPONENT_NAME}.a) +set(WHOLE_LINK + true +) +build_component() + +if (DEFINES MATCHES "SUPPORT_QUICK_NETCFG") +set(COMPONENT_NAME "hilinkquickcfg") +set(LIBS ${ROOT_DIR}/application/samples/wifi/libhilink/lib${COMPONENT_NAME}.a) +set(WHOLE_LINK + true +) +build_component() +endif() + +set(COMPONENT_NAME "hilink_addr_map") + +set(CMAKE_HILINK_SOURCE_DIR + ${CMAKE_CURRENT_SOURCE_DIR}) + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_call_entry.c + ${CMAKE_CURRENT_SOURCE_DIR}/hilink_function_mapping.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hichain.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_device.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_kv_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_mem_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_network_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_open_ota_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_open_ota_mcu_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_sal_aes.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_sal_base64.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_sal_drbg.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_sal_kdf.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_sal_md.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_sal_mpi.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_sal_rsa.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_socket_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_softap_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_stdio_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_str_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_sys_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_thread_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_time_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_tls_client.c + + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_ble_adapter.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_hilink_ble_main.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_cmsis_liteos2.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_cJSON.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_mbed_tls.c + + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_oh_sle_connection_manager.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_oh_sle_device_discovery.c + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/uapi_oh_sle_ssap_server.c +) + +set(PUBLIC_HEADER +) + +set(PRIVATE_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/../../../ohos_connect/hilink_adapt/product/ + ${CMAKE_CURRENT_SOURCE_DIR}/../../../ohos_connect/hilink_adapt/include/ + ${CMAKE_CURRENT_SOURCE_DIR}/../../../ohos_connect/hilink_adapt/adapter/include/ + + ${ROOT_DIR}/open_source/deviceauth/interfaces/innerkits/deviceauth_lite/ + + ${CMAKE_CURRENT_SOURCE_DIR}/ + ${CMAKE_CURRENT_SOURCE_DIR}/app_uapi/ + ${CMAKE_CURRENT_SOURCE_DIR}/../include/ + + ${ROOT_DIR}/kernel/liteos/liteos_v208.5.0/Huawei_LiteOS/open_source/CMSIS/CMSIS/RTOS2/Include/ + ${ROOT_DIR}/include/ + ${ROOT_DIR}/open_source/cjson/cjson + ${ROOT_DIR}/open_source/mbedtls/mbedtls_v3.1.0/include +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -Wno-error=logical-op + -Wno-error=sign-compare + -Wno-error=jump-misses-init + -Wno-sign-compare + -Wno-jump-misses-init + -Wno-error=unused-parameter + -Wno-unused-parameter + -Wno-unused-but-set-variable + -Wno-error=unused-variable +) + +set(PRIVATE_DEFINES +) + +set(PUBLIC_DEFINES +) +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + false +) + +set(LIB_OUT_PATH ${BIN_DIR}/${CHIP}/libs/wifi/${TARGET_COMMAND}) + +build_component() \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/app_call.h b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/app_call.h new file mode 100755 index 0000000..e8939bb --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/app_call.h @@ -0,0 +1,130 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: Function invoking macros on the application side. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#ifndef APP_CALL_H +#define APP_CALL_H + +#include "func_call_list.h" +#include "hilink_call_entry.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0L +#else +#define NULL ((void*)0) +#endif +#endif + +#define app_call0(idx, nr, t) do { \ + void *call_addr = get_app_api_addr(idx, #t#nr"()"); \ + if (call_addr != NULL) { \ + return ((t (*)(void))call_addr)(); \ + } \ +} while (0) +#define app_call1(idx, nr, t, t1, p1) do { \ + void *call_addr = get_app_api_addr(idx, #t#nr"("#t1")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1))call_addr)(p1); \ + } \ +} while (0) +#define app_call2(idx, nr, t, t1, p1, t2, p2) do { \ + void *call_addr = get_app_api_addr(idx, #t#nr"("#t1","#t2")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2))call_addr)(p1, p2); \ + } \ +} while (0) +#define app_call3(idx, nr, t, t1, p1, t2, p2, t3, p3) do { \ + void *call_addr = get_app_api_addr(idx, #t#nr"("#t1","#t2","#t3")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2, t3))call_addr)(p1, p2, p3); \ + } \ +} while (0) +#define app_call4(idx, nr, t, t1, p1, t2, p2, t3, p3, t4, p4) do { \ + void *call_addr = get_app_api_addr(idx, #t#nr"("#t1","#t2","#t3","#t4")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2, t3, t4))call_addr)(p1, p2, p3, p4); \ + } \ +} while (0) +#define app_call5(idx, nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) do { \ + void *call_addr = get_app_api_addr(idx, #t#nr"("#t1","#t2","#t3","#t4","#t5")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2, t3, t4, t5))call_addr)(p1, p2, p3, p4, p5); \ + } \ +} while (0) +#define app_call6(idx, nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) do { \ + void *call_addr = get_app_api_addr(idx, #t#nr"("#t1","#t2","#t3","#t4","#t5","#t6")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2, t3, t4, t5, t6))call_addr)(p1, p2, p3, p4, p5, p6); \ + } \ +} while (0) +#define app_call9(idx, nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9) do { \ + void *call_addr = get_app_api_addr(idx, #t#nr"("#t1","#t2","#t3","#t4","#t5","#t6","#t7","#t8","#t9")"); \ + if (call_addr != NULL) { \ + return ((t (*)(t1, t2, t3, t4, t5, t6, t7, t8, t9))call_addr)(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } \ +} while (0) + +#define app_call0_ret_void(idx, nr) do { \ + void *call_addr = get_app_api_addr(idx, "void"#nr"()"); \ + if (call_addr != NULL) { \ + ((void (*)(void))call_addr)(); \ + return; \ + } \ +} while (0) +#define app_call1_ret_void(idx, nr, t1, p1) do { \ + void *call_addr = get_app_api_addr(idx, "void"#nr"("#t1")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1))call_addr)(p1); \ + return; \ + } \ +} while (0) +#define app_call2_ret_void(idx, nr, t1, p1, t2, p2) do { \ + void *call_addr = get_app_api_addr(idx, "void"#nr"("#t1","#t2")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2))call_addr)(p1, p2); \ + return; \ + } \ +} while (0) +#define app_call3_ret_void(idx, nr, t1, p1, t2, p2, t3, p3) do { \ + void *call_addr = get_app_api_addr(idx, "void"#nr"("#t1","#t2","#t3")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2, t3))call_addr)(p1, p2, p3); \ + return; \ + } \ +} while (0) +#define app_call4_ret_void(idx, nr, t1, p1, t2, p2, t3, p3, t4, p4) do { \ + void *call_addr = get_app_api_addr(idx, "void"#nr"("#t1","#t2","#t3","#t4")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2, t3, t4))call_addr)(p1, p2, p3, p4); \ + return; \ + } \ +} while (0) +#define app_call5_ret_void(idx, nr, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) do { \ + void *call_addr = get_app_api_addr(idx, "void"#nr"("#t1","#t2","#t3","#t4","#t5")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2, t3, t4, t5))call_addr)(p1, p2, p3, p4, p5); \ + return; \ + } \ +} while (0) +#define app_call6_ret_void(idx, nr, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) do { \ + void *call_addr = get_app_api_addr(idx, "void"#nr"("#t1","#t2","#t3","#t4","#t5","#t6")"); \ + if (call_addr != NULL) { \ + ((void (*)(t1, t2, t3, t4, t5, t6))call_addr)(p1, p2, p3, p4, p5, p6); \ + return; \ + } \ +} while (0) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_cJSON.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_cJSON.c new file mode 100755 index 0000000..a0531b8 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_cJSON.c @@ -0,0 +1,520 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of cJSON in sdk side. \n + * + * History: \n + * 2024-11-26, Create file. \n + */ + +#include "app_call.h" +#include "cJSON.h" + +#ifdef true +#undef true +#endif +#define true ((cJSON_bool)1) + +#ifdef false +#undef false +#endif +#define false ((cJSON_bool)0) + +const char *cJSON_Version(void) +{ + app_call0(APP_CALL_C_JSON_VERSION, cJSON_Version, const char *); + return NULL; +} + +void cJSON_InitHooks(cJSON_Hooks * hooks) +{ + app_call1_ret_void(APP_CALL_C_JSON_INIT_HOOKS, cJSON_InitHooks, cJSON_Hooks *, hooks); +} + +cJSON *cJSON_Parse(const char *value) +{ + app_call1(APP_CALL_C_JSON_PARSE, cJSON_Parse, cJSON *, const char *, value); + return NULL; +} + +cJSON *cJSON_ParseWithLength(const char *value, size_t buffer_length) +{ + app_call2(APP_CALL_C_JSON_PARSE_WITH_LENGTH, cJSON_ParseWithLength, cJSON *, + const char *, value, size_t, buffer_length); + return NULL; +} + +cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + app_call3(APP_CALL_C_JSON_PARSE_WITH_OPTS, cJSON_ParseWithOpts, cJSON *, + const char *, value, const char **, return_parse_end, cJSON_bool, require_null_terminated); + return NULL; +} + +cJSON *cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, + const char **return_parse_end, cJSON_bool require_null_terminated) +{ + app_call4(APP_CALL_C_JSON_PARSE_WITH_LENGTH_OPTS, cJSON_ParseWithLengthOpts, cJSON *, + const char *, value, size_t, buffer_length, const char **, return_parse_end, cJSON_bool, require_null_terminated); + return NULL; +} + +char *cJSON_Print(const cJSON *item) +{ + app_call1(APP_CALL_C_JSON_PRINT, cJSON_Print, char *, const cJSON *, item); + return NULL; +} + +char *cJSON_PrintUnformatted(const cJSON *item) +{ + app_call1(APP_CALL_C_JSON_PRINT_UNFORMATTED, cJSON_PrintUnformatted, char *, const cJSON *, item); + return NULL; +} + +char *cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + app_call3(APP_CALL_C_JSON_PRINT_BUFFERED, cJSON_PrintBuffered, char *, + const cJSON *, item, int, prebuffer, cJSON_bool, fmt); + return NULL; +} + +cJSON_bool cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) +{ + app_call4(APP_CALL_C_JSON_PRINT_PREALLOCATED, cJSON_PrintPreallocated, cJSON_bool, + cJSON *, item, char *, buffer, const int, length, const cJSON_bool, format); + return false; +} + +void cJSON_Delete(cJSON *item) +{ + app_call1_ret_void(APP_CALL_C_JSON_DELETE, cJSON_Delete, cJSON *, item); +} + +int cJSON_GetArraySize(const cJSON *array) +{ + app_call1(APP_CALL_C_JSON_GET_ARRAY_SIZE, cJSON_GetArraySize, int, const cJSON *, array); + return 0; +} + +cJSON *cJSON_GetArrayItem(const cJSON *array, int index) +{ + app_call2(APP_CALL_C_JSON_GET_ARRAY_ITEM, cJSON_GetArrayItem, cJSON *, const cJSON *, array, int, index); + return NULL; +} + +cJSON *cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + app_call2(APP_CALL_C_JSON_GET_OBJECT_ITEM, cJSON_GetObjectItem, cJSON *, + const cJSON * const, object, const char * const, string); + return NULL; +} + +cJSON *cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + app_call2(APP_CALL_C_JSON_GET_OBJECT_ITEM_CASE_SENSITIVE, cJSON_GetObjectItemCaseSensitive, cJSON *, + const cJSON * const, object, const char * const, string); + return NULL; +} + +cJSON_bool cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + app_call2(APP_CALL_C_JSON_HAS_OBJECT_ITEM, cJSON_HasObjectItem, cJSON_bool, + const cJSON *, object, const char *, string); + return false; +} + +const char *cJSON_GetErrorPtr(void) +{ + app_call0(APP_CALL_C_JSON_GET_ERROR_PTR, cJSON_GetErrorPtr, const char *); + return NULL; +} + +char *cJSON_GetStringValue(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_GET_STRING_VALUE, cJSON_GetStringValue, char *, const cJSON * const, item); + return NULL; +} + +double cJSON_GetNumberValue(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_GET_NUMBER_VALUE, cJSON_GetNumberValue, double, const cJSON * const, item); + return 0; +} + +cJSON_bool cJSON_IsInvalid(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_INVALID, cJSON_IsInvalid, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON_bool cJSON_IsFalse(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_FALSE, cJSON_IsFalse, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON_bool cJSON_IsTrue(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_TRUE, cJSON_IsTrue, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON_bool cJSON_IsBool(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_BOOL, cJSON_IsBool, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON_bool cJSON_IsNull(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_NULL, cJSON_IsNull, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON_bool cJSON_IsNumber(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_NUMBER, cJSON_IsNumber, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON_bool cJSON_IsString(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_STRING, cJSON_IsString, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON_bool cJSON_IsArray(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_ARRAY, cJSON_IsArray, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON_bool cJSON_IsObject(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_OBJECT, cJSON_IsObject, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON_bool cJSON_IsRaw(const cJSON * const item) +{ + app_call1(APP_CALL_C_JSON_IS_RAW, cJSON_IsRaw, cJSON_bool, const cJSON * const, item); + return false; +} + +cJSON *cJSON_CreateNull(void) +{ + app_call0(APP_CALL_C_JSON_CREATE_NULL, cJSON_CreateNull, cJSON *); + return NULL; +} + +cJSON *cJSON_CreateTrue(void) +{ + app_call0(APP_CALL_C_JSON_CREATE_TRUE, cJSON_CreateTrue, cJSON *); + return NULL; +} + +cJSON *cJSON_CreateFalse(void) +{ + app_call0(APP_CALL_C_JSON_CREATE_FALSE, cJSON_CreateFalse, cJSON *); + return NULL; +} + +cJSON *cJSON_CreateBool(cJSON_bool boolean) +{ + app_call1(APP_CALL_C_JSON_CREATE_BOOL, cJSON_CreateBool, cJSON *, cJSON_bool, boolean); + return NULL; +} + +cJSON *cJSON_CreateNumber(double num) +{ + app_call1(APP_CALL_C_JSON_CREATE_NUMBER, cJSON_CreateNumber, cJSON *, double, num); + return NULL; +} + +cJSON *cJSON_CreateString(const char *string) +{ + app_call1(APP_CALL_C_JSON_CREATE_STRING, cJSON_CreateString, cJSON *, const char *, string); + return NULL; +} + +cJSON *cJSON_CreateRaw(const char *raw) +{ + app_call1(APP_CALL_C_JSON_CREATE_RAW, cJSON_CreateRaw, cJSON *, const char *, raw); + return NULL; +} + +cJSON *cJSON_CreateArray(void) +{ + app_call0(APP_CALL_C_JSON_CREATE_ARRAY, cJSON_CreateArray, cJSON *); + return NULL; +} + +cJSON *cJSON_CreateObject(void) +{ + app_call0(APP_CALL_C_JSON_CREATE_OBJECT, cJSON_CreateObject, cJSON *); + return NULL; +} + +cJSON *cJSON_CreateStringReference(const char *string) +{ + app_call1(APP_CALL_C_JSON_CREATE_STRING_REFERENCE, cJSON_CreateStringReference, cJSON *, const char *, string); + return NULL; +} + +cJSON *cJSON_CreateObjectReference(const cJSON *child) +{ + app_call1(APP_CALL_C_JSON_CREATE_OBJECT_REFERENCE, cJSON_CreateObjectReference, cJSON *, const cJSON *, child); + return NULL; +} + +cJSON *cJSON_CreateArrayReference(const cJSON *child) +{ + app_call1(APP_CALL_C_JSON_CREATE_ARRAY_REFERENCE, cJSON_CreateArrayReference, cJSON *, const cJSON *, child); + return NULL; +} + +cJSON *cJSON_CreateIntArray(const int *numbers, int count) +{ + app_call2(APP_CALL_C_JSON_CREATE_INT_ARRAY, cJSON_CreateIntArray, cJSON *, const int *, numbers, int, count); + return NULL; +} + +cJSON *cJSON_CreateFloatArray(const float *numbers, int count) +{ + app_call2(APP_CALL_C_JSON_CREATE_FLOAT_ARRAY, cJSON_CreateFloatArray, cJSON *, + const float *, numbers, int, count); + return NULL; +} + +cJSON *cJSON_CreateDoubleArray(const double *numbers, int count) +{ + app_call2(APP_CALL_C_JSON_CREATE_DOUBLE_ARRAY, cJSON_CreateDoubleArray, cJSON *, + const double *, numbers, int, count); + return NULL; +} + +cJSON *cJSON_CreateStringArray(const char *const *strings, int count) +{ + app_call2(APP_CALL_C_JSON_CREATE_STRING_ARRAY, cJSON_CreateStringArray, cJSON *, + const char *const *, strings, int, count); + return NULL; +} + +cJSON_bool cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + app_call2(APP_CALL_C_JSON_ADD_ITEM_TO_ARRAY, cJSON_AddItemToArray, cJSON_bool, cJSON *, array, cJSON *, item); + return false; +} + +cJSON_bool cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + app_call3(APP_CALL_C_JSON_ADD_ITEM_TO_OBJECT, cJSON_AddItemToObject, cJSON_bool, + cJSON *, object, const char *, string, cJSON *, item); + return false; +} + +cJSON_bool cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + app_call3(APP_CALL_C_JSON_ADD_ITEM_TO_OBJECT_CS, cJSON_AddItemToObjectCS, cJSON_bool, + cJSON *, object, const char *, string, cJSON *, item); + return false; +} + +cJSON_bool cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + app_call2(APP_CALL_C_JSON_ADD_ITEM_REFERENCE_TO_ARRAY, cJSON_AddItemReferenceToArray, cJSON_bool, + cJSON *, array, cJSON *, item); + return false; +} + +cJSON_bool cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + app_call3(APP_CALL_C_JSON_ADD_ITEM_REFERENCE_TO_OBJECT, cJSON_AddItemReferenceToObject, cJSON_bool, + cJSON *, object, const char *, string, cJSON *, item); + return false; +} + +cJSON *cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + app_call2(APP_CALL_C_JSON_DETACH_ITEM_VIA_POINTER, cJSON_DetachItemViaPointer, cJSON *, + cJSON *, parent, cJSON * const, item); + return NULL; +} + +cJSON *cJSON_DetachItemFromArray(cJSON *array, int which) +{ + app_call2(APP_CALL_C_JSON_DETACH_ITEM_FROM_ARRAY, cJSON_DetachItemFromArray, cJSON *, + cJSON *, array, int, which); + return NULL; +} + +void cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + app_call2_ret_void(APP_CALL_C_JSON_DELETE_ITEM_FROM_ARRAY, cJSON_DeleteItemFromArray, cJSON *, array, int, which); +} + +cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + app_call2(APP_CALL_C_JSON_DETACH_ITEM_FROM_OBJECT, cJSON_DetachItemFromObject, cJSON *, + cJSON *, object, const char *, string); + return NULL; +} + +cJSON *cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + app_call2(APP_CALL_C_JSON_DETACH_ITEM_FROM_OBJECT_CASE_SENSITIVE, cJSON_DetachItemFromObjectCaseSensitive, cJSON *, + cJSON *, object, const char *, string); + return NULL; +} + +void cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + app_call2_ret_void(APP_CALL_C_JSON_DELETE_ITEM_FROM_OBJECT, cJSON_DeleteItemFromObject, + cJSON *, object, const char *, string); +} + +void cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + app_call2_ret_void(APP_CALL_C_JSON_DELETE_ITEM_FROM_OBJECT_CASE_SENSITIVE, cJSON_DeleteItemFromObjectCaseSensitive, + cJSON *, object, const char *, string); +} + +cJSON_bool cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + app_call3(APP_CALL_C_JSON_INSERT_ITEM_IN_ARRAY, cJSON_InsertItemInArray, cJSON_bool, + cJSON *, array, int, which, cJSON *, newitem); + return false; +} + +cJSON_bool cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON *const item, cJSON *replacement) +{ + app_call3(APP_CALL_C_JSON_REPLACE_ITEM_VIA_POINTER, cJSON_ReplaceItemViaPointer, cJSON_bool, + cJSON * const, parent, cJSON * const, item, cJSON *, replacement); + return false; +} + +cJSON_bool cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + app_call3(APP_CALL_C_JSON_REPLACE_ITEM_IN_ARRAY, cJSON_ReplaceItemInArray, cJSON_bool, + cJSON *, array, int, which, cJSON *, newitem); + return false; +} + +cJSON_bool cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + app_call3(APP_CALL_C_JSON_REPLACE_ITEM_IN_OBJECT, cJSON_ReplaceItemInObject, cJSON_bool, + cJSON *, object, const char *, string, cJSON *, newitem); + return false; +} + +cJSON_bool cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + app_call3(APP_CALL_C_JSON_REPLACE_ITEM_IN_OBJECT_CASE_SENSITIVE, cJSON_ReplaceItemInObjectCaseSensitive, + cJSON_bool, cJSON *, object, const char *, string, cJSON *, newitem); + return false; +} + +cJSON *cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + app_call2(APP_CALL_C_JSON_DUPLICATE, cJSON_Duplicate, cJSON *, const cJSON *, item, cJSON_bool, recurse); + return NULL; +} + +cJSON_bool cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + app_call3(APP_CALL_C_JSON_COMPARE, cJSON_Compare, cJSON_bool, + const cJSON * const, a, const cJSON * const, b, const cJSON_bool, case_sensitive); + return false; +} + +void cJSON_Minify(char *json) +{ + app_call1_ret_void(APP_CALL_C_JSON_MINIFY, cJSON_Minify, char *, json); +} + +cJSON *cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + app_call2(APP_CALL_C_JSON_ADD_NULL_TO_OBJECT, cJSON_AddNullToObject, cJSON *, + cJSON * const, object, const char * const, name); + return NULL; +} + +cJSON *cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + app_call2(APP_CALL_C_JSON_ADD_TRUE_TO_OBJECT, cJSON_AddTrueToObject, cJSON *, + cJSON * const, object, const char * const, name); + return NULL; +} + +cJSON *cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + app_call2(APP_CALL_C_JSON_ADD_FALSE_TO_OBJECT, cJSON_AddFalseToObject, cJSON *, + cJSON * const, object, const char * const, name); + return NULL; +} + +cJSON *cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + app_call3(APP_CALL_C_JSON_ADD_BOOL_TO_OBJECT, cJSON_AddBoolToObject, cJSON *, + cJSON * const, object, const char * const, name, const cJSON_bool, boolean); + return NULL; +} + +cJSON *cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + app_call3(APP_CALL_C_JSON_ADD_NUMBER_TO_OBJECT, cJSON_AddNumberToObject, cJSON *, + cJSON * const, object, const char * const, name, const double, number); + return NULL; +} + +cJSON *cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + app_call3(APP_CALL_C_JSON_ADD_STRING_TO_OBJECT, cJSON_AddStringToObject, cJSON *, + cJSON * const, object, const char * const, name, const char * const, string); + return NULL; +} + +cJSON *cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + app_call3(APP_CALL_C_JSON_ADD_RAW_TO_OBJECT, cJSON_AddRawToObject, cJSON *, + cJSON * const, object, const char * const, name, const char * const, raw); + return NULL; +} + +cJSON *cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + app_call2(APP_CALL_C_JSON_ADD_OBJECT_TO_OBJECT, cJSON_AddObjectToObject, cJSON *, + cJSON * const, object, const char * const, name); + return NULL; +} + +cJSON *cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + app_call2(APP_CALL_C_JSON_ADD_ARRAY_TO_OBJECT, cJSON_AddArrayToObject, cJSON *, + cJSON * const, object, const char * const, name); + return NULL; +} + +double cJSON_SetNumberHelper(cJSON *object, double number) +{ + app_call2(APP_CALL_C_JSON_SET_NUMBER_HELPER, cJSON_SetNumberHelper, double, cJSON *, object, double, number); + return 0; +} + +char *cJSON_SetValuestring(cJSON *object, const char *valuestring) +{ + app_call2(APP_CALL_C_JSON_SET_VALUESTRING, cJSON_SetValuestring, char *, + cJSON *, object, const char *, valuestring); + return NULL; +} + +void *cJSON_malloc(size_t size) +{ + app_call1(APP_CALL_C_JSON_MALLOC, cJSON_malloc, void *, size_t, size); + return NULL; +} + +void cJSON_free(void *object) +{ + app_call1_ret_void(APP_CALL_C_JSON_FREE, cJSON_free, void *, object); +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_cmsis_liteos2.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_cmsis_liteos2.c new file mode 100755 index 0000000..096a6e2 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_cmsis_liteos2.c @@ -0,0 +1,123 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Common operations on the cmsis liteos2, including session creation and destruction. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "cmsis_os2.h" + +/* Only applicable to the partially used interfaces */ +uint32_t osKernelGetTickCount(void) +{ + app_call0(APP_CALL_OS_KERNEL_GET_TICK_COUNT, osKernelGetTickCount, uint32_t); + return 0; +} + +uint32_t osKernelGetTickFreq(void) +{ + app_call0(APP_CALL_OS_KERNEL_GET_TICK_FREQ, osKernelGetTickFreq, uint32_t); + return 0; +} + +osStatus_t osDelay(uint32_t ticks) +{ + app_call1(APP_CALL_OS_DELAY, osDelay, osStatus_t, uint32_t, ticks); + return osError; +} + +osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) +{ + app_call3(APP_CALL_OS_THREAD_NEW, osThreadNew, osThreadId_t, osThreadFunc_t, func, void *, argument, + const osThreadAttr_t *, attr); + return NULL; +} + +osStatus_t osThreadTerminate(osThreadId_t thread_id) +{ + app_call1(APP_CALL_OS_THREAD_TERMINATE, osThreadTerminate, osStatus_t, osThreadId_t, thread_id); + return osError; +} + +osThreadId_t osThreadGetId(void) +{ + app_call0(APP_CALL_OS_THREAD_GET_ID, osThreadGetId, osThreadId_t); + return NULL; +} + +osMutexId_t osMutexNew(const osMutexAttr_t *attr) +{ + app_call1(APP_CALL_OS_MUTEX_NEW, osMutexNew, osMutexId_t, const osMutexAttr_t *, attr); + return NULL; +} + +osStatus_t osMutexDelete(osMutexId_t mutex_id) +{ + app_call1(APP_CALL_OS_MUTEX_DELETE, osMutexDelete, osStatus_t, osMutexId_t, mutex_id); + return osError; +} + +osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout) +{ + app_call2(APP_CALL_OS_MUTEX_ACQUIRE, osMutexAcquire, osStatus_t, osMutexId_t, mutex_id, uint32_t, timeout); + return osError; +} + +osStatus_t osMutexRelease(osMutexId_t mutex_id) +{ + app_call1(APP_CALL_OS_MUTEX_RELEASE, osMutexRelease, osStatus_t, osMutexId_t, mutex_id); + return osError; +} + +osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, + const osSemaphoreAttr_t *attr) +{ + app_call3(APP_CALL_OS_SEMAPHORE_NEW, osSemaphoreNew, osSemaphoreId_t, uint32_t, max_count, + uint32_t, initial_count, const osSemaphoreAttr_t *, attr); + return NULL; +} + +osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout) +{ + app_call2(APP_CALL_OS_SEMAPHORE_ACQUIRE, osSemaphoreAcquire, osStatus_t, + osSemaphoreId_t, semaphore_id, uint32_t, timeout); + return osError; +} + +osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id) +{ + app_call1(APP_CALL_OS_SEMAPHORE_RELEASE, osSemaphoreRelease, osStatus_t, osSemaphoreId_t, semaphore_id); + return osError; +} + +osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id) +{ + app_call1(APP_CALL_OS_SEMAPHORE_DELETE, osSemaphoreDelete, osStatus_t, osSemaphoreId_t, semaphore_id); + return osError; +} + +osStatus_t osThreadSuspend(osThreadId_t thread_id) +{ + app_call1(APP_CALL_OS_THREAD_SUSPEND, osThreadSuspend, osStatus_t, osThreadId_t, thread_id); + return osError; +} + +osStatus_t osThreadResume(osThreadId_t thread_id) +{ + app_call1(APP_CALL_OS_THREAD_RESUME, osThreadResume, osStatus_t, osThreadId_t, thread_id); + return osError; +} + +void *malloc(size_t size) +{ + app_call1(APP_CALL_MALLOC, malloc, void *, size_t, size); + return NULL; +} + +void free(void *pt) +{ + app_call1_ret_void(APP_CALL_FREE, free, void *, pt); +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hichain.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hichain.c new file mode 100755 index 0000000..31ec428 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hichain.c @@ -0,0 +1,121 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Common operations on the hichain, including session creation and destruction. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hichain.h" + +DLL_API_PUBLIC void registe_log(struct log_func_group *log) +{ + app_call1_ret_void(APP_CALL_REGISTE_LOG, registe_log, struct log_func_group *, log); +} + +DLL_API_PUBLIC hc_handle get_instance(const struct session_identity *identity, enum hc_type type, + const struct hc_call_back *call_back) +{ + app_call3(APP_CALL_GET_INSTANCE, get_instance, hc_handle, const struct session_identity *, identity, + enum hc_type, type, const struct hc_call_back *, call_back); + return NULL; +} + +DLL_API_PUBLIC void destroy(hc_handle *handle) +{ + app_call1_ret_void(APP_CALL_DESTROY, destroy, hc_handle *, handle); +} + +DLL_API_PUBLIC void set_context(hc_handle handle, void *context) +{ + app_call2_ret_void(APP_CALL_SET_CONTEXT, set_context, hc_handle, handle, void *, context); +} + +DLL_API_PUBLIC int32_t receive_data(hc_handle handle, struct uint8_buff *data) +{ + app_call2(APP_CALL_RECEIVE_DATA, receive_data, int32_t, hc_handle, handle, struct uint8_buff *, data); + return 0; +} + +DLL_API_PUBLIC int32_t receive_data_with_json_object(hc_handle handle, const void *json_object) +{ + app_call2(APP_CALL_RECEIVE_DATA_WITH_JSON_OBJECT, receive_data_with_json_object, int32_t, + hc_handle, handle, const void *, json_object); + return 0; +} + +#ifndef _CUT_API_ +DLL_API_PUBLIC int32_t init_center(const struct hc_package_name *package_name, + const struct hc_service_type *service_type, const struct hc_auth_id *auth_id, struct hc_key_alias *dek) +{ + app_call4(APP_CALL_INIT_CENTER, init_center, int32_t, const struct hc_package_name *, package_name, + const struct hc_service_type *, service_type, const struct hc_auth_id *, auth_id, + struct hc_key_alias *, dek); + return 0; +} + +DLL_API_PUBLIC int32_t start_pake(hc_handle handle, const struct operation_parameter *params) +{ + app_call2(APP_CALL_START_PAKE, start_pake, int32_t, hc_handle, handle, const struct operation_parameter *, params); + return 0; +} + +DLL_API_PUBLIC int32_t authenticate_peer(hc_handle handle, struct operation_parameter *params) +{ + app_call2(APP_CALL_AUTHENTICATE_PEER, authenticate_peer, int32_t, + hc_handle, handle, struct operation_parameter *, params); + return 0; +} + +DLL_API_PUBLIC int32_t delete_local_auth_info(hc_handle handle, struct hc_user_info *user_info) +{ + app_call2(APP_CALL_DELETE_LOCAL_AUTH_INFO, delete_local_auth_info, int32_t, + hc_handle, handle, struct hc_user_info *, user_info); + return 0; +} + +DLL_API_PUBLIC int32_t import_auth_info(hc_handle handle, struct hc_user_info *user_info, + struct hc_auth_id *auth_id, enum hc_export_type auth_info_type, struct uint8_buff *auth_info) +{ + app_call5(APP_CALL_IMPORT_AUTH_INFO, import_auth_info, int32_t, hc_handle, handle, struct hc_user_info *, + user_info, struct hc_auth_id *, auth_id, enum hc_export_type, auth_info_type, struct uint8_buff *, auth_info); + return 0; +} + +int32_t add_auth_info(hc_handle handle, const struct operation_parameter *params, + const struct hc_auth_id *auth_id, int32_t user_type) +{ + app_call4(APP_CALL_ADD_AUTH_INFO, add_auth_info, int32_t, hc_handle, handle, + const struct operation_parameter *, params, const struct hc_auth_id *, auth_id, int32_t, user_type); + return 0; +} + +int32_t remove_auth_info(hc_handle handle, const struct operation_parameter *params, + const struct hc_auth_id *auth_id, int32_t user_type) +{ + app_call4(APP_CALL_REMOVE_AUTH_INFO, remove_auth_info, int32_t, hc_handle, handle, + const struct operation_parameter *, params, const struct hc_auth_id *, auth_id, int32_t, user_type); + return 0; +} + +DLL_API_PUBLIC int32_t is_trust_peer(hc_handle handle, struct hc_user_info *user_info) +{ + app_call2(APP_CALL_IS_TRUST_PEER, is_trust_peer, int32_t, hc_handle, handle, struct hc_user_info *, user_info); + return 0; +} + +DLL_API_PUBLIC uint32_t list_trust_peers(hc_handle handle, int32_t trust_user_type, + struct hc_auth_id *owner_auth_id, struct hc_auth_id **auth_id_list) +{ + app_call4(APP_CALL_LIST_TRUST_PEERS, list_trust_peers, uint32_t, hc_handle, handle, int32_t, trust_user_type, + struct hc_auth_id *, owner_auth_id, struct hc_auth_id **, auth_id_list); + return 0; +} +#endif /* _CUT_XXX_ */ + +DLL_API_PUBLIC void set_self_auth_id(hc_handle handle, struct uint8_buff *data) +{ + app_call2_ret_void(APP_CALL_SET_SELF_AUTH_ID, set_self_auth_id, hc_handle, handle, struct uint8_buff *, data); +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_ble_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_ble_adapter.c new file mode 100755 index 0000000..561bb81 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_ble_adapter.c @@ -0,0 +1,327 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Common operations on the ble adapter, including session creation and destruction. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include +#include "app_call.h" +#include "ohos_bt_gatt.h" +#include "ohos_bt_def.h" +#include "ohos_bt_gatt_server.h" + +BdAddr* GetLocalAddress(void) +{ + app_call0(APP_CALL_GET_LOCAL_ADDRESS, GetLocalAddress, BdAddr*); + return NULL; +} + +bool GetLocalName(unsigned char *localName, unsigned char *length) +{ + app_call2(APP_CALL_GET_LOCAL_NAME, GetLocalName, bool, unsigned char *, localName, unsigned char *, length); + return false; +} + +bool SetLocalName(unsigned char *localName, unsigned char length) +{ + app_call2(APP_CALL_SET_LOCAL_NAME, SetLocalName, bool, unsigned char *, localName, unsigned char, length); + return false; +} + +bool BluetoothFactoryReset(void) +{ + app_call0(APP_CALL_BLUETOOTH_FACTORY_RESET, BluetoothFactoryReset, bool); + return false; +} + +int GetBtScanMode(void) +{ + app_call0(APP_CALL_GET_BT_SCAN_MODE, GetBtScanMode, int); + return 0; +} + +bool SetBtScanMode(int mode, int duration) +{ + app_call2(APP_CALL_SET_BT_SCAN_MODE, SetBtScanMode, bool, int, mode, int, duration); + return false; +} + +int ReadBtMacAddr(unsigned char *mac, unsigned int len) +{ + app_call2(APP_CALL_READ_BT_MAC_ADDR, ReadBtMacAddr, int, unsigned char *, mac, unsigned int, len); + return 0; +} + +bool GetPariedDevicesNum(unsigned int *number) +{ + app_call1(APP_CALL_GET_PARIED_DEVICES_NUM, GetPariedDevicesNum, bool, unsigned int *, number); + return false; +} + +int GetPairState(void) +{ + app_call0(APP_CALL_GET_PAIR_STATE, GetPairState, int); + return 0; +} + +bool RemovePair(const BdAddr addr) +{ + app_call1(APP_CALL_REMOVE_PAIR, RemovePair, bool, const BdAddr, addr); + return false; +} + +bool RemoveAllPairs(void) +{ + app_call0(APP_CALL_REMOVE_ALL_PAIRS, RemoveAllPairs, bool); + return false; +} + +bool ReadRemoteRssiValue(const BdAddr *bdAddr, int transport) +{ + app_call2(APP_CALL_READ_REMOTE_RSSI_VALUE, ReadRemoteRssiValue, bool, const BdAddr *, bdAddr, int, transport); + return false; +} + +bool IsAclConnected(BdAddr *addr) +{ + app_call1(APP_CALL_IS_ACL_CONNECTED, IsAclConnected, bool, BdAddr *, addr); + return false; +} + +bool DisconnectRemoteDevice(BdAddr *addr) +{ + app_call1(APP_CALL_DISCONNECT_REMOTE_DEVICE, DisconnectRemoteDevice, bool, BdAddr *, addr); + return false; +} + +bool ConnectRemoteDevice(BdAddr *addr) +{ + app_call1(APP_CALL_CONNECT_REMOTE_DEVICE, ConnectRemoteDevice, bool, BdAddr *, addr); + return false; +} + +int InitBtStack(void) +{ + app_call0(APP_CALL_INIT_BT_STACK, InitBtStack, int); + return 0; +} + +int EnableBtStack(void) +{ + app_call0(APP_CALL_ENABLE_BT_STACK, EnableBtStack, int); + return 0; +} + +int DisableBtStack(void) +{ + app_call0(APP_CALL_DISABLE_BT_STACK, DisableBtStack, int); + return 0; +} + +int SetDeviceName(const char *name, unsigned int len) +{ + app_call2(APP_CALL_SET_DEVICE_NAME, SetDeviceName, int, const char *, name, unsigned int, len); + return 0; +} + +int BleSetAdvData(int advId, const BleConfigAdvData *data) +{ + app_call2(APP_CALL_BLE_SET_ADV_DATA, BleSetAdvData, int, int, advId, const BleConfigAdvData *, data); + return 0; +} + +int BleStartAdv(int advId, const BleAdvParams *param) +{ + app_call2(APP_CALL_BLE_START_ADV, BleStartAdv, int, int, advId, const BleAdvParams *, param); + return 0; +} + +int BleStopAdv(int advId) +{ + app_call1(APP_CALL_BLE_STOP_ADV, BleStopAdv, int, int, advId); + return 0; +} + +int BleUpdateAdv(int advId, const BleAdvParams *param) +{ + app_call2(APP_CALL_BLE_UPDATE_ADV, BleUpdateAdv, int, int, advId, const BleAdvParams *, param); + return 0; +} + +int BleSetSecurityIoCap(BleIoCapMode mode) +{ + app_call1(APP_CALL_BLE_SET_SECURITY_IO_CAP, BleSetSecurityIoCap, int, BleIoCapMode, mode); + return 0; +} + +int BleSetSecurityAuthReq(BleAuthReqMode mode) +{ + app_call1(APP_CALL_BLE_SET_SECURITY_AUTH_REQ, BleSetSecurityAuthReq, int, BleAuthReqMode, mode); + return 0; +} + +int BleGattSecurityRsp(BdAddr bdAddr, bool accept) +{ + app_call2(APP_CALL_BLE_GATT_SECURITY_RSP, BleGattSecurityRsp, int, BdAddr, bdAddr, bool, accept); + return 0; +} + +int BleScanFilterParamSetup(BleAdvScanFilterParam *param) +{ + app_call1(APP_CALL_BLE_SCAN_FILTER_PARAM_SETUP, BleScanFilterParamSetup, int, BleAdvScanFilterParam *, param); + return 0; +} + +int BleScanFilterAddRemove(BleAdvScanFilterCondition *param) +{ + app_call1(APP_CALL_BLE_SCAN_FILTER_ADD_REMOVE, BleScanFilterAddRemove, int, BleAdvScanFilterCondition *, param); + return 0; +} + +int BleScanFilterClear(int clientId, int filterIndex) +{ + app_call2(APP_CALL_BLE_SCAN_FILTER_CLEAR, BleScanFilterClear, int, int, clientId, int, filterIndex); + return 0; +} + +int BleScanFilterEnable(int clientId, bool enable) +{ + app_call2(APP_CALL_BLE_SCAN_FILTER_ENABLE, BleScanFilterEnable, int, int, clientId, bool, enable); + return 0; +} + +int BleSetScanParameters(int clientId, BleScanParams *param) +{ + app_call2(APP_CALL_BLE_SET_SCAN_PARAMETERS, BleSetScanParameters, int, int, clientId, BleScanParams *, param); + return 0; +} + +int BleStartScan(void) +{ + app_call0(APP_CALL_BLE_START_SCAN, BleStartScan, int); + return 0; +} + +int BleStopScan(void) +{ + app_call0(APP_CALL_BLE_STOP_SCAN, BleStopScan, int); + return 0; +} + +int BleGattRegisterCallbacks(BtGattCallbacks *func) +{ + app_call1(APP_CALL_BLE_GATT_REGISTER_CALLBACKS, BleGattRegisterCallbacks, int, BtGattCallbacks *, func); + return 0; +} + +int BleStartAdvEx(int *advId, const StartAdvRawData rawData, BleAdvParams advParam) +{ + app_call3(APP_CALL_BLE_START_ADV_EX, BleStartAdvEx, int, int *, advId, + const StartAdvRawData, rawData, BleAdvParams, advParam); + return 0; +} + +int BleGattsRegister(BtUuid appUuid) +{ + app_call1(APP_CALL_BLE_GATTS_REGISTER, BleGattsRegister, int, BtUuid, appUuid); + return 0; +} + +int BleGattsUnRegister(int serverId) +{ + app_call1(APP_CALL_BLE_GATTS_UN_REGISTER, BleGattsUnRegister, int, int, serverId); + return 0; +} + +int BleGattsDisconnect(int serverId, BdAddr bdAddr, int connId) +{ + app_call3(APP_CALL_BLE_GATTS_DISCONNECT, BleGattsDisconnect, int, int, serverId, BdAddr, bdAddr, int, connId); + return 0; +} + +int BleGattsAddService(int serverId, BtUuid srvcUuid, bool isPrimary, int number) +{ + app_call4(APP_CALL_BLE_GATTS_ADD_SERVICE, BleGattsAddService, int, int, serverId, BtUuid, srvcUuid, + bool, isPrimary, int, number); + return 0; +} + +int BleGattsAddCharacteristic(int serverId, int srvcHandle, BtUuid characUuid, + int properties, int permissions) +{ + app_call5(APP_CALL_BLE_GATTS_ADD_CHARACTERISTIC, BleGattsAddCharacteristic, int, int, serverId, int, srvcHandle, + BtUuid, characUuid, int, properties, int, permissions); + return 0; +} + +int BleGattsAddDescriptor(int serverId, int srvcHandle, BtUuid descUuid, int permissions) +{ + app_call4(APP_CALL_BLE_GATTS_ADD_DESCRIPTOR, BleGattsAddDescriptor, int, int, serverId, int, srvcHandle, + BtUuid, descUuid, int, permissions); + return 0; +} + +int BleGattsStartService(int serverId, int srvcHandle) +{ + app_call2(APP_CALL_BLE_GATTS_START_SERVICE, BleGattsStartService, int, int, serverId, int, srvcHandle); + return 0; +} + +int BleGattsStopService(int serverId, int srvcHandle) +{ + app_call2(APP_CALL_BLE_GATTS_STOP_SERVICE, BleGattsStopService, int, int, serverId, int, srvcHandle); + return 0; +} + +int BleGattsDeleteService(int serverId, int srvcHandle) +{ + app_call2(APP_CALL_BLE_GATTS_DELETE_SERVICE, BleGattsDeleteService, int, int, serverId, int, srvcHandle); + return 0; +} + +int BleGattsClearServices(int serverId) +{ + app_call1(APP_CALL_BLE_GATTS_CLEAR_SERVICES, BleGattsClearServices, int, int, serverId); + return 0; +} + +int BleGattsSendResponse(int serverId, GattsSendRspParam *param) +{ + app_call2(APP_CALL_BLE_GATTS_SEND_RESPONSE, BleGattsSendResponse, int, int, serverId, GattsSendRspParam *, param); + return 0; +} + +int BleGattsSendIndication(int serverId, GattsSendIndParam *param) +{ + app_call2(APP_CALL_BLE_GATTS_SEND_INDICATION, BleGattsSendIndication, int, + int, serverId, GattsSendIndParam *, param); + return 0; +} + +int BleGattsSetEncryption(BdAddr bdAddr, BleSecAct secAct) +{ + app_call2(APP_CALL_BLE_GATTS_SET_ENCRYPTION, BleGattsSetEncryption, int, BdAddr, bdAddr, BleSecAct, secAct); + return 0; +} + +int BleGattsRegisterCallbacks(BtGattServerCallbacks *func) +{ + app_call1(APP_CALL_BLE_GATTS_REGISTER_CALLBACKS, BleGattsRegisterCallbacks, int, BtGattServerCallbacks *, func); + return 0; +} + +int BleGattsStartServiceEx(int *srvcHandle, BleGattService *srvcInfo) +{ + app_call2(APP_CALL_BLE_GATTS_START_SERVICE_EX, BleGattsStartServiceEx, int, int *, srvcHandle, + BleGattService *, srvcInfo); + return 0; +} + +int BleGattsStopServiceEx(int srvcHandle) +{ + app_call1(APP_CALL_BLE_GATTS_STOP_SERVICE_EX, BleGattsStopServiceEx, int, int, srvcHandle); + return 0; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_ble_main.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_ble_main.c new file mode 100755 index 0000000..5557cb8 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_ble_main.c @@ -0,0 +1,59 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Common operations on the ble main, including session creation and destruction. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_bt_api.h" + +void HILINK_GetDeviceSn(unsigned int len, char *sn) +{ + app_call2_ret_void(APP_CALL_HILINK_GET_DEVICE_SN, HILINK_GetDeviceSn, unsigned int, len, char *, sn); +} + +int HILINK_GetSubProdId(char *subProdId, int len) +{ + app_call2(APP_CALL_HILINK_GET_SUB_PROD_ID, HILINK_GetSubProdId, int, char *, subProdId, int, len); + return 0; +} + +int HILINK_BT_GetDevSurfacePower(char *power) +{ + app_call1(APP_CALL_HILINK_BT_GET_DEV_SURFACE_POWER, HILINK_BT_GetDevSurfacePower, int, char *, power); + return 0; +} + +HILINK_BT_DevInfo *HILINK_BT_GetDevInfo(void) +{ + app_call0(APP_CALL_HILINK_BT_GET_DEV_INFO, HILINK_BT_GetDevInfo, HILINK_BT_DevInfo *); + return NULL; +} + +int HILINK_GetCustomInfo(char *customInfo, unsigned int len) +{ + app_call2(APP_CALL_HILINK_GET_CUSTOM_INFO, HILINK_GetCustomInfo, int, char *, customInfo, unsigned int, len); + return 0; +} + +int HILINK_GetManuId(char *manuId, unsigned int len) +{ + app_call2(APP_CALL_HILINK_GET_MANU_ID, HILINK_GetManuId, int, char *, manuId, unsigned int, len); + return 0; +} + +int HILINK_BT_GetMacAddr(unsigned char *mac, unsigned int len) +{ + app_call2(APP_CALL_HILINK_BT_GET_MAC_ADDR, HILINK_BT_GetMacAddr, int, unsigned char *, mac, unsigned int, len); + return 0; +} + +int getDeviceVersion(char* *firmwareVer, char* *softwareVer, char* *hardwareVer) +{ + app_call3(APP_CALL_GET_DEVICE_VERSION, getDeviceVersion, int, char* *, firmwareVer, + char* *, softwareVer, char* *, hardwareVer); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_device.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_device.c new file mode 100755 index 0000000..4ee0437 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_device.c @@ -0,0 +1,68 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Source file for HiLink adaptation. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_device.h" + +#include "hilink_stdio_adapter.h" +int HILINK_GetDevInfo(HILINK_DevInfo *devinfo) +{ + app_call1(APP_CALL_HILINK_GET_DEV_INFO, HILINK_GetDevInfo, int, HILINK_DevInfo *, devinfo); + return 0; +} + +int HILINK_GetSvcInfo(HILINK_SvcInfo *svcInfo[], unsigned int size) +{ + app_call2(APP_CALL_HILINK_GET_SVC_INFO, HILINK_GetSvcInfo, int, HILINK_SvcInfo *[], svcInfo, unsigned int, size); + return 0; +} + +unsigned char *HILINK_GetAutoAc(void) +{ + app_call0(APP_CALL_HILINK_GET_AUTO_AC, HILINK_GetAutoAc, unsigned char *); + return NULL; +} + +int HILINK_PutCharState(const char *svcId, const char *payload, unsigned int len) +{ + app_call3(APP_CALL_HILINK_PUT_CHAR_STATE, HILINK_PutCharState, int, + const char *, svcId, const char *, payload, unsigned int, len); + return 0; +} + +int HILINK_ControlCharState(const char *payload, unsigned int len) +{ + app_call2(APP_CALL_HILINK_CONTROL_CHAR_STATE, HILINK_ControlCharState, int, + const char *, payload, unsigned int, len); + return 0; +} + +int HILINK_GetCharState(const char *svcId, const char *in, unsigned int inLen, char **out, unsigned int *outLen) +{ + app_call5(APP_CALL_HILINK_GET_CHAR_STATE, HILINK_GetCharState, int, const char *, svcId, + const char *, in, unsigned int, inLen, char **, out, unsigned int *, outLen); + return 0; +} + +int HILINK_GetPinCode(void) +{ + app_call0(APP_CALL_HILINK_GET_PIN_CODE, HILINK_GetPinCode, int); + return 0; +} + +void HILINK_NotifyDevStatus(int status) +{ + app_call1_ret_void(APP_CALL_HILINK_NOTIFY_DEV_STATUS, HILINK_NotifyDevStatus, int, status); +} + +int HILINK_ProcessBeforeRestart(int flag) +{ + app_call1(APP_CALL_HILINK_PROCESS_BEFORE_RESTART, HILINK_ProcessBeforeRestart, int, int, flag); + return 0; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_kv_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_kv_adapter.c new file mode 100755 index 0000000..9a120e3 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_kv_adapter.c @@ -0,0 +1,43 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Source file for HiLink adaptation. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ +#include "app_call.h" +#include "hilink_kv_adapter.h" + +int HILINK_KVStoreInit(const char *path, const char *key[], unsigned int num) +{ + app_call3(APP_CALL_HILINK_KVSTORE_INIT, HILINK_KVStoreInit, int, + const char *, path, const char *[], key, unsigned int, num); + return 0; +} + +int HILINK_SetValue(const char *key, unsigned int offset, const unsigned char *value, unsigned int len) +{ + app_call4(APP_CALL_HILINK_SET_VALUE, HILINK_SetValue, int, const char *, key, unsigned int, offset, + const unsigned char *, value, unsigned int, len); + return 0; +} + +int HILINK_GetValue(const char *key, unsigned int offset, unsigned char *value, unsigned int len) +{ + app_call4(APP_CALL_HILINK_GET_VALUE, HILINK_GetValue, int, const char *, key, unsigned int, offset, + unsigned char *, value, unsigned int, len); + return 0; +} + +void HILINK_DeleteValue(const char * key) +{ + app_call1_ret_void(APP_CALL_HILINK_DELETE_VALUE, HILINK_DeleteValue, const char *, key); +} + +int HILINK_GetFileName(const char *key, char *out, unsigned int len) +{ + app_call3(APP_CALL_HILINK_GET_FILE_NAME, HILINK_GetFileName, int, + const char *, key, char *, out, unsigned int, len); + return 0; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_mem_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_mem_adapter.c new file mode 100755 index 0000000..cf2573b --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_mem_adapter.c @@ -0,0 +1,27 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the memory interface at the system adaptation layer. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" + +void *HILINK_Malloc(unsigned int size) +{ + app_call1(APP_CALL_HILINK_MALLOC, HILINK_Malloc, void *, unsigned int, size); + return NULL; +} + +void HILINK_Free(void *pt) +{ + app_call1_ret_void(APP_CALL_HILINK_FREE, HILINK_Free, void *, pt); +} + +int HILINK_Memcmp(const void *buf1, const void *buf2, unsigned int len) +{ + app_call3(APP_CALL_HILINK_MEMCMP, HILINK_Memcmp, int, const void *, buf1, const void *, buf2, unsigned int, len); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_network_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_network_adapter.c new file mode 100755 index 0000000..7472b6d --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_network_adapter.c @@ -0,0 +1,65 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Network adaptation implementation. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" + +int HILINK_GetLocalIp(char *localIp, unsigned char len) +{ + app_call2(APP_CALL_HILINK_GET_LOCAL_IP, HILINK_GetLocalIp, int, char *, localIp, unsigned char, len); + return 0; +} + +int HILINK_GetMacAddr(unsigned char *mac, unsigned char len) +{ + app_call2(APP_CALL_HILINK_GET_MAC_ADDR, HILINK_GetMacAddr, int, unsigned char *, mac, unsigned char, len); + return 0; +} + +int HILINK_GetWiFiSsid(char *ssid, unsigned int *ssidLen) +{ + app_call2(APP_CALL_HILINK_GET_WI_FI_SSID, HILINK_GetWiFiSsid, int, char *, ssid, unsigned int *, ssidLen); + return 0; +} + +int HILINK_SetWiFiInfo(const char *ssid, unsigned int ssidLen, const char *pwd, unsigned int pwdLen) +{ + app_call4(APP_CALL_HILINK_SET_WI_FI_INFO, HILINK_SetWiFiInfo, int, + const char *, ssid, unsigned int, ssidLen, const char *, pwd, unsigned int, pwdLen); + return 0; +} + +void HILINK_ReconnectWiFi(void) +{ + app_call0_ret_void(APP_CALL_HILINK_RECONNECT_WI_FI, HILINK_ReconnectWiFi); +} + +int HILINK_ConnectWiFi(void) +{ + app_call0(APP_CALL_HILINK_CONNECT_WI_FI, HILINK_ConnectWiFi, int); + return 0; +} + +int HILINK_GetNetworkState(int *state) +{ + app_call1(APP_CALL_HILINK_GET_NETWORK_STATE, HILINK_GetNetworkState, int, int *, state); + return 0; +} + +int HILINK_GetWiFiBssid(unsigned char *bssid, unsigned char *bssidLen) +{ + app_call2(APP_CALL_HILINK_GET_WI_FI_BSSID, HILINK_GetWiFiBssid, int, + unsigned char *, bssid, unsigned char *, bssidLen); + return 0; +} + +int HILINK_GetWiFiRssi(signed char *rssi) +{ + app_call1(APP_CALL_HILINK_GET_WI_FI_RSSI, HILINK_GetWiFiRssi, int, signed char *, rssi); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_open_ota_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_open_ota_adapter.c new file mode 100755 index 0000000..c4a7286 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_open_ota_adapter.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: OTA Adaptation Implementation. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include +#include "app_call.h" + +bool HILINK_OtaAdapterFlashInit(void) +{ + app_call0(APP_CALL_HILINK_OTA_ADAPTER_FLASH_INIT, HILINK_OtaAdapterFlashInit, bool); + return false; +} + +unsigned int HILINK_OtaAdapterGetUpdateIndex(void) +{ + app_call0(APP_CALL_HILINK_OTA_ADAPTER_GET_UPDATE_INDEX, HILINK_OtaAdapterGetUpdateIndex, unsigned int); + return 0; +} + +int HILINK_OtaAdapterFlashErase(unsigned int size) +{ + app_call1(APP_CALL_HILINK_OTA_ADAPTER_FLASH_ERASE, HILINK_OtaAdapterFlashErase, int, unsigned int, size); + return 0; +} + +int HILINK_OtaAdapterFlashWrite(const unsigned char *buf, unsigned int bufLen) +{ + app_call2(APP_CALL_HILINK_OTA_ADAPTER_FLASH_WRITE, HILINK_OtaAdapterFlashWrite, int, + const unsigned char *, buf, unsigned int, bufLen); + return 0; +} + +int HILINK_OtaAdapterFlashRead(unsigned int offset, unsigned char *buf, unsigned int bufLen) +{ + app_call3(APP_CALL_HILINK_OTA_ADAPTER_FLASH_READ, HILINK_OtaAdapterFlashRead, int, + unsigned int, offset, unsigned char *, buf, unsigned int, bufLen); + return 0; +} + +bool HILINK_OtaAdapterFlashFinish(void) +{ + app_call0(APP_CALL_HILINK_OTA_ADAPTER_FLASH_FINISH, HILINK_OtaAdapterFlashFinish, bool); + return false; +} + +unsigned int HILINK_OtaAdapterFlashMaxSize(void) +{ + app_call0(APP_CALL_HILINK_OTA_ADAPTER_FLASH_MAX_SIZE, HILINK_OtaAdapterFlashMaxSize, unsigned int); + return 0; +} + +void HILINK_OtaAdapterRestart(int flag) +{ + app_call1_ret_void(APP_CALL_HILINK_OTA_ADAPTER_RESTART, HILINK_OtaAdapterRestart, int, flag); +} + +int HILINK_OtaStartProcess(int type) +{ + app_call1(APP_CALL_HILINK_OTA_START_PROCESS, HILINK_OtaStartProcess, int, int, type); + return 0; +} + +int HILINK_OtaEndProcess(int status) +{ + app_call1(APP_CALL_HILINK_OTA_END_PROCESS, HILINK_OtaEndProcess, int, int, status); + return 0; +} + +int HILINK_GetRebootFlag(void) +{ + app_call0(APP_CALL_HILINK_GET_REBOOT_FLAG, HILINK_GetRebootFlag, int); + return 0; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_open_ota_mcu_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_open_ota_mcu_adapter.c new file mode 100755 index 0000000..0fde38e --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_open_ota_mcu_adapter.c @@ -0,0 +1,31 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Upgrade and adaptation of the external MCU. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" + +int HILINK_GetMcuVersion(char *version, unsigned int inLen, unsigned int *outLen) +{ + app_call3(APP_CALL_HILINK_GET_MCU_VERSION, HILINK_GetMcuVersion, int, + char *, version, unsigned int, inLen, unsigned int *, outLen); + return 0; +} + +int HILINK_NotifyOtaStatus(int flag, unsigned int len, unsigned int type) +{ + app_call3(APP_CALL_HILINK_NOTIFY_OTA_STATUS, HILINK_NotifyOtaStatus, int, + int, flag, unsigned int, len, unsigned int, type); + return 0; +} + +int HILINK_NotifyOtaData(const unsigned char *data, unsigned int len, unsigned int offset) +{ + app_call3(APP_CALL_HILINK_NOTIFY_OTA_DATA, HILINK_NotifyOtaData, int, + const unsigned char *, data, unsigned int, len, unsigned int, offset); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_aes.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_aes.c new file mode 100755 index 0000000..ab9071c --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_aes.c @@ -0,0 +1,72 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the AES Encryption and Decryption Adaptation Layer Interfaces. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_sal_aes.h" + +int HILINK_SAL_AesGcmEncrypt(const HiLinkAesGcmParam *param, unsigned char *tag, + unsigned int tagLen, unsigned char *buf) +{ + app_call4(APP_CALL_HILINK_SAL_AES_GCM_ENCRYPT, HILINK_SAL_AesGcmEncrypt, int, + const HiLinkAesGcmParam *, param, unsigned char *, tag, unsigned int, tagLen, unsigned char *, buf); + return 0; +} + +int HILINK_SAL_AesGcmDecrypt(const HiLinkAesGcmParam *param, const unsigned char *tag, + unsigned int tagLen, unsigned char *buf) +{ + app_call4(APP_CALL_HILINK_SAL_AES_GCM_DECRYPT, HILINK_SAL_AesGcmDecrypt, int, + const HiLinkAesGcmParam *, param, const unsigned char *, tag, unsigned int, tagLen, unsigned char *, buf); + return 0; +} + +int HILINK_SAL_AddPadding(HiLinkPaddingMode mode, unsigned char *out, unsigned int outLen, unsigned int dataLen) +{ + app_call4(APP_CALL_HILINK_SAL_ADD_PADDING, HILINK_SAL_AddPadding, int, + HiLinkPaddingMode, mode, unsigned char *, out, unsigned int, outLen, unsigned int, dataLen); + return 0; +} + +int HILINK_SAL_GetPadding(HiLinkPaddingMode mode, const unsigned char *input, + unsigned int inputLen, unsigned int *dataLen) +{ + app_call4(APP_CALL_HILINK_SAL_GET_PADDING, HILINK_SAL_GetPadding, int, + HiLinkPaddingMode, mode, const unsigned char *, input, unsigned int, inputLen, unsigned int *, dataLen); + return 0; +} + +int HILINK_SAL_AesCbcEncrypt(const HiLinkAesCbcParam *param, unsigned char *buf) +{ + app_call2(APP_CALL_HILINK_SAL_AES_CBC_ENCRYPT, HILINK_SAL_AesCbcEncrypt, int, + const HiLinkAesCbcParam *, param, unsigned char *, buf); + return 0; +} + +int HILINK_SAL_AesCbcDecrypt(const HiLinkAesCbcParam *param, unsigned char *buf) +{ + app_call2(APP_CALL_HILINK_SAL_AES_CBC_DECRYPT, HILINK_SAL_AesCbcDecrypt, int, + const HiLinkAesCbcParam *, param, unsigned char *, buf); + return 0; +} + +int HILINK_SAL_AesCcmDecrypt(const HiLinkAesCcmParam *param, const unsigned char *tag, + unsigned int tagLen, unsigned char *buf) +{ + app_call4(APP_CALL_HILINK_SAL_AES_CCM_DECRYPT, HILINK_SAL_AesCcmDecrypt, int, + const HiLinkAesCcmParam *, param, const unsigned char *, tag, unsigned int, tagLen, unsigned char *, buf); + return 0; +} + +int HILINK_SAL_AesCcmEncrypt(const HiLinkAesCcmParam *param, unsigned char *tag, unsigned int tagLen, + unsigned char *buf) +{ + app_call4(APP_CALL_HILINK_SAL_AES_CCM_ENCRYPT, HILINK_SAL_AesCcmEncrypt, int, const HiLinkAesCcmParam *, param, + unsigned char *, tag, unsigned int, tagLen, unsigned char *, buf); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_base64.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_base64.c new file mode 100755 index 0000000..0737523 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_base64.c @@ -0,0 +1,26 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Base64 encoding and decoding adaptation layer interface implementation. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" + +int HILINK_SAL_Base64Encode(const unsigned char *inData, unsigned int inLen, + unsigned char *outData, unsigned int *outLen) +{ + app_call4(APP_CALL_HILINK_SAL_BASE64_ENCODE, HILINK_SAL_Base64Encode, int, + const unsigned char *, inData, unsigned int, inLen, unsigned char *, outData, unsigned int *, outLen); + return 0; +} + +int HILINK_SAL_Base64Decode(const unsigned char *inData, unsigned int inLen, + unsigned char *outData, unsigned int *outLen) +{ + app_call4(APP_CALL_HILINK_SAL_BASE64_DECODE, HILINK_SAL_Base64Decode, int, + const unsigned char *, inData, unsigned int, inLen, unsigned char *, outData, unsigned int *, outLen); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_drbg.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_drbg.c new file mode 100755 index 0000000..7a9e415 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_drbg.c @@ -0,0 +1,29 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of secure random number Adaptation Layer Interfaces. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_sal_drbg.h" + +HiLinkDrbgContext HILINK_SAL_DrbgInit(const char *custom) +{ + app_call1(APP_CALL_HILINK_SAL_DRBG_INIT, HILINK_SAL_DrbgInit, HiLinkDrbgContext, const char *, custom); + return NULL; +} + +void HILINK_SAL_DrbgDeinit(HiLinkDrbgContext ctx) +{ + app_call1_ret_void(APP_CALL_HILINK_SAL_DRBG_DEINIT, HILINK_SAL_DrbgDeinit, HiLinkDrbgContext, ctx); +} + +int HILINK_SAL_DrbgRandom(HiLinkDrbgContext ctx, unsigned char *out, unsigned int outLen) +{ + app_call3(APP_CALL_HILINK_SAL_DRBG_RANDOM, HILINK_SAL_DrbgRandom, int, + HiLinkDrbgContext, ctx, unsigned char *, out, unsigned int, outLen); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_kdf.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_kdf.c new file mode 100755 index 0000000..5d01816 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_kdf.c @@ -0,0 +1,25 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Key derivation algorithm adaptation layer interface implementation. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_sal_kdf.h" + +int HILINK_SAL_Hkdf(const HiLinkHkdfParam *param, unsigned char *key, unsigned int keyLen) +{ + app_call3(APP_CALL_HILINK_SAL_HKDF, HILINK_SAL_Hkdf, int, + const HiLinkHkdfParam *, param, unsigned char *, key, unsigned int, keyLen); + return 0; +} + +int HILINK_SAL_Pkcs5Pbkdf2Hmac(const HiLinkPbkdf2HmacParam *param, unsigned char *key, unsigned int keyLen) +{ + app_call3(APP_CALL_HILINK_SAL_PKCS5_PBKDF2_HMAC, HILINK_SAL_Pkcs5Pbkdf2Hmac, int, + const HiLinkPbkdf2HmacParam *, param, unsigned char *, key, unsigned int, keyLen); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_md.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_md.c new file mode 100755 index 0000000..b708fbf --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_md.c @@ -0,0 +1,51 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the Message Digest Algorithm Adaptation Layer Interface. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_sal_md.h" + +int HILINK_SAL_MdCalc(HiLinkMdType type, const unsigned char *inData, unsigned int inLen, + unsigned char *md, unsigned int mdLen) +{ + app_call5(APP_CALL_HILINK_SAL_MD_CALC, HILINK_SAL_MdCalc, int, HiLinkMdType, type, + const unsigned char *, inData, unsigned int, inLen, unsigned char *, md, unsigned int, mdLen); + return 0; +} + +int HILINK_SAL_HmacCalc(const HiLinkHmacParam *param, unsigned char *hmac, unsigned int hmacLen) +{ + app_call3(APP_CALL_HILINK_SAL_HMAC_CALC, HILINK_SAL_HmacCalc, int, const HiLinkHmacParam *, param, + unsigned char *, hmac, unsigned int, hmacLen); + return 0; +} + +HiLinkMdContext HILINK_SAL_MdInit(HiLinkMdType type) +{ + app_call1(APP_CALL_HILINK_SAL_MD_INIT, HILINK_SAL_MdInit, HiLinkMdContext, HiLinkMdType, type); + return NULL; +} + +int HILINK_SAL_MdUpdate(HiLinkMdContext ctx, const unsigned char *inData, unsigned int inLen) +{ + app_call3(APP_CALL_HILINK_SAL_MD_UPDATE, HILINK_SAL_MdUpdate, int, + HiLinkMdContext, ctx, const unsigned char *, inData, unsigned int, inLen); + return 0; +} + +int HILINK_SAL_MdFinish(HiLinkMdContext ctx, unsigned char *outData, unsigned int outLen) +{ + app_call3(APP_CALL_HILINK_SAL_MD_FINISH, HILINK_SAL_MdFinish, int, + HiLinkMdContext, ctx, unsigned char *, outData, unsigned int, outLen); + return 0; +} + +void HILINK_SAL_MdFree(HiLinkMdContext ctx) +{ + app_call1_ret_void(APP_CALL_HILINK_SAL_MD_FREE, HILINK_SAL_MdFree, HiLinkMdContext, ctx); +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_mpi.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_mpi.c new file mode 100755 index 0000000..d8e8aa7 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_mpi.c @@ -0,0 +1,75 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Multi-precision integer implementation. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_sal_mpi.h" + +HiLinkMpi HILINK_SAL_MpiInit(void) +{ + app_call0(APP_CALL_HILINK_SAL_MPI_INIT, HILINK_SAL_MpiInit, HiLinkMpi); + return NULL; +} + +void HILINK_SAL_MpiFree(HiLinkMpi mpi) +{ + app_call1_ret_void(APP_CALL_HILINK_SAL_MPI_FREE, HILINK_SAL_MpiFree, HiLinkMpi, mpi); +} + +int HILINK_SAL_MpiExpMod(HiLinkMpi x, HiLinkMpi a, HiLinkMpi e, HiLinkMpi n) +{ + app_call4(APP_CALL_HILINK_SAL_MPI_EXP_MOD, HILINK_SAL_MpiExpMod, int, + HiLinkMpi, x, HiLinkMpi, a, HiLinkMpi, e, HiLinkMpi, n); + return 0; +} + +int HILINK_SAL_MpiCmpInt(HiLinkMpi x, int64_t z) +{ + app_call2(APP_CALL_HILINK_SAL_MPI_CMP_INT, HILINK_SAL_MpiCmpInt, int, HiLinkMpi, x, int64_t, z); + return 0; +} + +int HILINK_SAL_MpiSubInt(HiLinkMpi x, HiLinkMpi a, int64_t b) +{ + app_call3(APP_CALL_HILINK_SAL_MPI_SUB_INT, HILINK_SAL_MpiSubInt, int, HiLinkMpi, x, HiLinkMpi, a, int64_t, b); + return 0; +} + +int HILINK_SAL_MpiCmpMpi(HiLinkMpi x, HiLinkMpi y) +{ + app_call2(APP_CALL_HILINK_SAL_MPI_CMP_MPI, HILINK_SAL_MpiCmpMpi, int, HiLinkMpi, x, HiLinkMpi, y); + return 0; +} + +int HILINK_SAL_MpiReadString(HiLinkMpi mpi, unsigned char radix, const char *s) +{ + app_call3(APP_CALL_HILINK_SAL_MPI_READ_STRING, HILINK_SAL_MpiReadString, int, + HiLinkMpi, mpi, unsigned char, radix, const char *, s); + return 0; +} + +int HILINK_SAL_MpiWriteString(HiLinkMpi mpi, unsigned int radix, char *buf, unsigned int *bufLen) +{ + app_call4(APP_CALL_HILINK_SAL_MPI_WRITE_STRING, HILINK_SAL_MpiWriteString, int, + HiLinkMpi, mpi, unsigned int, radix, char *, buf, unsigned int *, bufLen); + return 0; +} + +int HILINK_SAL_MpiReadBinary(HiLinkMpi mpi, const unsigned char *buf, unsigned int bufLen) +{ + app_call3(APP_CALL_HILINK_SAL_MPI_READ_BINARY, HILINK_SAL_MpiReadBinary, int, + HiLinkMpi, mpi, const unsigned char *, buf, unsigned int, bufLen); + return 0; +} + +int HILINK_SAL_MpiWriteBinary(HiLinkMpi mpi, unsigned char *buf, unsigned int bufLen) +{ + app_call3(APP_CALL_HILINK_SAL_MPI_WRITE_BINARY, HILINK_SAL_MpiWriteBinary, int, + HiLinkMpi, mpi, unsigned char *, buf, unsigned int, bufLen); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_rsa.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_rsa.c new file mode 100755 index 0000000..ecda703 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sal_rsa.c @@ -0,0 +1,52 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of RSA Encryption and Decryption Adaptation Layer Interfaces. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_sal_rsa.h" + +HiLinkRsaContext HILINK_SAL_RsaInit(HiLinkRsaPkcs1Mode padding, HiLinkMdType md) +{ + app_call2(APP_CALL_HILINK_SAL_RSA_INIT, HILINK_SAL_RsaInit, HiLinkRsaContext, + HiLinkRsaPkcs1Mode, padding, HiLinkMdType, md); + return NULL; +} + +void HILINK_SAL_RsaFree(HiLinkRsaContext ctx) +{ + app_call1_ret_void(APP_CALL_HILINK_SAL_RSA_FREE, HILINK_SAL_RsaFree, HiLinkRsaContext, ctx); +} + +int HILINK_SAL_RsaParamImport(HiLinkRsaContext ctx, const HiLinkRsaParam *param) +{ + app_call2(APP_CALL_HILINK_SAL_RSA_PARAM_IMPORT, HILINK_SAL_RsaParamImport, int, + HiLinkRsaContext, ctx, const HiLinkRsaParam *, param); + return 0; +} + +int HILINK_RsaPkcs1Verify(HiLinkRsaContext ctx, HiLinkMdType md, const unsigned char *hash, + unsigned int hashLen, const unsigned char *sig, unsigned int sigLen) +{ + app_call6(APP_CALL_HILINK_RSA_PKCS1_VERIFY, HILINK_RsaPkcs1Verify, int, HiLinkRsaContext, ctx, HiLinkMdType, md, + const unsigned char *, hash, unsigned int, hashLen, const unsigned char *, sig, unsigned int, sigLen); + return 0; +} + +int HILINK_RsaPkcs1Decrypt(const HiLinkRsaCryptParam *param, unsigned char *buf, unsigned int *len) +{ + app_call3(APP_CALL_HILINK_RSA_PKCS1_DECRYPT, HILINK_RsaPkcs1Decrypt, int, const HiLinkRsaCryptParam *, param, + unsigned char *, buf, unsigned int *, len); + return 0; +} + +int HILINK_RsaPkcs1Encrypt(const HiLinkRsaCryptParam *param, unsigned char *buf, unsigned int len) +{ + app_call3(APP_CALL_HILINK_RSA_PKCS1_ENCRYPT, HILINK_RsaPkcs1Encrypt, int, const HiLinkRsaCryptParam *, param, + unsigned char *, buf, unsigned int, len); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_socket_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_socket_adapter.c new file mode 100755 index 0000000..c476f65 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_socket_adapter.c @@ -0,0 +1,140 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the Network Socket Interface at the System Adaptation Layer. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_socket_adapter.h" + +int HILINK_GetAddrInfo(const char *nodename, const char *servname, + const HiLinkAddrInfo *hints, HiLinkAddrInfo **result) +{ + app_call4(APP_CALL_HILINK_GET_ADDR_INFO, HILINK_GetAddrInfo, int, const char *, nodename, const char *, servname, + const HiLinkAddrInfo *, hints, HiLinkAddrInfo **, result); + return 0; +} + +void HILINK_FreeAddrInfo(HiLinkAddrInfo *addrInfo) +{ + app_call1_ret_void(APP_CALL_HILINK_FREE_ADDR_INFO, HILINK_FreeAddrInfo, HiLinkAddrInfo *, addrInfo); +} + +int HILINK_Socket(HiLinkSocketDomain domain, HiLinkSocketType type, HiLinkSocketProto proto) +{ + app_call3(APP_CALL_HILINK_SOCKET, HILINK_Socket, int, + HiLinkSocketDomain, domain, HiLinkSocketType, type, HiLinkSocketProto, proto); + return 0; +} + +void HILINK_Close(int fd) +{ + app_call1_ret_void(APP_CALL_HILINK_CLOSE, HILINK_Close, int, fd); +} + +int HILINK_SetSocketOpt(int fd, HiLinkSocketOption option, const void *value, unsigned int len) +{ + app_call4(APP_CALL_HILINK_SET_SOCKET_OPT, HILINK_SetSocketOpt, int, int, fd, HiLinkSocketOption, option, + const void *, value, unsigned int, len); + return 0; +} + +int HILINK_Bind(int fd, const HiLinkSockaddr *addr, unsigned int addrLen) +{ + app_call3(APP_CALL_HILINK_BIND, HILINK_Bind, int, int, fd, const HiLinkSockaddr *, addr, unsigned int, addrLen); + return 0; +} + +int HILINK_Connect(int fd, const HiLinkSockaddr *addr, unsigned int addrLen) +{ + app_call3(APP_CALL_HILINK_CONNECT, HILINK_Connect, int, + int, fd, const HiLinkSockaddr *, addr, unsigned int, addrLen); + return 0; +} + +int HILINK_Recv(int fd, unsigned char *buf, unsigned int len) +{ + app_call3(APP_CALL_HILINK_RECV, HILINK_Recv, int, int, fd, unsigned char *, buf, unsigned int, len); + return 0; +} + +int HILINK_Send(int fd, const unsigned char *buf, unsigned int len) +{ + app_call3(APP_CALL_HILINK_SEND, HILINK_Send, int, int, fd, const unsigned char *, buf, unsigned int, len); + return 0; +} + +int HILINK_RecvFrom(int fd, unsigned char *buf, unsigned int len, + HiLinkSockaddr *from, unsigned int *fromLen) +{ + app_call5(APP_CALL_HILINK_RECV_FROM, HILINK_RecvFrom, int, int, fd, unsigned char *, buf, unsigned int, len, + HiLinkSockaddr *, from, unsigned int *, fromLen); + return 0; +} + +int HILINK_SendTo(int fd, const unsigned char *buf, unsigned int len, + const HiLinkSockaddr *to, unsigned int toLen) +{ + app_call5(APP_CALL_HILINK_SEND_TO, HILINK_SendTo, int, int, fd, const unsigned char *, buf, unsigned int, len, + const HiLinkSockaddr *, to, unsigned int, toLen); + return 0; +} + +int HILINK_Select(HiLinkFdSet *readSet, HiLinkFdSet *writeSet, HiLinkFdSet *exceptSet, unsigned int ms) +{ + app_call4(APP_CALL_HILINK_SELECT, HILINK_Select, int, HiLinkFdSet *, readSet, + HiLinkFdSet *, writeSet, HiLinkFdSet *, exceptSet, unsigned int, ms); + return 0; +} + +int HILINK_GetSocketErrno(int fd) +{ + app_call1(APP_CALL_HILINK_GET_SOCKET_ERRNO, HILINK_GetSocketErrno, int, int, fd); + return 0; +} + +unsigned int HILINK_Htonl(unsigned int hl) +{ + app_call1(APP_CALL_HILINK_HTONL, HILINK_Htonl, unsigned int, unsigned int, hl); + return 0; +} + +unsigned int HILINK_Ntohl(unsigned int nl) +{ + app_call1(APP_CALL_HILINK_NTOHL, HILINK_Ntohl, unsigned int, unsigned int, nl); + return 0; +} + +unsigned short HILINK_Htons(unsigned short hs) +{ + app_call1(APP_CALL_HILINK_HTONS, HILINK_Htons, unsigned short, unsigned short, hs); + return 0; +} + +unsigned short HILINK_Ntohs(unsigned short ns) +{ + app_call1(APP_CALL_HILINK_NTOHS, HILINK_Ntohs, unsigned short, unsigned short, ns); + return 0; +} + +unsigned int HILINK_InetAton(const char *ip, unsigned int *addr) +{ + app_call2(APP_CALL_HILINK_INET_ATON, HILINK_InetAton, unsigned int, const char *, ip, unsigned int *, addr); + return 0; +} + +unsigned int HILINK_InetAddr(const char *ip) +{ + app_call1(APP_CALL_HILINK_INET_ADDR, HILINK_InetAddr, unsigned int, const char *, ip); + return 0; +} + +const char *HILINK_InetNtoa(unsigned int addr, char *buf, unsigned int buflen) +{ + app_call3(APP_CALL_HILINK_INET_NTOA, HILINK_InetNtoa, const char *, + unsigned int, addr, char *, buf, unsigned int, buflen); + return NULL; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_softap_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_softap_adapter.c new file mode 100755 index 0000000..d573307 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_softap_adapter.c @@ -0,0 +1,22 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: SoftAP Adaptation Implementation. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" + +int HILINK_StartSoftAp(const char *ssid, unsigned int ssidLen) +{ + app_call2(APP_CALL_HILINK_START_SOFT_AP, HILINK_StartSoftAp, int, const char *, ssid, unsigned int, ssidLen); + return 0; +} + +int HILINK_StopSoftAp(void) +{ + app_call0(APP_CALL_HILINK_STOP_SOFT_AP, HILINK_StopSoftAp, int); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_stdio_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_stdio_adapter.c new file mode 100755 index 0000000..e6dd3e2 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_stdio_adapter.c @@ -0,0 +1,43 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the standard output interface of the system adaptation layer. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include +#include +#include "app_call.h" + +int HILINK_Vprintf(const char *format, va_list ap) +{ + app_call2(APP_CALL_HILINK_VPRINTF, HILINK_Vprintf, int, const char *, format, va_list, ap); + return 0; +} + +int HILINK_Printf(const char *format, ...) +{ + if (format == NULL) { + return 0; + } + va_list ap; + va_start(ap, format); + int ret = HILINK_Vprintf(format, ap); + va_end(ap); + + return ret; +} + +int HILINK_Rand(unsigned char *input, unsigned int len) +{ + app_call2(APP_CALL_HILINK_RAND, HILINK_Rand, int, unsigned char *, input, unsigned int, len); + return 0; +} + +int HILINK_Trng(unsigned char *input, unsigned int len) +{ + app_call2(APP_CALL_HILINK_TRNG, HILINK_Trng, int, unsigned char *, input, unsigned int, len); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_str_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_str_adapter.c new file mode 100755 index 0000000..47c8702 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_str_adapter.c @@ -0,0 +1,52 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the character string interface at the system adaptation layer. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" + +unsigned int HILINK_Strlen(const char *src) +{ + app_call1(APP_CALL_HILINK_STRLEN, HILINK_Strlen, unsigned int, const char *, src); + return 0; +} + +char *HILINK_Strchr(const char *str, int ch) +{ + app_call2(APP_CALL_HILINK_STRCHR, HILINK_Strchr, char *, const char *, str, int, ch); + return NULL; +} + +char *HILINK_Strrchr(const char *str, int ch) +{ + app_call2(APP_CALL_HILINK_STRRCHR, HILINK_Strrchr, char *, const char *, str, int, ch); + return NULL; +} + +int HILINK_Atoi(const char *str) +{ + app_call1(APP_CALL_HILINK_ATOI, HILINK_Atoi, int, const char *, str); + return 0; +} + +char *HILINK_Strstr(const char *str1, const char *str2) +{ + app_call2(APP_CALL_HILINK_STRSTR, HILINK_Strstr, char *, const char *, str1, const char *, str2); + return NULL; +} + +int HILINK_Strcmp(const char *str1, const char *str2) +{ + app_call2(APP_CALL_HILINK_STRCMP, HILINK_Strcmp, int, const char *, str1, const char *, str2); + return 0; +} + +int HILINK_Strncmp(const char *str1, const char *str2, unsigned int len) +{ + app_call3(APP_CALL_HILINK_STRNCMP, HILINK_Strncmp, int, const char *, str1, const char *, str2, unsigned int, len); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sys_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sys_adapter.c new file mode 100755 index 0000000..fabe297 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_sys_adapter.c @@ -0,0 +1,23 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: System adaptation layer interface implementation. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_sys_adapter.h" + +int HILINK_Restart(void) +{ + app_call0(APP_CALL_HILINK_RESTART, HILINK_Restart, int); + return 0; +} + +unsigned char HILINK_GetSystemBootReason(void) +{ + app_call0(APP_CALL_HILINK_GET_SYSTEM_BOOT_REASON, HILINK_GetSystemBootReason, unsigned char); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_thread_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_thread_adapter.c new file mode 100755 index 0000000..5411da3 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_thread_adapter.c @@ -0,0 +1,97 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Thread adaptation layer interface. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_thread_adapter.h" + +HiLinkTaskId HILINK_CreateTask(HiLinkTaskParam *param) +{ + app_call1(APP_CALL_HILINK_CREATE_TASK, HILINK_CreateTask, HiLinkTaskId, HiLinkTaskParam *, param); + return NULL; +} + +int HILINK_ThreadSuspend(HiLinkTaskId handle) +{ + app_call1(APP_CALL_HILINK_THREAD_SUSPEND, HILINK_ThreadSuspend, int, HiLinkTaskId, handle); + return 0; +} + +int HILINK_ThreadResume(HiLinkTaskId handle) +{ + app_call1(APP_CALL_HILINK_THREAD_RESUME, HILINK_ThreadResume, int, HiLinkTaskId, handle); + return 0; +} + +void HILINK_DeleteTask(HiLinkTaskId handle) +{ + app_call1_ret_void(APP_CALL_HILINK_DELETE_TASK, HILINK_DeleteTask, HiLinkTaskId, handle); +} + +HiLinkTaskId HILINK_GetCurrentTaskId(void) +{ + app_call0(APP_CALL_HILINK_GET_CURRENT_TASK_ID, HILINK_GetCurrentTaskId, HiLinkTaskId); + return NULL; +} + +HiLinkMutexId HILINK_MutexCreate(void) +{ + app_call0(APP_CALL_HILINK_MUTEX_CREATE, HILINK_MutexCreate, HiLinkMutexId); + return NULL; +} + +int HILINK_MutexLock(HiLinkMutexId mutex, unsigned int ms) +{ + app_call2(APP_CALL_HILINK_MUTEX_LOCK, HILINK_MutexLock, int, HiLinkMutexId, mutex, unsigned int, ms); + return 0; +} + +int HILINK_MutexUnlock(HiLinkMutexId mutex) +{ + app_call1(APP_CALL_HILINK_MUTEX_UNLOCK, HILINK_MutexUnlock, int, HiLinkMutexId, mutex); + return 0; +} + +void HILINK_MutexDestroy(HiLinkMutexId mutex) +{ + app_call1_ret_void(APP_CALL_HILINK_MUTEX_DESTROY, HILINK_MutexDestroy, HiLinkMutexId, mutex); +} + +HiLinkSemId HILINK_SemCreate(unsigned int count) +{ + app_call1(APP_CALL_HILINK_SEM_CREATE, HILINK_SemCreate, HiLinkSemId, unsigned int, count); + return NULL; +} + +int HILINK_SemWait(HiLinkSemId handle, unsigned int ms) +{ + app_call2(APP_CALL_HILINK_SEM_WAIT, HILINK_SemWait, int, HiLinkSemId, handle, unsigned int, ms); + return 0; +} + +int HILINK_SemPost(HiLinkSemId handle) +{ + app_call1(APP_CALL_HILINK_SEM_POST, HILINK_SemPost, int, HiLinkSemId, handle); + return 0; +} + +void HILINK_SemDestroy(HiLinkSemId handle) +{ + app_call1_ret_void(APP_CALL_HILINK_SEM_DESTROY, HILINK_SemDestroy, HiLinkSemId, handle); +} + +int HILINK_MilliSleep(unsigned int ms) +{ + app_call1(APP_CALL_HILINK_MILLI_SLEEP, HILINK_MilliSleep, int, unsigned int, ms); + return 0; +} + +void HILINK_SchedYield(void) +{ + app_call0_ret_void(APP_CALL_HILINK_SCHED_YIELD, HILINK_SchedYield); +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_time_adapter.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_time_adapter.c new file mode 100755 index 0000000..00b8841 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_time_adapter.c @@ -0,0 +1,23 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the Time Adaptation Layer Interface. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_time_adapter.h" + +int HILINK_GetOsTime(HiLinkTimeval *time) +{ + app_call1(APP_CALL_HILINK_GET_OS_TIME, HILINK_GetOsTime, int, HiLinkTimeval *, time); + return 0; +} + +int HILINK_GetUtcTime(HiLinkTimeval *time) +{ + app_call1(APP_CALL_HILINK_GET_UTC_TIME, HILINK_GetUtcTime, int, HiLinkTimeval *, time); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_tls_client.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_tls_client.c new file mode 100755 index 0000000..8237252 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_hilink_tls_client.c @@ -0,0 +1,62 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Common operations on the TLS client, including session creation and destruction. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "app_call.h" +#include "hilink_tls_client.h" + +HiLinkTlsClient *HILINK_TlsClientCreate(const char *custom) +{ + app_call1(APP_CALL_HILINK_TLS_CLIENT_CREATE, HILINK_TlsClientCreate, HiLinkTlsClient *, const char *, custom); + return NULL; +} + +int HILINK_SetTlsClientOption(HiLinkTlsClient *ctx, HiLinkTlsOption option, const void *value, unsigned int len) +{ + app_call4(APP_CALL_HILINK_SET_TLS_CLIENT_OPTION, HILINK_SetTlsClientOption, int, + HiLinkTlsClient *, ctx, HiLinkTlsOption, option, const void *, value, unsigned int, len); + return 0; +} + +int HILINK_TlsClientConnect(HiLinkTlsClient *ctx) +{ + app_call1(APP_CALL_HILINK_TLS_CLIENT_CONNECT, HILINK_TlsClientConnect, int, HiLinkTlsClient *, ctx); + return 0; +} + +int HILINK_TlsClientGetContextFd(HiLinkTlsClient *ctx) +{ + app_call1(APP_CALL_HILINK_TLS_CLIENT_GET_CONTEXT_FD, HILINK_TlsClientGetContextFd, int, HiLinkTlsClient *, ctx); + return 0; +} + +int HILINK_TlsClientRead(HiLinkTlsClient *ctx, unsigned char *buf, size_t len) +{ + app_call3(APP_CALL_HILINK_TLS_CLIENT_READ, HILINK_TlsClientRead, int, + HiLinkTlsClient *, ctx, unsigned char *, buf, size_t, len); + return 0; +} + +int HILINK_TlsClientWrite(HiLinkTlsClient *ctx, const unsigned char *buf, size_t len) +{ + app_call3(APP_CALL_HILINK_TLS_CLIENT_WRITE, HILINK_TlsClientWrite, int, + HiLinkTlsClient *, ctx, const unsigned char *, buf, size_t, len); + return 0; +} + +bool HILINK_TlsClientIsValidCert(HiLinkTlsClient *ctx) +{ + app_call1(APP_CALL_HILINK_TLS_CLIENT_IS_VALID_CERT, HILINK_TlsClientIsValidCert, bool, HiLinkTlsClient *, ctx); + return false; +} + +int HILINK_TlsClientFreeResource(HiLinkTlsClient *ctx) +{ + app_call1(APP_CALL_HILINK_TLS_CLIENT_FREE_RESOURCE, HILINK_TlsClientFreeResource, int, HiLinkTlsClient *, ctx); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_mbed_tls.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_mbed_tls.c new file mode 100755 index 0000000..107c5ad --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_mbed_tls.c @@ -0,0 +1,228 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of cJSON in sdk side. \n + * + * History: \n + * 2024-11-26, Create file. \n + */ + +#include "app_call.h" +#include "mbedtls/md.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/bignum.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/hkdf.h" +#include "mbedtls/entropy.h" +#include "mbedtls/sha256.h" +#include "mbedtls/ecp.h" + +const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) +{ + app_call1(APP_CALL_MBEDTLS_MD_INFO_FROM_TYPE, mbedtls_md_info_from_type, const mbedtls_md_info_t *, + mbedtls_md_type_t, md_type); + return NULL; +} + +void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx) +{ + app_call1_ret_void(APP_CALL_MBEDTLS_CTR_DRBG_INIT, mbedtls_ctr_drbg_init, mbedtls_ctr_drbg_context *, ctx); +} + +void mbedtls_mpi_init(mbedtls_mpi *X) +{ + app_call1_ret_void(APP_CALL_MBEDTLS_MPI_INIT, mbedtls_mpi_init, mbedtls_mpi *, X); +} + +void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx) +{ + app_call1_ret_void(APP_CALL_MBEDTLS_ECDH_INIT, mbedtls_ecdh_init, mbedtls_ecdh_context *, ctx); +} + +int mbedtls_ctr_drbg_random(void *p_rng, unsigned char *output, size_t output_len) +{ + app_call3(APP_CALL_MBEDTLS_CTR_DRBG_RANDOM, mbedtls_ctr_drbg_random, int, + void *, p_rng, unsigned char *, output, size_t, output_len); + return 0; +} + +int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen) +{ + app_call3(APP_CALL_MBEDTLS_MPI_READ_BINARY, mbedtls_mpi_read_binary, int, + mbedtls_mpi *, X, const unsigned char *, buf, size_t, buflen); + return 0; +} + +int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + app_call3(APP_CALL_MBEDTLS_MPI_SUB_MPI, mbedtls_mpi_sub_mpi, int, + mbedtls_mpi *, X, const mbedtls_mpi *, A, const mbedtls_mpi *, B); + return 0; +} + +int mbedtls_hkdf(const mbedtls_md_info_t *md, const unsigned char *salt, + size_t salt_len, const unsigned char *ikm, size_t ikm_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len) +{ + app_call9(APP_CALL_MBEDTLS_HKDF, mbedtls_hkdf, int, + const mbedtls_md_info_t *, md, const unsigned char *, salt, + size_t, salt_len, const unsigned char *, ikm, size_t, ikm_len, + const unsigned char *, info, size_t, info_len, + unsigned char *, okm, size_t, okm_len); + return 0; +} + +unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info) +{ + app_call1(APP_CALL_MBEDTLS_MD_GET_SIZE, mbedtls_md_get_size, unsigned char, + const mbedtls_md_info_t *, md_info); + return 0; +} + +void mbedtls_entropy_init(mbedtls_entropy_context *ctx) +{ + app_call1_ret_void(APP_CALL_MBEDTLS_ENTROPY_INIT, mbedtls_entropy_init, mbedtls_entropy_context *, ctx); +} + +int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y ) +{ + app_call2(APP_CALL_MBEDTLS_MPI_CMP_MPI, mbedtls_mpi_cmp_mpi, int, + const mbedtls_mpi *, X, const mbedtls_mpi *, Y); + return 0; +} + +typedef int (*func_rng_t)(void *, unsigned char *, size_t); +int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + func_rng_t f_rng, + void *p_rng) +{ + app_call6(APP_CALL_MBEDTLS_ECDH_COMPUTE_SHARED, mbedtls_ecdh_compute_shared, int, + mbedtls_ecp_group *, grp, mbedtls_mpi *, z, + const mbedtls_ecp_point *, Q, const mbedtls_mpi *, d, + func_rng_t, f_rng, + void *, p_rng); + return 0; +} + +int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR) +{ + app_call5(APP_CALL_MBEDTLS_MPI_EXP_MOD, mbedtls_mpi_exp_mod, int, + mbedtls_mpi *, X, const mbedtls_mpi *, A, + const mbedtls_mpi *, E, const mbedtls_mpi *, N, + mbedtls_mpi *, prec_RR); + return 0; +} + +int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + app_call3(APP_CALL_MBEDTLS_MPI_MOD_MPI, mbedtls_mpi_mod_mpi, int, + mbedtls_mpi *, R, const mbedtls_mpi *, A, const mbedtls_mpi *, B); + return 0; +} + +int mbedtls_sha256(const unsigned char *input, size_t ilen, unsigned char *output, int is224) +{ + app_call4(APP_CALL_MBEDTLS_SHA256, mbedtls_sha256, int, + const unsigned char *, input, size_t, ilen, unsigned char *, output, int, is224); + return 0; +} + +void mbedtls_mpi_free(mbedtls_mpi *X) +{ + app_call1_ret_void(APP_CALL_MBEDTLS_MPI_FREE, mbedtls_mpi_free, mbedtls_mpi *, X); +} + +int mbedtls_mpi_write_binary(const mbedtls_mpi *X, unsigned char *buf, size_t buflen) +{ + app_call3(APP_CALL_MBEDTLS_MPI_WRITE_BINARY, mbedtls_sha256, int, + const mbedtls_mpi *, X, unsigned char *, buf, size_t, buflen); + return 0; +} + +int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + app_call3(APP_CALL_MBEDTLS_MPI_MUL_MPI, mbedtls_mpi_mul_mpi, int, + mbedtls_mpi *, X, const mbedtls_mpi *, A, const mbedtls_mpi *, B); + return 0; +} + +int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + app_call3(APP_CALL_MBEDTLS_MPI_ADD_MPI, mbedtls_mpi_add_mpi, int, + mbedtls_mpi *, X, const mbedtls_mpi *, A, const mbedtls_mpi *, B); + return 0; +} + +int mbedtls_entropy_func(void *data, unsigned char *output, size_t len) +{ + app_call3(APP_CALL_MBEDTLS_ENTROPY_FUNC, mbedtls_entropy_func, int, + void *, data, unsigned char *, output, size_t, len); + return 0; +} + +void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx) +{ + app_call1_ret_void(APP_CALL_MBEDTLS_ECDH_FREE, mbedtls_ecdh_free, mbedtls_ecdh_context *, ctx); +} + +int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N) +{ + app_call3(APP_CALL_MBEDTLS_MPI_INV_MOD, mbedtls_mpi_inv_mod, int, + mbedtls_mpi *, X, const mbedtls_mpi *, A, const mbedtls_mpi *, N); + return 0; +} + +typedef int (*func_entropy_t)(void *, unsigned char *, size_t); +int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx, + func_entropy_t f_entropy, + void *p_entropy, const unsigned char *custom, size_t len) +{ + app_call5(APP_CALL_MBEDTLS_CTR_DRBG_SEED, mbedtls_ctr_drbg_seed, int, + mbedtls_ctr_drbg_context *, ctx, + func_entropy_t, f_entropy, + void *, p_entropy, const unsigned char *, custom, size_t, len); + return 0; +} + +void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx) +{ + app_call1_ret_void(APP_CALL_MBEDTLS_CTR_DRBG_FREE, mbedtls_ctr_drbg_free, mbedtls_ctr_drbg_context *, ctx); + +} + +int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y) +{ + app_call2(APP_CALL_MBEDTLS_MPI_COPY, mbedtls_mpi_copy, int, + mbedtls_mpi *, X, const mbedtls_mpi *, Y); + return 0; +} + +void mbedtls_entropy_free( mbedtls_entropy_context *ctx ) +{ + app_call1_ret_void(APP_CALL_MBEDTLS_ENTROPY_FREE, mbedtls_entropy_free, mbedtls_entropy_context *, ctx); +} + +int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ) +{ + app_call2(APP_CALL_MBEDTLS_ECP_GROUP_LOAD, mbedtls_ecp_group_load, int, + mbedtls_ecp_group *, grp, mbedtls_ecp_group_id, id); + return 0; +} + +int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign ) +{ + app_call3(APP_CALL_MBEDTLS_MPI_SAFE_COND_SWAP, mbedtls_mpi_safe_cond_swap, int, + mbedtls_mpi *, X, mbedtls_mpi *, Y, unsigned char, assign); + return 0; +} + +int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ) +{ + app_call2(APP_CALL_MBEDTLS_MPI_LSET, mbedtls_mpi_lset, int, + mbedtls_mpi *, X, mbedtls_mpi_sint, z); + return 0; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_oh_sle_connection_manager.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_oh_sle_connection_manager.c new file mode 100755 index 0000000..eb747f5 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_oh_sle_connection_manager.c @@ -0,0 +1,27 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the sle connection manager. \n + * + * History: \n + * 2024-11-13, Create file. \n + */ + +#include "app_call.h" +#include "oh_sle_common.h" +#include "oh_sle_connection_manager.h" +#include "oh_sle_errcode.h" + +ErrCodeType SleDisconnectRemoteDevice(const SleAddr *addr) +{ + app_call1(APP_CALL_SLE_DISCONNECT_REMOTE_DEVICE, SleDisconnectRemoteDevice, ErrCodeType, + const SleAddr *, addr); + return OH_ERRCODE_SLE_MAX; +} + +ErrCodeType SleConnectionRegisterCallbacks(SleConnectionCallbacks *func) +{ + app_call1(APP_CALL_SLE_CONNECTION_REGISTER_CALLBACKS, SleConnectionRegisterCallbacks, ErrCodeType, + SleConnectionCallbacks *, func); + return OH_ERRCODE_SLE_MAX; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_oh_sle_device_discovery.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_oh_sle_device_discovery.c new file mode 100755 index 0000000..0e80f92 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_oh_sle_device_discovery.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the sle device discovery. \n + * + * History: \n + * 2024-11-13, Create file. \n + */ + +#include "app_call.h" +#include "oh_sle_device_discovery.h" +#include "oh_sle_errcode.h" + +ErrCodeType EnableSle(void) +{ + app_call0(APP_CALL_ENABLE_SLE, EnableSle, ErrCodeType); + return OH_ERRCODE_SLE_MAX; +} + +ErrCodeType DisableSle(void) +{ + app_call0(APP_CALL_DISABLE_SLE, DisableSle, ErrCodeType); + return OH_ERRCODE_SLE_MAX; +} + +ErrCodeType SleGetLocalAddr(SleAddr *addr) +{ + app_call1(APP_CALL_SLE_GET_LOCAL_ADDR, SleGetLocalAddr, ErrCodeType, + SleAddr *, addr); + return OH_ERRCODE_SLE_MAX; +} + +ErrCodeType SleSetLocalName(const uint8_t *name, uint8_t len) +{ + app_call2(APP_CALL_SLE_SET_LOCAL_NAME, SleSetLocalName, ErrCodeType, + const uint8_t *, name, uint8_t, len); + return OH_ERRCODE_SLE_MAX; +} + +ErrCodeType SleSetAnnounceData(uint8_t announceId, const SleAnnounceData *data) +{ + app_call2(APP_CALL_SLE_SET_ANNOUNCE_DATA, SleSetAnnounceData, ErrCodeType, + uint8_t, announceId, const SleAnnounceData *, data); + return OH_ERRCODE_SLE_MAX; +} + +ErrCodeType SleSetAnnounceParam(uint8_t announceId, const SleAnnounceParam *param) +{ + app_call2(APP_CALL_SLE_SET_ANNOUNCE_PARAM, SleSetAnnounceParam, ErrCodeType, + uint8_t, announceId, const SleAnnounceParam *, param); + return OH_ERRCODE_SLE_MAX; +} + +ErrCodeType SleStartAnnounce(uint8_t announceId) +{ + app_call1(APP_CALL_SLE_START_ANNOUNCE, SleStartAnnounce, ErrCodeType, + uint8_t, announceId); + return OH_ERRCODE_SLE_MAX; +} + +ErrCodeType SleStopAnnounce(uint8_t announceId) +{ + app_call1(APP_CALL_SLE_STOP_ANNOUNCE, SleStopAnnounce, ErrCodeType, + uint8_t, announceId); + return OH_ERRCODE_SLE_MAX; +} + +ErrCodeType SleAnnounceSeekRegisterCallbacks(SleAnnounceSeekCallbacks *func) +{ + app_call1(APP_CALL_SLE_ANNOUNCE_SEEK_REGISTER_CALLBACKS, SleAnnounceSeekRegisterCallbacks, ErrCodeType, + SleAnnounceSeekCallbacks *, func); + return OH_ERRCODE_SLE_MAX; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_oh_sle_ssap_server.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_oh_sle_ssap_server.c new file mode 100755 index 0000000..e29624d --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/app_uapi/uapi_oh_sle_ssap_server.c @@ -0,0 +1,77 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * + * Description: Implementation of the sle ssap server. \n + * + * History: \n + * 2024-11-13, Create file. \n + */ + +#include "app_call.h" +#include "oh_sle_ssap_server.h" +#include "errcode.h" + +errcode_t ssapsRegisterServer(SleUuid *appUuid, uint8_t *serverId) +{ + app_call2(APP_CALL_SSAPS_REGISTER_SERVER, ssapsRegisterServer, errcode_t, + SleUuid *, appUuid, uint8_t *, serverId); + return ERRCODE_FAIL; +} + +errcode_t SsapsAddServiceSync(uint8_t serverId, SleUuid *serviceUuid, bool isPrimary, uint16_t *handle) +{ + app_call4(APP_CALL_SSAPS_ADD_SERVICE_SYNC, SsapsAddServiceSync, errcode_t, + uint8_t, serverId, SleUuid *, serviceUuid, bool, isPrimary, uint16_t *, handle); + return ERRCODE_FAIL; +} + +errcode_t SsapsAddPropertySync(uint8_t serverId, uint16_t serviceHandle, SsapsPropertyInfo *property, + uint16_t *handle) +{ + app_call4(APP_CALL_SSAPS_ADD_PROPERTY_SYNC, SsapsAddPropertySync, errcode_t, + uint8_t, serverId, uint16_t, serviceHandle, SsapsPropertyInfo *, property, uint16_t *, handle); + return ERRCODE_FAIL; +} + +errcode_t SsapsAddDescriptorSync(uint8_t serverId, uint16_t serviceHandle, uint16_t propertyHandle, + SsapsDescInfo *descriptor) +{ + app_call4(APP_CALL_SSAPS_ADD_DESCRIPTOR_SYNC, SsapsAddDescriptorSync, errcode_t, + uint8_t, serverId, uint16_t, serviceHandle, uint16_t, propertyHandle, SsapsDescInfo *, descriptor); + return ERRCODE_FAIL; +} + +errcode_t SsapsStartService(uint8_t serverId, uint16_t serviceHandle) +{ + app_call2(APP_CALL_SSAPS_START_SERVICE, SsapsStartService, errcode_t, + uint8_t, serverId, uint16_t, serviceHandle); + return ERRCODE_FAIL; +} + +errcode_t SsapsDeleteAllServices(uint8_t serverId) +{ + app_call1(APP_CALL_SSAPS_DELETE_ALL_SERVICES, SsapsDeleteAllServices, errcode_t, + uint8_t, serverId); + return ERRCODE_FAIL; +} + +errcode_t SsapsSendResponse(uint8_t serverId, uint16_t connId, SsapsSendRsp *param) +{ + app_call3(APP_CALL_SSAPS_SEND_RESPONSE, SsapsSendResponse, errcode_t, + uint8_t, serverId, uint16_t, connId, SsapsSendRsp *, param); + return ERRCODE_FAIL; +} + +errcode_t SsapsNotifyIndicate(uint8_t serverId, uint16_t connId, SsapsNtfInd *param) +{ + app_call3(APP_CALL_SSAPS_NOTIFY_INDICATE, SsapsNotifyIndicate, errcode_t, + uint8_t, serverId, uint16_t, connId, SsapsNtfInd *, param); + return ERRCODE_FAIL; +} + +errcode_t SsapsRegisterCallbacks(SsapsCallbacks *func) +{ + app_call1(APP_CALL_SSAPS_REGISTER_CALLBACKS, SsapsRegisterCallbacks, errcode_t, + SsapsCallbacks *, func); + return ERRCODE_FAIL; +} \ No newline at end of file diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_call_entry.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_call_entry.c new file mode 100755 index 0000000..6177950 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_call_entry.c @@ -0,0 +1,127 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: hilink call entry. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#include "hilink_call_entry.h" +#include "hilink_function_mapping.h" +#include "func_call.h" + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0L +#else +#define NULL ((void*)0) +#endif +#endif + +#define BITS_PER_BYTES 8 +#define CRC32_TBL_SIZE 256 + +unsigned int g_crc32_tbl[CRC32_TBL_SIZE] = { 0 }; + +static api_get g_app_api_get = NULL; + +void *get_app_api_addr(unsigned int index, const char *prototype) +{ + return g_app_api_get == NULL ? NULL : g_app_api_get(index, prototype); +} + +static void init_crc32_table(void) +{ + for (unsigned int i = 0; i < CRC32_TBL_SIZE; i++) { + unsigned int tmp = i; + for (unsigned char bit = 0; bit < BITS_PER_BYTES; bit++) { + if ((tmp & 1) != 0) { + /* 0xEDB88320 为 CRC32 的生成多项式的反转 */ + tmp = (tmp >> 1) ^ 0xEDB88320; + } else { + tmp = tmp >> 1; + } + } + g_crc32_tbl[i] = tmp; + } +} + +static unsigned int prototype_cal_crc32(const char *input) +{ + unsigned int checksum = 0xFFFFFFFF; + for (unsigned int i = 0; input[i] != 0; i++) { + if (input[i] == ' ') { + continue; + } + checksum = (checksum >> BITS_PER_BYTES) ^ (g_crc32_tbl[(checksum ^ input[i]) & 0xFF]); + } + return ~checksum; +} + +/* copy ram */ +static void copy_bin_to_ram(unsigned int *start_addr, + const unsigned int *const load_addr, unsigned int size) +{ + unsigned int i; + + for (i = 0; i < size / sizeof(unsigned int); i++) { + *(start_addr + i) = *(load_addr + i); + } +} + +/* init ram value */ +static void init_mem_value(unsigned int *start_addr, + const unsigned int *const end_addr, unsigned int init_val) +{ + unsigned int *dest = start_addr; + + while (dest < end_addr) { + *dest = init_val; + dest++; + } +} + +static void *hilink_api_get(unsigned int index, const char *prototype) +{ + const struct mapping_tbl *hilink_call_tbl = get_hilink_mapping_tbl(); + unsigned int size = get_hilink_mapping_tbl_size(); + if (hilink_call_tbl == NULL || size == 0) { + return NULL; + } + + unsigned int checksum = prototype_cal_crc32(prototype); + if ((index < size) && (hilink_call_tbl[index].checksum == checksum)) { + return hilink_call_tbl[index].addr; + } + /* 对应校验和不匹配,尝试全部匹配 */ + for (unsigned int i = 0; i < size; i++) { + if (hilink_call_tbl[i].checksum == checksum) { + return hilink_call_tbl[i].addr; + } + } + return NULL; +} + +static void hilink_info_entry(api_get *hilink_get, api_get app_get) +{ + if (hilink_get == NULL || app_get == NULL) { + return; + } +#ifndef CHIP_EDA + /* copy sram_text from flash to SRAM */ + copy_bin_to_ram(&__sram_text_begin__, &__sram_text_load__, (unsigned int)&__sram_text_size__); + /* copy data from flash to SRAM */ + copy_bin_to_ram(&__data_begin__, &__data_load__, (unsigned int)&__data_size__); + /* clear bss on SRAM */ + init_mem_value(&__bss_begin__, &__bss_end__, 0); +#endif + + *hilink_get = hilink_api_get; + g_app_api_get = app_get; + init_crc32_table(); +} + +__attribute__ ((used, section(".hilink_info"))) struct hilink_info_stru hilink_info = { + hilink_info_entry, +}; diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_call_entry.h b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_call_entry.h new file mode 100755 index 0000000..e6c97d6 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_call_entry.h @@ -0,0 +1,32 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: hilink call entry. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#ifndef HILINK_CALL_ENTRY_H +#define HILINK_CALL_ENTRY_H + +#ifdef __cplusplus +extern "C" { +#endif + +void *get_app_api_addr(unsigned int index, const char *prototype); + +extern unsigned int __bss_begin__; +extern unsigned int __bss_end__; +extern unsigned int __data_begin__; +extern unsigned int __data_load__; +extern unsigned int __data_size__; + +extern unsigned int __sram_text_begin__; +extern unsigned int __sram_text_load__; +extern unsigned int __sram_text_size__; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_function_mapping.c b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_function_mapping.c new file mode 100755 index 0000000..37b4c02 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_function_mapping.c @@ -0,0 +1,89 @@ + +#include "hilink_function_mapping.h" +#include "func_call.h" +#include "func_call_list.h" +#include "hilink.h" +#include "hilink_log_manage.h" +#include "ble_cfg_net_api.h" +#include "hilink_bt_function.h" +#include "hilink_custom.h" +#include "hilink_sle_api.h" +#include "hilink_quick_netcfg_api.h" +#include "hilink_quick_netcfg_adapter.h" +#include "hilink_bt_api.h" +#include "hilink_device.h" +#include "hilink_network_adapter.h" +#include "hilink_socket_adapter.h" + +static const struct mapping_tbl g_hilink_call_tbl[HILINK_CALL_MAX] = { + [HILINK_CALL_HILINK_REGISTER_BASE_CALLBACK] = { HILINK_RegisterBaseCallback, 0xBEC62B3A }, + [HILINK_CALL_HILINK_MAIN] = { HILINK_Main, 0x1B90717B }, + [HILINK_CALL_HILINK_RESET] = { HILINK_Reset, 0xABD8C9AD }, + [HILINK_CALL_HILINK_SET_SDK_ATTR] = { HILINK_SetSdkAttr, 0x15D3BE15 }, + [HILINK_CALL_HILINK_GET_SDK_ATTR] = { HILINK_GetSdkAttr, 0x60977111 }, + [HILINK_CALL_HILINK_RESTORE_FACTORY_SETTINGS] = { HILINK_RestoreFactorySettings, 0xA022C59C }, + [HILINK_CALL_HILINK_GET_DEV_STATUS] = { HILINK_GetDevStatus, 0xEF399A97 }, + [HILINK_CALL_HILINK_GET_SDK_VERSION] = { HILINK_GetSdkVersion, 0xE8B1D1D2 }, + [HILINK_CALL_HILINK_REPORT_CHAR_STATE] = { HILINK_ReportCharState, 0xD981EE97 }, + [HILINK_CALL_HILINK_IS_REGISTER] = { HILINK_IsRegister, 0x2F4C881D }, + [HILINK_CALL_HILINK_GET_NETWORKING_MODE] = { HILINK_GetNetworkingMode, 0x0D3D30D8 }, + [HILINK_CALL_HILINK_GET_REGISTER_STATUS] = { HILINK_GetRegisterStatus, 0x165FA46B }, + [HILINK_CALL_HILINK_SET_SCHEDULE_INTERVAL] = { HILINK_SetScheduleInterval, 0xEB1F07B4 }, + [HILINK_CALL_HILINK_SET_MONITOR_SCHEDULE_INTERVAL] = { HILINK_SetMonitorScheduleInterval, 0xB8F1AECE }, + [HILINK_CALL_HILINK_SET_NET_CONFIG_MODE] = { HILINK_SetNetConfigMode, 0xA4335DFC }, + [HILINK_CALL_HILINK_GET_NET_CONFIG_MODE] = { HILINK_GetNetConfigMode, 0x7388E123 }, + [HILINK_CALL_HILINK_SET_NET_CONFIG_TIMEOUT] = { HILINK_SetNetConfigTimeout, 0x4641EDD1 }, + [HILINK_CALL_HILINK_SET_OTA_BOOT_TIME] = { HILINK_SetOtaBootTime, 0xAF31DFED }, + [HILINK_CALL_HILINK_ENABLE_KITFRAMEWORK] = { HILINK_EnableKitframework, 0xB616EBF0 }, + [HILINK_CALL_HILINK_ENABLE_BATCH_CONTROL] = { HILINK_EnableBatchControl, 0xA9900778 }, + [HILINK_CALL_HILINK_ENABLE_PROCESS_DEL_ERR_CODE] = { HILINK_EnableProcessDelErrCode, 0xC03C4467 }, + [HILINK_CALL_HILINK_UNBIND_DEVICE] = { HILINK_UnbindDevice, 0xD3CBCD65 }, + [HILINK_CALL_HILINK_SET_DEVICE_INSTALL_TYPE] = { HILINK_SetDeviceInstallType, 0x40F51D66 }, + [HILINK_CALL_HILINK_GET_DEV_SETUP_TYPE] = { HILINK_GetDevSetupType, 0xCBE0FF99 }, + [HILINK_CALL_HILINK_ENABLE_DEV_ID_INHERIT] = { HILINK_EnableDevIdInherit, 0x8506BA06 }, + [HILINK_CALL_HILINK_NOTIFY_NETWORK_AVAILABLE] = { HILINK_NotifyNetworkAvailable, 0x448D8BEB }, + [HILINK_CALL_HILINK_SET_LOG_LEVEL] = { HILINK_SetLogLevel, 0x6CDA8E9E }, + [HILINK_CALL_HILINK_GET_LOG_LEVEL] = { HILINK_GetLogLevel, 0x79BE4C8B }, + [HILINK_CALL_HILINK_REGISTER_GET_AC_V2_FUNC] = { HILINK_RegisterGetAcV2Func, 0xF15449A4 }, + [HILINK_CALL_BLE_CFG_NET_INIT] = { BLE_CfgNetInit, 0xDEFEB22F }, + [HILINK_CALL_BLE_CFG_NET_DE_INIT] = { BLE_CfgNetDeInit, 0x342B09F0 }, + [HILINK_CALL_BLE_CFG_NET_ADV_CTRL] = { BLE_CfgNetAdvCtrl, 0x3683E17D }, + [HILINK_CALL_BLE_CFG_NET_ADV_UPDATE] = { BLE_CfgNetAdvUpdate, 0x699DA475 }, + [HILINK_CALL_BLE_CFG_NET_DIS_CONNECT] = { BLE_CfgNetDisConnect, 0xD08A2F07 }, + [HILINK_CALL_BLE_SEND_CUSTOM_DATA] = { BLE_SendCustomData, 0x9EDA59B9 }, + [HILINK_CALL_BLE_GET_ADV_TYPE] = { BLE_GetAdvType, 0x9A96CD0E }, + [HILINK_CALL_BLE_SET_ADV_TYPE] = { BLE_SetAdvType, 0x468B0892 }, + [HILINK_CALL_BLE_SET_ADV_NAME_MPP] = { BLE_SetAdvNameMpp, 0x24120EE9 }, + [HILINK_CALL_BLE_NEAR_DISCOVERY_INIT] = { BLE_NearDiscoveryInit, 0x6B86A8BB }, + [HILINK_CALL_BLE_NEAR_DISCOVERY_ENABLE] = { BLE_NearDiscoveryEnable, 0x4B250B35 }, + [HILINK_CALL_HILINK_BT_GET_TASK_STACK_SIZE] = { HILINK_BT_GetTaskStackSize, 0xE0E8B8A1 }, + [HILINK_CALL_HILINK_BT_SET_TASK_STACK_SIZE] = { HILINK_BT_SetTaskStackSize, 0xE77FE8A1 }, + [HILINK_CALL_HILINK_BT_SET_SDK_EVENT_CALLBACK] = { HILINK_BT_SetSdkEventCallback, 0x3F50CF8B }, + [HILINK_CALL_HILINK_BT_HARD_REVOKE] = { HILINK_BT_HardRevoke, 0x018FA5A9 }, + [HILINK_CALL_HILINK_REG_WI_FI_RECOVERY_CALLBACK] = { HILINK_RegWiFiRecoveryCallback, 0x1475DDA9 }, + [HILINK_CALL_HILINK_REGISTER_ERRNO_CALLBACK] = { HILINK_RegisterErrnoCallback, 0x32141DAF }, + [HILINK_CALL_HILINK_SET_PROT_TYPE] = { HILINK_SetProtType, 0x1F5C4D9C }, + [HILINK_CALL_HILINK_ENABLE_PRESCAN] = { HILINK_EnablePrescan, 0x5D7F8DC8 }, + [HILINK_CALL_HILINK_SET_NET_CONFIG_INFO] = { HILINK_SetNetConfigInfo, 0xE3CB582D }, + [HILINK_CALL_HILINK_SET_SOFT_APMODE] = { HILINK_SetSoftAPMode, 0x0DB0EA88 }, + [HILINK_CALL_HILINK_REQUEST_REG_INFO] = { HILINK_RequestRegInfo, 0x23396BF6 }, + [HILINK_CALL_HILINK_DIAGNOSIS_INFO_RECORD] = { HILINK_DiagnosisInfoRecord, 0xBC0A30D6 }, + [HILINK_CALL_HILINK_ENABLE_SLE] = { HILINK_EnableSle, 0x8B968BEE }, + [HILINK_CALL_HILINK_SET_QUICK_CFG_COMMON_LOADER] = { HILINK_SetQuickCfgCommonLoader, 0x77AB6014 }, + [HILINK_CALL_HILINK_START_QUICK_CFG] = { HILINK_StartQuickCfg, 0x036385A6 }, + [HILINK_CALL_HILINK_FRAME_PARSE] = { HILINK_FrameParse, 0x8BB35701 }, + [HILINK_CALL_HILINK_QUICK_CFG_CMD_PARSE] = { HILINK_QuickCfgCmdParse, 0xD274404A }, + [HILINK_CALL_HILINK_SET_DEVICE_TYPE] = { HILINK_SetDeviceType, 0x9BFA2434 }, + [HILINK_CALL_HILINK_SET_QUICK_CFG_WIFI_LOADER] = { HILINK_SetQuickCfgWifiLoader, 0x8E7321F6 }, + [HILINK_CALL_HILINK_ENABLE_QUICK_NET_CFG] = { HILINK_EnableQuickNetCfg, 0x3FEA98B7 }, +}; + +const struct mapping_tbl *get_hilink_mapping_tbl(void) +{ + return g_hilink_call_tbl; +} + +unsigned int get_hilink_mapping_tbl_size(void) +{ + return HILINK_CALL_MAX; +} diff --git a/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_function_mapping.h b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_function_mapping.h new file mode 100755 index 0000000..f75dd44 --- /dev/null +++ b/application/samples/wifi/hilink_indie_upgrade/address_mapping/hilinksdk/hilink_function_mapping.h @@ -0,0 +1,23 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2025. All rights reserved. + * + * Description: hilink function mapping. \n + * + * History: \n + * 2024-01-27, Create file. \n + */ + +#ifndef HILINK_FUNCTION_MAPPING_H +#define HILINK_FUNCTION_MAPPING_H + +#ifdef __cplusplus +extern "C" { +#endif + +const struct mapping_tbl *get_hilink_mapping_tbl(void); +unsigned int get_hilink_mapping_tbl_size(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/application/samples/wifi/ohos_connect/CMakeLists.txt b/application/samples/wifi/ohos_connect/CMakeLists.txt new file mode 100755 index 0000000..2842656 --- /dev/null +++ b/application/samples/wifi/ohos_connect/CMakeLists.txt @@ -0,0 +1,131 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(HILINK_LIBS_DIR ${ROOT_DIR}/application/samples/wifi/libhilink) + +if (NOT DEFINES MATCHES "CONFIG_SUPPORT_HILINK_INDIE_UPGRADE") +set(COMPONENT_NAME "hilinkdevicesdk") +set(LIBS ${HILINK_LIBS_DIR}/lib${COMPONENT_NAME}.a) +set(WHOLE_LINK + true +) +build_component() + +set(COMPONENT_NAME "hilinkota") +set(LIBS ${HILINK_LIBS_DIR}/lib${COMPONENT_NAME}.a) +set(WHOLE_LINK + true +) +build_component() + +set(COMPONENT_NAME "hilinkbtsdk") +set(LIBS ${HILINK_LIBS_DIR}/lib${COMPONENT_NAME}.a) +set(WHOLE_LINK + true +) +build_component() + +if (DEFINES MATCHES "SUPPORT_QUICK_NETCFG") +set(COMPONENT_NAME "hilinkquickcfg") +set(LIBS ${HILINK_LIBS_DIR}/lib${COMPONENT_NAME}.a) +set(WHOLE_LINK + true +) +build_component() +endif() + +endif() + +set(COMPONENT_NAME "hilink") + +set(CMAKE_HILINK_SOURCE_DIR + ${CMAKE_CURRENT_SOURCE_DIR}) + +set(SOURCES + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/product/hilink_device.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_kv_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_open_ota_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_sal_base64.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_sal_md.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_socket_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_str_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_time_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_mem_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_open_ota_mcu_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_sal_drbg.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_sal_mpi.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_softap_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_sys_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_tls_client.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_network_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_sal_aes.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_sal_kdf.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_sal_rsa.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_stdio_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_thread_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_ble_adapter.c + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/entry/hilink_entry.c +) + +if (DEFINES MATCHES "SUPPORT_MINIMALIST_NETCFG" OR DEFINES MATCHES "SUPPORT_BLE_ANCILLAY_NETCFG") + list(APPEND SOURCES ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/entry/hilink_ble_main.c) +endif() +if (DEFINES MATCHES "SUPPORT_SOFTAP_NETCFG") + list(APPEND SOURCES ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/entry/hilink_wifi_main.c) +endif() +if (DEFINES MATCHES "SUPPORT_QUICK_NETCFG") + list(APPEND SOURCES ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/hilink_quick_netcfg_demo.c) +endif() + +if (DEFINES MATCHES "CONFIG_SUPPORT_HILINK_INDIE_UPGRADE") + list(APPEND SOURCES ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/entry/hilink_indie_upgrade_main.c) +endif() +set(PUBLIC_HEADER + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/include/ + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/product/ + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/include/ +) + +set(PRIVATE_HEADER + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/product/ + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/include/ + ${CMAKE_HILINK_SOURCE_DIR}/hilink_adapt/adapter/include/ + ${ROOT_DIR}/protocol/wifi/source/host/inc/liteOS + ${ROOT_DIR}/open_source/mbedtls/mbedtls_v3.1.0/harden/src/internal_include + ${ROOT_DIR}/include +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -Wno-error=logical-op + -Wno-error=sign-compare + -Wno-error=jump-misses-init + -Wno-sign-compare + -Wno-jump-misses-init + -Wno-error=unused-parameter + -Wno-unused-parameter + -Wno-unused-but-set-variable + -Wno-error=unused-variable +) + +set(PRIVATE_DEFINES + MBEDTLS_SHA256_ALT +) + +set(PUBLIC_DEFINES +) +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + false +) + +set(LIB_OUT_PATH ${BIN_DIR}/${CHIP}/libs/wifi/${TARGET_COMMAND}) + +build_component() \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_ble_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_ble_adapter.c new file mode 100755 index 0000000..9be827a --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_ble_adapter.c @@ -0,0 +1,1472 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: HiLink BLE file实现源文件(此文件为DEMO,需集成方适配修改) + */ + +#include +#include +#include + +#include "osal_list.h" +#include "securec.h" +#include "bts_le_gap.h" +#include "bts_gatt_client.h" +#include "bts_gatt_server.h" +#include "cmsis_os2.h" +#include "hilink_sal_defines.h" +#include "mac_addr.h" + +#include "ohos_bt_gatt.h" +#include "ohos_bt_def.h" +#include "ohos_bt_gatt_server.h" + +#include "oh_sle_device_discovery.h" + +#define UUID16_LEN 2 +#define UUID32_LEN 4 +#define UUID128_LEN 16 +#define BLE_MAX_SERVICES_NUMS 16 +#define BLE_HILINK_SERVER_LOG "[BLE_HILINK_SERVER]" +#define BLE_ADV_HANDLE_DEFAULT 1 +#define INVALID_SERVER_ID 0 +#define EXT_ADV_OR_SCAN_RSP_DATA_LEN 251 +#define MAX_READ_REQ_LEN 200 +#define BLE_MAX_CHAR_NUMS 10 + +static BtGattCallbacks *g_ble_gap_cb = NULL; +static BtGattServerCallbacks *g_ble_gatts_cb = NULL; + +static uint16_t g_services_handle[BLE_MAX_SERVICES_NUMS] = {0}; +static uint16_t g_server_request_id = 0; +static uint16_t g_srvc_handle = 0; +static uint16_t g_cb_chara_handle = 0; +static uint16_t g_cb_desc_handle = 0; +static uint16_t g_indicate_handle = 17; +static uint8_t g_io_cap_mode = 0; +static uint8_t g_sc_mode = 0; +static uint8_t g_gatt_write_flag = 0; /* 0:write 1:read */ +static uint8_t g_service_flag = 0; /* 0:enable 1:disable start service */ +static uint8_t g_server_id = INVALID_SERVER_ID; /* gatt server ID */ + +typedef struct { + int conn_id; + int attr_handle; /* The handle of the attribute to be read */ + BleGattServiceRead read; + BleGattServiceWrite write; + BleGattServiceIndicate indicate; + int hilinkAttrHandle; +} hilink_ble_gatt_func; + +static hilink_ble_gatt_func g_charas_func[BLE_MAX_CHAR_NUMS] = {{0}}; +static uint8_t g_chara_cnt = 0; + +static uint8_t g_hilink_group_cnt = 0; +static char g_hilink_group_uuid[][OHOS_BLE_UUID_MAX_LEN] = { + { 0x15, 0xF1, 0xE4, 0x00, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, + { 0x15, 0xF1, 0xE4, 0x01, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, + { 0x15, 0xF1, 0xE5, 0x00, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, + { 0x15, 0xF1, 0xE5, 0x01, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, + { 0x15, 0xF1, 0xE6, 0x00, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, + { 0x15, 0xF1, 0xE6, 0x02, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, + { 0x15, 0xF1, 0xE6, 0x01, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, + { 0x15, 0xF1, 0xE6, 0x10, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, + { 0x15, 0xF1, 0xE6, 0x11, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, + { 0x15, 0xF1, 0xE6, 0x12, 0xA2, 0x77, 0x43, 0xFC, 0xA4, 0x84, 0xDD, 0x39, 0xEF, 0x8A, 0x91, 0x00 }, +}; +static char g_hilink_cccd_uuid[UUID16_LEN] = { 0x29, 0x02 }; +static uint8_t g_chara_val[] = { 0x11, 0x22, 0x33, 0x44 }; +static uint8_t g_desc_val[] = { 0x55, 0x66, 0x77, 0x88 }; + +static void reverse_uuid(const uint8_t *input, int input_len, char *output, int output_len) +{ + if (input_len < output_len) { + return; + } + for (int i = 0; i < output_len; i++) { + output[i] = input[output_len - i - 1]; + } +} + +static BleGattServiceRead get_chara_read_func(int conn_id, int attr_handle) +{ + for (uint8_t i = 0; i < g_chara_cnt; i++) { + if ((g_charas_func[i].attr_handle == attr_handle)) { + return g_charas_func[i].read; + } + } + HILINK_SAL_ERROR("get_chara_read_func Not Found! \n"); + return NULL; +} + +static BleGattServiceWrite get_chara_write_func(int conn_id, int attr_handle) +{ + for (uint8_t i = 0; i < g_chara_cnt; i++) { + if (g_charas_func[i].attr_handle == attr_handle) { + return g_charas_func[i].write; + } + } + HILINK_SAL_ERROR("get_chara_write_func Not Found! \n"); + return NULL; +} + +static BleGattServiceIndicate get_chara_ind_func(int conn_id, int attr_handle) +{ + for (uint8_t i = 0; i < g_chara_cnt; i++) { + if (g_charas_func[i].attr_handle == attr_handle) { + return g_charas_func[i].indicate; + } + } + HILINK_SAL_ERROR("get_chara_ind_func Not Found! \n"); + return NULL; +} + +static int get_chara_handle(int hilinkAttrHandle) +{ + for (uint8_t i = 0; i < g_chara_cnt; i++) { + if (g_charas_func[i].hilinkAttrHandle == hilinkAttrHandle) { + return g_charas_func[i].attr_handle; + } + } + HILINK_SAL_ERROR("get_chara_handle Not Found! \n"); + return -1; +} + +static uint32_t perm_bt_to_bluez(uint32_t permissions) +{ + uint32_t perm = 0; + if (permissions & OHOS_GATT_PERMISSION_READ) { + perm |= GATT_ATTRIBUTE_PERMISSION_READ; + } + if (permissions & OHOS_GATT_PERMISSION_READ_ENCRYPTED) { + perm |= (GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_ENCRYPTION_NEED); + } + if (permissions & OHOS_GATT_PERMISSION_READ_ENCRYPTED_MITM) { + perm |= (GATT_ATTRIBUTE_PERMISSION_READ | + GATT_ATTRIBUTE_PERMISSION_ENCRYPTION_NEED | GATT_ATTRIBUTE_PERMISSION_MITM_NEED); + } + if (permissions & OHOS_GATT_PERMISSION_WRITE) { + perm |= GATT_ATTRIBUTE_PERMISSION_WRITE; + } + if (permissions & OHOS_GATT_PERMISSION_WRITE_ENCRYPTED) { + perm |= (GATT_ATTRIBUTE_PERMISSION_WRITE | GATT_ATTRIBUTE_PERMISSION_ENCRYPTION_NEED); + } + if (permissions & OHOS_GATT_PERMISSION_WRITE_ENCRYPTED_MITM) { + perm |= (GATT_ATTRIBUTE_PERMISSION_WRITE | + GATT_ATTRIBUTE_PERMISSION_ENCRYPTION_NEED | GATT_ATTRIBUTE_PERMISSION_MITM_NEED); + } + HILINK_SAL_DEBUG("convert %08x to %08x.\n", permissions, perm); + return perm; +} + +int SetBleAndSleAddrToStackFromNv(void) +{ + bd_addr_t set_ble_addr = {0}; + SleAddr set_sle_addr = {0}; + + int ret = get_dev_addr(set_ble_addr.addr, BD_ADDR_LEN, IFTYPE_BLE); + if (ret != ERRCODE_SUCC) { + HILINK_SAL_ERROR("get_dev_addr ble err=%d\n", ret); + return -1; + } + set_ble_addr.type = BT_ADDRESS_TYPE_PUBLIC_DEVICE_ADDRESS; + ret = gap_ble_set_local_addr(&set_ble_addr); + if (ret != ERRCODE_SUCC) { + HILINK_SAL_ERROR("gap_ble_set_local_addr err=%d\n", ret); + return -1; + } + ret = get_dev_addr(set_sle_addr.addr, OH_SLE_ADDR_LEN, IFTYPE_SLE); + if (ret != ERRCODE_SUCC) { + HILINK_SAL_ERROR("get_dev_addr sle err=%d\n", ret); + return -1; + } + set_sle_addr.type = OH_SLE_ADDRESS_TYPE_PUBLIC; + ret = SleSetLocalAddr(&set_sle_addr); + if (ret != OH_ERRCODE_SLE_SUCCESS) { + HILINK_SAL_ERROR("SleSetLocalAddr err=%d\n", ret); + return -1; + } + + HILINK_SAL_NOTICE("set ble stack addr success %02x:%02x:%02x:%02x:**:**\n", + set_ble_addr.addr[5], set_ble_addr.addr[4], set_ble_addr.addr[3], set_ble_addr.addr[2]); + HILINK_SAL_NOTICE("set sle stack addr success %02x:%02x:%02x:%02x:**:**\n", + set_sle_addr.addr[5], set_sle_addr.addr[4], set_sle_addr.addr[3], set_sle_addr.addr[2]); + return 0; +} + +bool EnableBle(void) +{ + return false; +} + +bool DisableBle(void) +{ + return false; +} + +bool EnableBt(void) +{ + return false; +} + +bool DisableBt(void) +{ + return false; +} + +/** + * @brief Get local host bluetooth address + * @return @c Local host bluetooth address + */ +BdAddr* GetLocalAddress(void) +{ + HILINK_SAL_DEBUG("%s GetLocalAddress enter.\n", BLE_HILINK_SERVER_LOG); + return NULL; +} + +/** + * @brief Get local host bluetooth name + * @param localName actual receiving device name + length - localName length, initail set length to zero, and call this func to set real length + * @return Local host bluetooth name + */ +bool GetLocalName(unsigned char *localName, unsigned char *length) +{ + (void)localName; + (void)length; + HILINK_SAL_DEBUG("%s GetLocalName enter.\n", BLE_HILINK_SERVER_LOG); + return false; +} + +/** + * @brief Set local device name. + * @param localName Device name. + length device name length + * @return Returns true if the operation is successful; + * returns false if the operation fails. + */ +bool SetLocalName(unsigned char *localName, unsigned char length) +{ + (void)localName; + (void)length; + HILINK_SAL_DEBUG("%s SetLocalName enter.\n", BLE_HILINK_SERVER_LOG); + return false; +} + +/** + * @brief Factory reset bluetooth service. + * @return Returns true if the operation is successful; + * returns false if the operation fails. + */ +bool BluetoothFactoryReset(void) +{ + return false; +} + +/** + * @brief Set device scan mode. + * @param mode Scan mode. + * @param duration Scan time, see details {@link GapBtScanMode} + * @return special mode + */ +int GetBtScanMode(void) +{ + return 0; +} + +/** + * @brief Set device scan mode. + * @param mode Scan mode, see details {@link GapBtScanMode}. + * @param duration Scan time. + * @return Returns true if the operation is successful; + * returns false if the operation fails. + */ +bool SetBtScanMode(int mode, int duration) +{ + (void)mode; + (void)duration; + return 0; +} + +/* + * @brief read bt mac address + * @param[in] mac addr + * @param[in] addr length + * @return 0-success, other-fail + */ +int ReadBtMacAddr(unsigned char *mac, unsigned int len) +{ + HILINK_SAL_DEBUG("%s ReadBtMacAddr enter.\n", BLE_HILINK_SERVER_LOG); + bd_addr_t get_addr = {0}; + int ret = gap_ble_get_local_addr(&get_addr); + if (ret != ERRCODE_SUCC) { + HILINK_SAL_ERROR("ret=%d\n", ret); + return -1; + } + HILINK_SAL_DEBUG("%s get ble mac %02x:%02x:%02x:%02x:**:**", BLE_HILINK_SERVER_LOG, + get_addr.addr[5], get_addr.addr[4], get_addr.addr[3], get_addr.addr[2]); + ret = memcpy_s(mac, len, get_addr.addr, sizeof(get_addr.addr)); + if (ret != EOK) { + HILINK_SAL_ERROR("ret=%d\n", ret); + return -1; + } + return 0; +} + +/* + * @brief Get paired devices. + * @param pairList - 按照maxPairNums申请的设备列表数组 + maxPairNums - 指定需要获取的设备列表最大个数 + realPairNums - 实际的配对设备列表个数 + * @return Returns true if the operation is successful; + * returns false if the operation fails. + */ +bool GetPariedDevicesNum(unsigned int *number) +{ + (void)number; + HILINK_SAL_DEBUG("%s GetPariedDevicesNum enter.\n", BLE_HILINK_SERVER_LOG); + return false; +} + +/** + * @brief Get device pair state. + * @param device Remote device. + * @return Returns device pair state. see detail {@link GapBtPairedState} + */ +int GetPairState(void) +{ + HILINK_SAL_DEBUG("%s GetPairState enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/** + * @brief Remove pair. + * @param BdAddr Remote device address. + * @return Returns true if the operation is successful; + * returns false if the operation fails. + */ +bool RemovePair(const BdAddr addr) +{ + (void)addr; + HILINK_SAL_DEBUG("%s RemovePair enter.\n", BLE_HILINK_SERVER_LOG); + return false; +} + +/** + * @brief Remove all pairs. + * @return Returns true if the operation is successful; + * returns false if the operation fails. + */ +bool RemoveAllPairs(void) +{ + HILINK_SAL_DEBUG("%s RemoveAllPairs enter.\n", BLE_HILINK_SERVER_LOG); + return false; +} + +/** + * @brief Read remote device rssi value. + * + * @param bdAddr device address. + * @param transport Transport type, details see {@link BtTransportId} + * @return Returns true if the operation is successful; + * returns false if the operation fails. + */ +bool ReadRemoteRssiValue(const BdAddr *bdAddr, int transport) +{ + (void)bdAddr; + (void)transport; + HILINK_SAL_DEBUG("%s ReadRemoteRssiValue enter.\n", BLE_HILINK_SERVER_LOG); + return false; +} + +/** + * @brief Check if device acl connected. + * @param addr device address. + * @return Returns true if device acl connected; + * returns false if device does not acl connect. + */ +bool IsAclConnected(BdAddr *addr) +{ + (void)addr; + HILINK_SAL_DEBUG("%s IsAclConnected enter.\n", BLE_HILINK_SERVER_LOG); + return false; +} + +/** + * @brief disconnect remote device all profile. + * @param addr device address. + * @return Returns true if device acl connected; + * returns false if device does not acl connect. + */ +bool DisconnectRemoteDevice(BdAddr *addr) +{ + (void)addr; + HILINK_SAL_DEBUG("%s DisconnectRemoteDevice enter.\n", BLE_HILINK_SERVER_LOG); + return false; +} + +/* + * @brief connect remote device acl profile. + * @param: remote device address + * @return Returns true if device acl connected; + * returns false if device does not acl connect. + */ +bool ConnectRemoteDevice(BdAddr *addr) +{ + (void)addr; + HILINK_SAL_DEBUG("%s ConnectRemoteDevice enter.\n", BLE_HILINK_SERVER_LOG); + return false; +} + +/* + * @brief Initialize the Bluetooth protocol stack + * @param[in] void + * @return 0-success, other-fail + */ +int InitBtStack(void) +{ + HILINK_SAL_DEBUG("%s InitBtStack enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Bluetooth protocol stack enable + * @param[in] void + * @return 0-success, other-fail + */ +int EnableBtStack(void) +{ + HILINK_SAL_DEBUG("%s EnableBtStack enter.\n", BLE_HILINK_SERVER_LOG); + errcode_t ret = enable_ble(); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s EnableBtStack fail, ret:%d.\n", BLE_HILINK_SERVER_LOG, ret); + return -1; + } + return 0; +} + +/* + * @brief Bluetooth protocol stack disable + * @param[in] void + * @return 0-success, other-fail + */ +int DisableBtStack(void) +{ + HILINK_SAL_DEBUG("%s DisableBtStack enter.\n", BLE_HILINK_SERVER_LOG); + errcode_t ret = disable_ble(); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_DEBUG("%s DisableBtStack fail, ret:%d.\n", BLE_HILINK_SERVER_LOG, ret); + return -1; + } + return 0; +} + +/* + * @brief set this device's name for friendly + * @param[in] device name + * @param[in] length + * @return 0-success, other-fail + */ +int SetDeviceName(const char *name, unsigned int len) +{ + (void)name; + (void)len; + #ifdef ENABLE_BLE_SCAN + extern int hfble_start_scan(void); + hfble_start_scan(); + #endif + HILINK_SAL_DEBUG("%s SetDeviceName enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief set advertising data + * @param[in] specified by upper layer + * @param[in] adv data or scan response + * @return 0-success, other-fail + */ +int BleSetAdvData(int advId, const BleConfigAdvData *data) +{ + (void)advId; + (void)data; + HILINK_SAL_DEBUG("%s BleSetAdvData enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief start ble advertising + * @param[in] specified by upper layer + * @param[in] ble advertising param list + * @return 0-success, other-fail + */ +int BleStartAdv(int advId, const BleAdvParams *param) +{ + (void)advId; + (void)param; + HILINK_SAL_DEBUG("%s BleStartAdv enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief stop ble advertising + * @param[in] specified by upper layer + * @return 0-success, other-fail + */ +int BleStopAdv(int advId) +{ + (void)advId; + HILINK_SAL_DEBUG("%s BleStopAdv enter.\n", BLE_HILINK_SERVER_LOG); + + errcode_t ret = gap_ble_stop_adv(BLE_ADV_HANDLE_DEFAULT); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_DEBUG("%s BleStopAdv gap_ble_stop_adv error.\n", BLE_HILINK_SERVER_LOG); + return ERRCODE_BT_FAIL; + } + + return 0; +} + +/* + * @Update the parameters as per spec, user manual specified values and restart multi ADV + * @param[in] specified by upper layer + * @param[in] ble advertising param list + * @return 0-success, other-fail + */ +int BleUpdateAdv(int advId, const BleAdvParams *param) +{ + (void)advId; + (void)param; + HILINK_SAL_DEBUG("%s BleUpdateAdv enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief set security IO capability + * @param[in] BleIoCapMode + * @return 0-success, other-fail + */ +int BleSetSecurityIoCap(BleIoCapMode mode) +{ + HILINK_SAL_DEBUG("%s BleSetSecurityIoCap enter, io_mod:%d.\n", BLE_HILINK_SERVER_LOG, mode); + g_io_cap_mode = mode; + return 0; +} + +/* + * @brief set security authority + * @param[in] BleAuthReqMode + * @return 0-success, other-fail + */ +int BleSetSecurityAuthReq(BleAuthReqMode mode) +{ + HILINK_SAL_DEBUG("%s BleSetSecurityAuthReq enter sc_mode:%d.\n", BLE_HILINK_SERVER_LOG, mode); + g_sc_mode = mode; + return 0; +} + +/* + * @brief The device accept or reject the connection initiator. + * @param[in] initiator's address + * @param[in] 0-reject, 1-accept + * @return 0-success, other-fail + */ +int BleGattSecurityRsp(BdAddr bdAddr, bool accept) +{ + (void)bdAddr; + (void)accept; + HILINK_SAL_DEBUG("%s BleGattSecurityRsp enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Setup scan filter params + * @param[in] BleAdvScanFilterParam + * @return 0-success, other-fail + */ +int BleScanFilterParamSetup(BleAdvScanFilterParam *param) +{ + (void)param; + HILINK_SAL_DEBUG("%s BleScanFilterParamSetup enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Configure a scan filter condition + * @param[in] BleAdvScanFilterCondition + * @return 0-success, other-fail + */ +int BleScanFilterAddRemove(BleAdvScanFilterCondition *param) +{ + (void)param; + HILINK_SAL_DEBUG("%s BleScanFilterAddRemove enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Clear all scan filter conditions for specific filter index + * @param[in] client Id + * @param[in] filter index + * @return 0-success, other-fail + */ +int BleScanFilterClear(int clientId, int filterIndex) +{ + (void)clientId; + (void)filterIndex; + HILINK_SAL_DEBUG("%s BleScanFilterClear enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Enable / disable scan filter feature + * @param[in] client Id + * @param[in] 0-disable, 1-enable + * @return 0-success, other-fail + */ +int BleScanFilterEnable(int clientId, bool enable) +{ + (void)clientId; + (void)enable; + HILINK_SAL_DEBUG("%s BleScanFilterEnable enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Set BLE scan parameters + * @param[in] client Id + * @param[in] BleScanParams, include scanInterval,scanWindow and so on. + * @return 0-success, other-fail + */ +int BleSetScanParameters(int clientId, BleScanParams *param) +{ + (void)clientId; + (void)param; + HILINK_SAL_DEBUG("%s BleSetScanParameters enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Start Ble scan + * @return 0-success, other-fail + */ +int BleStartScan(void) +{ + HILINK_SAL_DEBUG("%s BleStartScan enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Stop Ble scan + * @return 0-success, other-fail + */ +int BleStopScan(void) +{ + HILINK_SAL_DEBUG("%s BleStopScan enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +static void set_adv_data_cb_adapt(uint8_t adv_id, errcode_t status) +{ + (void)adv_id; + HILINK_SAL_DEBUG("%s set_adv_data_cb_adapt status: %d.\n", BLE_HILINK_SERVER_LOG, status); +} + +static void set_adv_param_cb_adapt(uint8_t adv_id, errcode_t status) +{ + (void)adv_id; + HILINK_SAL_DEBUG("%s set_adv_param_cb_adapt status: %d.\n", BLE_HILINK_SERVER_LOG, status); +} + +static void set_scan_param_cb_adapt(errcode_t status) +{ + HILINK_SAL_DEBUG("%s set_scan_param_cb_adapt status: %d.\n", BLE_HILINK_SERVER_LOG, status); +} + +static void start_adv_cb_adapt(uint8_t adv_id, adv_status_t status) +{ + HILINK_SAL_DEBUG("%s start_adv_cb_adapt enter adv_id:%d, status: %d.\n", BLE_HILINK_SERVER_LOG, adv_id, status); + g_ble_gap_cb->advEnableCb(adv_id, 0); +} + +static void stop_adv_cb_adapt(uint8_t adv_id, adv_status_t status) +{ + HILINK_SAL_DEBUG("%s stop_adv_cb_adapt enter status: %d.\n", BLE_HILINK_SERVER_LOG, status); + g_ble_gap_cb->advDisableCb(adv_id, 0); +} + +static void scan_result_cb_adapt(gap_scan_result_data_t *scan_result_data) +{ + #ifdef ENABLE_BLE_SCAN + hf_ble_scan_callback(scan_result_data); + #endif + //HILINK_SAL_DEBUG("%s scan_result_cb_adapt enter.\n", BLE_HILINK_SERVER_LOG); +} + +static void conn_state_change_cb_adapt(uint16_t conn_id, bd_addr_t *addr, + gap_ble_conn_state_t conn_state, gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason) +{ + HILINK_SAL_DEBUG("%s connect state change conn_id: %d, status: %d, pair_status:%d, disc_reason %x\n", + BLE_HILINK_SERVER_LOG, conn_id, conn_state, pair_state, disc_reason); + + BdAddr bd_addr = {0}; + if (conn_state == GAP_BLE_STATE_CONNECTED) { + HILINK_SAL_DEBUG("%s conn_state_change_cb_adapt conn succ.\n", BLE_HILINK_SERVER_LOG); + (void)memcpy_s(bd_addr.addr, BD_ADDR_LEN, addr->addr, BD_ADDR_LEN); + if (g_ble_gatts_cb->connectServerCb) { + g_ble_gatts_cb->connectServerCb(conn_id, g_server_id, &bd_addr); + } + } else if (conn_state == GAP_BLE_STATE_DISCONNECTED) { + HILINK_SAL_DEBUG("%s conn_state_change_cb_adapt disconnect.\n", BLE_HILINK_SERVER_LOG); + (void)memcpy_s(bd_addr.addr, BD_ADDR_LEN, addr->addr, BD_ADDR_LEN); + if (g_ble_gatts_cb->disconnectServerCb) { + g_ble_gatts_cb->disconnectServerCb(conn_id, g_server_id, &bd_addr); + } + } +} + +static gap_ble_callbacks_t g_gap_callback = { + .set_adv_data_cb = set_adv_data_cb_adapt, + .set_adv_param_cb = set_adv_param_cb_adapt, + .set_scan_param_cb = set_scan_param_cb_adapt, + .start_adv_cb = start_adv_cb_adapt, + .stop_adv_cb = stop_adv_cb_adapt, + .scan_result_cb = scan_result_cb_adapt, + .conn_state_change_cb = conn_state_change_cb_adapt +}; + +/* + * @brief Callback invoked for gatt common function + * @param[in] Callback funcs + * @return 0-success, other-fail + */ +int BleGattRegisterCallbacks(BtGattCallbacks *func) +{ + HILINK_SAL_DEBUG("%s BleGattRegisterCallbacks enter.\n", BLE_HILINK_SERVER_LOG); + if (func == NULL) { + HILINK_SAL_ERROR("null\n"); + return -1; + } + g_ble_gap_cb = func; + errcode_t ret = gap_ble_register_callbacks(&g_gap_callback); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s gap_ble_register_callbacks fail ret=%d.\n", BLE_HILINK_SERVER_LOG, ret); + return -1; + } + + return 0; +} + +static int set_own_addr_from_nv(bd_addr_t *own_addr) +{ + uint8_t efuse_mac[BD_ADDR_LEN] = {0}; + if (get_dev_addr(efuse_mac, BD_ADDR_LEN, IFTYPE_BLE) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("get device macaddr from efuse fail.\r\n"); + return -1; + } + + own_addr->type = 0; + if (memcpy_s(own_addr->addr, BD_ADDR_LEN, efuse_mac, BD_ADDR_LEN) != EOK) { + HILINK_SAL_ERROR("memcpy_s error set_ble_mac \r\n"); + return -1; + } + + return gap_ble_set_local_addr(own_addr); +} + +/* + * @brief Start advertising include set adv data. + * This API will not described in the development manual, only for Hilink. + * @return 0-success, other-fail + */ +int BleStartAdvEx(int *advId, const StartAdvRawData rawData, BleAdvParams advParam) +{ + HILINK_SAL_DEBUG("%s BleStartAdvEx enter.\n", BLE_HILINK_SERVER_LOG); + errcode_t ret = ERRCODE_BT_FAIL; + gap_ble_adv_params_t cfg_adv_params = {0}; + bd_addr_t own_addr = {0}; + + *advId = BLE_ADV_HANDLE_DEFAULT; + cfg_adv_params.min_interval = advParam.minInterval; + cfg_adv_params.max_interval = advParam.maxInterval; + cfg_adv_params.duration = advParam.duration; + cfg_adv_params.channel_map = advParam.channelMap; /* 广播通道选择bitMap, 可参考BleAdvChannelMap */ + cfg_adv_params.adv_type = advParam.advType; + cfg_adv_params.adv_filter_policy = advParam.advFilterPolicy; + cfg_adv_params.peer_addr.type = advParam.peerAddrType; + cfg_adv_params.own_addr.type = advParam.ownAddrType; + cfg_adv_params.tx_power = advParam.txPower; + set_own_addr_from_nv(&own_addr); + (void)memcpy_s(&cfg_adv_params.peer_addr.addr, BD_ADDR_LEN, advParam.peerAddr.addr, BD_ADDR_LEN); + (void)memcpy_s(&cfg_adv_params.own_addr.addr, BD_ADDR_LEN, own_addr.addr, BD_ADDR_LEN); + + ret = gap_ble_set_adv_param(BLE_ADV_HANDLE_DEFAULT, &cfg_adv_params); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s BleStartAdvEx gap_ble_set_adv_param error.\n", BLE_HILINK_SERVER_LOG); + return -1; + } + + gap_ble_config_adv_data_t cfg_adv_data = {0}; + cfg_adv_data.adv_length = rawData.advDataLen; + cfg_adv_data.adv_data = rawData.advData; /* set adv data */ + cfg_adv_data.scan_rsp_length = rawData.rspDataLen; + cfg_adv_data.scan_rsp_data = rawData.rspData; /* set scan response data */ + ret = gap_ble_set_adv_data(BLE_ADV_HANDLE_DEFAULT, &cfg_adv_data); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s BleStartAdvEx gap_ble_set_adv_data error.\n", BLE_HILINK_SERVER_LOG); + return -1; + } + + ret = gap_ble_start_adv(BLE_ADV_HANDLE_DEFAULT); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s BleStartAdvEx gap_ble_start_adv error.\n", BLE_HILINK_SERVER_LOG); + return -1; + } + + return 0; +} + +/* + * @brief gatt server application register, callback return serverId + * @param[in] specified by upper layer + * @return 0-success, other-fail + */ +int BleGattsRegister(BtUuid appUuid) +{ + HILINK_SAL_DEBUG("%s BleGattsRegister enter.\n", BLE_HILINK_SERVER_LOG); + bt_uuid_t app_uuid = {0}; + app_uuid.uuid_len = appUuid.uuidLen; + if (memcpy_s(app_uuid.uuid, app_uuid.uuid_len, appUuid.uuid, appUuid.uuidLen) != EOK) { + return ERRCODE_BT_FAIL; + } + gatts_register_server(&app_uuid, &g_server_id); + return ERRCODE_BT_SUCCESS; +} + +/* + * @brief gatt server deregister + * @param[in] server interface Id + * @return 0-success, other-fail + */ +int BleGattsUnRegister(int serverId) +{ + (void)serverId; + HILINK_SAL_DEBUG("%s BleGattsUnRegister enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Cancel connection with remote device + * @param[in] server interface id + * @param[in] remote address + * @param[in] connection index. + * @return 0-success, other-fail + */ +int BleGattsDisconnect(int serverId, BdAddr bdAddr, int connId) +{ + HILINK_SAL_DEBUG("%s BleGattsDisconnect enter.\n", BLE_HILINK_SERVER_LOG); + bd_addr_t bd_addr = { 0 }; + bd_addr.type = BT_ADDRESS_TYPE_PUBLIC_DEVICE_ADDRESS; + (void)memcpy_s(bd_addr.addr, BD_ADDR_LEN, bdAddr.addr, BD_ADDR_LEN); + return gap_ble_disconnect_remote_device(&bd_addr); +} + +/* + * @brief add service + * @param[in] server interface id + * @param[in] service uuid and uuid length + * @param[in] is primary or secondary service. + * @param[in] service characther attribute number. + * @return 0-success, other-fail + */ +int BleGattsAddService(int serverId, BtUuid srvcUuid, bool isPrimary, int number) +{ + HILINK_SAL_DEBUG("%s BleGattsAddService enter.\n", BLE_HILINK_SERVER_LOG); + errcode_t ret = 0; + bt_uuid_t service_uuid = {0}; + uint16_t service_handle = 0; + service_uuid.uuid_len = srvcUuid.uuidLen; + (void)memcpy_s(service_uuid.uuid, srvcUuid.uuidLen, (uint8_t *)srvcUuid.uuid, srvcUuid.uuidLen); + + while (1) { + osDelay(10); /* 等待10 tick */ + /* APP 调用StartService为异步接口 无法保证Add Service时 前一个Service已完成Start */ + if (g_service_flag == 0) { + ret = gatts_add_service_sync(g_server_id, &service_uuid, 1, &service_handle); + g_service_flag = 1; + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_DEBUG("%s BleGattsStartServiceEx Add Service Fail, ret:%x !!!\n", BLE_HILINK_SERVER_LOG, ret); + } + break; + } + } + g_srvc_handle = service_handle; + HILINK_SAL_DEBUG("%s BleGattsAddService end, srvcHandle:%u.\n", BLE_HILINK_SERVER_LOG, g_srvc_handle); + + return ret; +} + +/* + * @brief add characteristic + * @param[in] server interface id + * @param[in] service handle + * @param[in] characteristic uuid and uuid length + * @param[in] e.g. (OHOS_GATT_CHARACTER_PROPERTY_BIT_BROADCAST | OHOS_GATT_CHARACTER_PROPERTY_BIT_READ) + * @param[in] e.g. (OHOS_GATT_PERMISSION_READ | OHOS_GATT_PERMISSION_WRITE) + * @return 0-success, other-fail + */ +int BleGattsAddCharacteristic(int serverId, int srvcHandle, BtUuid characUuid, + int properties, int permissions) +{ + HILINK_SAL_DEBUG("%s BleGattsAddCharacteristic enter, srvcHandle:%d.\n", BLE_HILINK_SERVER_LOG, srvcHandle); + bt_uuid_t chara_uuid = {0}; + gatts_add_chara_info_t chara_info = {0}; + gatts_add_character_result_t chara_result = {0}; + chara_uuid.uuid_len = characUuid.uuidLen; + (void)memcpy_s(chara_uuid.uuid, characUuid.uuidLen, (uint8_t *)characUuid.uuid, characUuid.uuidLen); + + chara_info.chara_uuid = chara_uuid; + chara_info.properties = properties; + chara_info.permissions = perm_bt_to_bluez(permissions); + chara_info.value_len = sizeof(g_chara_val); + chara_info.value = g_chara_val; + int ret = gatts_add_characteristic_sync(g_server_id, srvcHandle, &chara_info, &chara_result); + HILINK_SAL_DEBUG("%s BleGattsAddCharacteristic ret:%d handle:%d, value_handle:%d.\n", + BLE_HILINK_SERVER_LOG, ret, chara_result.handle, chara_result.value_handle); + + g_cb_chara_handle = chara_result.value_handle; + return ret; +} + +/* + * @brief add descriptor + * @param[in] server interface id + * @param[in] service handle + * @param[in] descriptor uuid and uuid length + * @param[in] e.g. (OHOS_GATT_PERMISSION_READ | OHOS_GATT_PERMISSION_WRITE) + * @return 0-success, other-fail + */ +int BleGattsAddDescriptor(int serverId, int srvcHandle, BtUuid descUuid, int permissions) +{ + HILINK_SAL_DEBUG("%s BleGattsAddDescriptor enter.\n", BLE_HILINK_SERVER_LOG); + bt_uuid_t desc_uuid = {0}; + gatts_add_desc_info_t descriptor = {0}; + uint16_t desc_handle = 0; + + desc_uuid.uuid_len = descUuid.uuidLen; + (void)memcpy_s(desc_uuid.uuid, descUuid.uuidLen, (uint8_t *)descUuid.uuid, descUuid.uuidLen); + + descriptor.desc_uuid = desc_uuid; + descriptor.permissions = perm_bt_to_bluez(permissions); + descriptor.value_len = sizeof(g_desc_val); + descriptor.value = g_desc_val; + + int ret = gatts_add_descriptor_sync(g_server_id, srvcHandle, &descriptor, &desc_handle); + g_cb_desc_handle = desc_handle; + HILINK_SAL_DEBUG("%s BleGattsAddDescriptor ret:%d desc_handle:%u.\n", BLE_HILINK_SERVER_LOG, ret, desc_handle); + return ret; +} + +/* + * @brief start service + * @param[in] server interface id + * @param[in] service handle + * @return 0-success, other-fail + */ +int BleGattsStartService(int serverId, int srvcHandle) +{ + (void)serverId; + (void)srvcHandle; + HILINK_SAL_DEBUG("%s BleGattsStartService enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief start service + * @param[in] server interface id + * @param[in] service handle + * @return 0-success, other-fail + */ +int BleGattsStopService(int serverId, int srvcHandle) +{ + (void)serverId; + (void)srvcHandle; + HILINK_SAL_DEBUG("%s BleGattsStopService enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief remove a service from the list of provided services + * @param[in] server interface id + * @param[in] service handle + * @return 0-success, other-fail + */ +int BleGattsDeleteService(int serverId, int srvcHandle) +{ + (void)serverId; + (void)srvcHandle; + HILINK_SAL_DEBUG("%s BleGattsDeleteService enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief remove all services from the list of provided services + * @param[in] server interface id + * @return 0-success, other-fail + */ +int BleGattsClearServices(int serverId) +{ + (void)serverId; + HILINK_SAL_DEBUG("%s BleGattsClearServices enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} + +/* + * @brief Send a response to a read or write request to a remote device. + * @param[in] server interface id + * @param[in] response param + * @return 0-success, other-fail + */ +int BleGattsSendResponse(int serverId, GattsSendRspParam *param) +{ + (void)serverId; + if (param == NULL) { + HILINK_SAL_ERROR("null\n"); + return -1; + } + HILINK_SAL_DEBUG("%s BleGattsSendResponse enter, handle:%d.\n", BLE_HILINK_SERVER_LOG, param->attrHandle); + int ret = 0; + gatts_send_rsp_t rsp_param = {0}; + rsp_param.request_id = g_server_request_id; + rsp_param.status = 0; + rsp_param.offset = 0; + rsp_param.value_len = param->valueLen; + rsp_param.value = (uint8_t *)param->value; + + if (g_gatt_write_flag) { + ret = gatts_send_response(g_server_id, param->connectId, &rsp_param); + HILINK_SAL_DEBUG("%s BleGattsSendResponse send write resp, ret:%x.\n", BLE_HILINK_SERVER_LOG, ret); + } else { + ret = gatts_send_response(g_server_id, param->connectId, &rsp_param); + HILINK_SAL_DEBUG("%s BleGattsSendResponse send read resp, ret:%x.\n", BLE_HILINK_SERVER_LOG, ret); + } + + return ret; +} + +/* + * @brief Send a notification or indication that a local characteristic has been updated + * @param[in] server interface id + * @param[in] indication param + * @return 0-success, other-fail + */ +int BleGattsSendIndication(int serverId, GattsSendIndParam *param) +{ + (void)serverId; + if (param == NULL) { + HILINK_SAL_ERROR("null\n"); + return -1; + } + HILINK_SAL_DEBUG("%s BleGattsSendIndication enter, handle:%d.\n", BLE_HILINK_SERVER_LOG, param->attrHandle); + int attr_handle = get_chara_handle(param->attrHandle); + if (attr_handle < 0) { + return 0; + } + int ret = 0; + gatts_ntf_ind_t ntf_param = {0}; + ntf_param.attr_handle = attr_handle; + ntf_param.value_len = param->valueLen; + ntf_param.value = (uint8_t *)param->value; + ret = gatts_notify_indicate(g_server_id, param->connectId, &ntf_param); + if (ret != 0) { + HILINK_SAL_DEBUG("%s gatts_notify_indicate fail, ret:%x.\n", BLE_HILINK_SERVER_LOG, ret); + } + + int yet = ret ? 0 : -1; + if (g_ble_gatts_cb->indicationSentCb != NULL) { + HILINK_SAL_DEBUG("%s indicationSentCb form Hilink.\n", BLE_HILINK_SERVER_LOG); + g_ble_gatts_cb->indicationSentCb(param->connectId, yet); + } + + BleGattServiceIndicate indicate_func = get_chara_ind_func(param->connectId, attr_handle); + if (indicate_func != NULL) { + ret = indicate_func(ntf_param.value, ntf_param.value_len); + if (ret != 0) { + HILINK_SAL_DEBUG("indicateFunc fail %d.\n", ret); + } + } + return ret; +} + +/* + * @brief Set the encryption level of the data transmission channel during connection + * @param[in] remote address + * @param[in] BleSecAct + * @return 0-success, other-fail + */ +int BleGattsSetEncryption(BdAddr bdAddr, BleSecAct secAct) +{ + HILINK_SAL_DEBUG("%s BleGattsSetEncryption enter, secAct:%d.\n", BLE_HILINK_SERVER_LOG, secAct); + + gap_ble_sec_params_t sec_params = {0}; + sec_params.bondable = 1; + sec_params.io_capability = g_io_cap_mode; + sec_params.sc_enable = 0; + sec_params.sc_mode = secAct; + int ret = gap_ble_set_sec_param(&sec_params); + if (ret != 0) { + HILINK_SAL_DEBUG("%s gap_ble_set_sec_param fail, ret:%d.\n", BLE_HILINK_SERVER_LOG, ret); + } + return 0; +} + +void add_service_cb_adapt(uint8_t server_id, bt_uuid_t *uuid, uint16_t handle, errcode_t status) +{ + (void)uuid; + HILINK_SAL_DEBUG("%s add_service_cb_adapt server_id:%u, handle:%u, status:%d.\n", + BLE_HILINK_SERVER_LOG, server_id, handle, status); +} + +void add_characteristic_cb_adapt(uint8_t server_id, bt_uuid_t *uuid, uint16_t service_handle, + gatts_add_character_result_t *result, errcode_t status) +{ + if (uuid == NULL) { + return; + } + HILINK_SAL_DEBUG("%s add_characteristic_cb server: %u srvc_hdl: %u char_hdl: %u char_val_hdl: %u uuid_len: %u \n", + BLE_HILINK_SERVER_LOG, server_id, service_handle, result->handle, result->value_handle, uuid->uuid_len); +} + +void add_descriptor_cb_adapt(uint8_t server_id, bt_uuid_t *uuid, uint16_t service_handle, + uint16_t handle, errcode_t status) +{ + if (uuid == NULL) { + return; + } + HILINK_SAL_DEBUG("%s add_descriptor_cb_adapt server: %u srv_hdl: %u desc_hdl: %u uuid_len:%u.\n", + BLE_HILINK_SERVER_LOG, server_id, service_handle, handle, uuid->uuid_len); +} + +void start_service_cb_adapt(uint8_t server_id, uint16_t handle, errcode_t status) +{ + HILINK_SAL_DEBUG("%s start_service_cb_adapt server: %u srv_hdl: %u status: %d\n", + BLE_HILINK_SERVER_LOG, server_id, handle, status); + if (g_srvc_handle != handle) { + return; + } + g_service_flag = 0; + if (g_ble_gatts_cb->serviceStartCb) { + g_ble_gatts_cb->serviceStartCb(status, server_id, handle); + } +} + +void stop_service_cb_adapt(uint8_t server_id, uint16_t handle, errcode_t status) +{ + HILINK_SAL_DEBUG("%s stop_service_cb_adapt server: %u srv_hdl: %u status: %d\n", + BLE_HILINK_SERVER_LOG, server_id, handle, status); + if (g_ble_gatts_cb->serviceStopCb) { + g_ble_gatts_cb->serviceStopCb(status, server_id, handle); + } +} + +void delete_service_cb_adapt(uint8_t server_id, errcode_t status) +{ + HILINK_SAL_DEBUG("%s delete_service_cb_adapt server: %u status: %d\n", + BLE_HILINK_SERVER_LOG, server_id, status); +} + +void read_request_cb_adapt(uint8_t server_id, uint16_t conn_id, gatts_req_read_cb_t *read_cb_para, + errcode_t status) +{ + if (read_cb_para == NULL) { + return; + } + HILINK_SAL_DEBUG("%s read_request_cb_adapt server_id:%u conn_id:%u status:%d\n", + BLE_HILINK_SERVER_LOG, server_id, conn_id, status); + char buff[MAX_READ_REQ_LEN] = {0}; + unsigned int length = MAX_READ_REQ_LEN; + int ret = 0; + + BleGattServiceRead read_func = get_chara_read_func(conn_id, read_cb_para->handle); + if (read_func != NULL) { + ret = read_func((uint8_t *)buff, &length); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_DEBUG("read_func fail %d.\n", ret); + length = 0; + } + } + + GattsSendRspParam rsp = {0}; + rsp.connectId = conn_id; + rsp.status = OHOS_GATT_SUCCESS; + rsp.attrHandle = read_cb_para->handle; + + if (length > read_cb_para->offset) { + rsp.valueLen = length - read_cb_para->offset; + rsp.value = buff + read_cb_para->offset; + } else { + rsp.valueLen = 0; + rsp.value = buff; + } + + BleGattsSendResponse(g_server_id, &rsp); + + g_gatt_write_flag = 0; + g_server_request_id = read_cb_para->request_id; +} + +void write_request_cb_adapt(uint8_t server_id, uint16_t conn_id, gatts_req_write_cb_t *write_cb_para, + errcode_t status) +{ + if (write_cb_para == NULL) { + return; + } + HILINK_SAL_DEBUG("%s write_request_cb_adapt request_id:%u att_handle:%u data_len:%u\n", + BLE_HILINK_SERVER_LOG, write_cb_para->request_id, write_cb_para->handle, write_cb_para->length); + + BleGattServiceWrite write_func = get_chara_write_func(conn_id, write_cb_para->handle); + if (write_func != NULL) { + int ret = write_func(write_cb_para->value, write_cb_para->length); + if (ret != 0) { + HILINK_SAL_DEBUG("write_func fail %d.\n", ret); + } + } + + g_server_request_id = write_cb_para->request_id; + g_gatt_write_flag = 1; + + if (write_cb_para->is_prep) { + GattsSendRspParam rsp = {0}; + char one_byte_rsp = 0; + rsp.connectId = conn_id; + rsp.status = OHOS_GATT_SUCCESS; + rsp.attrHandle = write_cb_para->handle; + rsp.valueLen = sizeof(one_byte_rsp); + rsp.value = &one_byte_rsp; + + int ret = BleGattsSendResponse(g_server_id, &rsp); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_DEBUG("BleGattsSendResponse fail %d.\n", ret); + } + } +} + +void mtu_changed_cb_adapt(uint8_t server_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status) +{ + HILINK_SAL_DEBUG("%s mtu_changed_cb_adapt server_id:%u conn_id:%u mtu_size: %u status: %d\n", + BLE_HILINK_SERVER_LOG, server_id, conn_id, mtu_size, status); + + g_ble_gatts_cb->mtuChangeCb(conn_id, mtu_size); +} + +gatts_callbacks_t g_gatt_callback = { + .add_service_cb = add_service_cb_adapt, + .add_characteristic_cb = add_characteristic_cb_adapt, + .add_descriptor_cb = add_descriptor_cb_adapt, + .start_service_cb = start_service_cb_adapt, + .stop_service_cb = stop_service_cb_adapt, + .delete_service_cb = delete_service_cb_adapt, + .read_request_cb = read_request_cb_adapt, + .write_request_cb = write_request_cb_adapt, + .mtu_changed_cb = mtu_changed_cb_adapt +}; + +/* + * @brief Callback invoked for gatt server function + * @param[in] Callback funcs + * @return 0-success, other-fail + */ +int BleGattsRegisterCallbacks(BtGattServerCallbacks *func) +{ + HILINK_SAL_DEBUG("%s BleGattsRegisterCallbacks enter.\n", BLE_HILINK_SERVER_LOG); + if (func == NULL) { + HILINK_SAL_ERROR("null\n"); + return -1; + } + g_ble_gatts_cb = func; + errcode_t ret = gatts_register_callbacks(&g_gatt_callback); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s gatts_register_callbacks fail, ret:%d.\n", BLE_HILINK_SERVER_LOG, ret); + return -1; + } + + return 0; +} + +static errcode_t ble_uuid_server_init(void) +{ + bt_uuid_t app_uuid = {0}; + char uuid[] = { 0x12, 0x34 }; + app_uuid.uuid_len = sizeof(uuid); + int ret = memcpy_s(app_uuid.uuid, app_uuid.uuid_len, uuid, sizeof(uuid)); + if (ret != EOK) { + HILINK_SAL_ERROR("ret=%d\n", ret); + return -1; + } + ret = gatts_register_server(&app_uuid, &g_server_id); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s gatts_register_server fail ret=%d.\n", BLE_HILINK_SERVER_LOG, ret); + return -1; + } + return ret; +} + +/* + * @brief Start sevice include add service/characteristic/Descriptor option. + * This API will not described in the development manual, only for Hilink. + * @return 0-success, other-fail + */ + +static void hilnk_group_add(void) +{ + g_hilink_group_cnt++; +} + +static void convert_uuid(uint8_t *uuid_input, UuidType type, BtUuid *uuid_output) +{ + uint8_t temp_uuid[OHOS_BLE_UUID_MAX_LEN] = {0}; + int ret = 0; + + switch (type) { + case OHOS_UUID_TYPE_16_BIT: + uuid_output->uuidLen = UUID16_LEN; + break; + case OHOS_UUID_TYPE_32_BIT: + uuid_output->uuidLen = UUID32_LEN; + break; + case OHOS_UUID_TYPE_128_BIT: + uuid_output->uuidLen = UUID128_LEN; + break; + default: + uuid_output->uuidLen = 0; + break; + } + + uuid_output->uuid = (char *)uuid_input; + ret = memcpy_s(temp_uuid, OHOS_BLE_UUID_MAX_LEN, g_hilink_group_uuid[g_hilink_group_cnt], OHOS_BLE_UUID_MAX_LEN); + if (ret != EOK) { + HILINK_SAL_ERROR("%s convert_uuid memcpy_s fail.\n", BLE_HILINK_SERVER_LOG); + return; + } + reverse_uuid(temp_uuid, sizeof(temp_uuid), uuid_output->uuid, uuid_output->uuidLen); + return; +} + +static void set_chara_func(BleGattAttr *attr, uint8_t is_indicate, int hilinkAttrHandle) +{ + if (g_chara_cnt >= BLE_MAX_CHAR_NUMS) { + HILINK_SAL_ERROR("g_chara_cnt:%u\n", g_chara_cnt); + return; + } + g_charas_func[g_chara_cnt].conn_id = 0; + if (is_indicate == 0) { + if (attr->attrType == OHOS_BLE_ATTRIB_TYPE_CHAR) { + g_charas_func[g_chara_cnt].attr_handle = g_cb_chara_handle; + } else { + g_charas_func[g_chara_cnt].attr_handle = g_cb_desc_handle; + } + g_charas_func[g_chara_cnt].read = attr->func.read; + g_charas_func[g_chara_cnt].write = attr->func.write; + g_charas_func[g_chara_cnt].indicate = attr->func.indicate; + g_charas_func[g_chara_cnt].hilinkAttrHandle = hilinkAttrHandle; + } else { + g_charas_func[g_chara_cnt].attr_handle = g_cb_desc_handle; + g_charas_func[g_chara_cnt].hilinkAttrHandle = hilinkAttrHandle; + } + g_chara_cnt++; +} + +int BleGattsStartServiceEx(int *srvcHandle, BleGattService *srvcInfo) +{ + if (srvcHandle == NULL || srvcInfo == NULL) { + HILINK_SAL_ERROR("null\n"); + return -1; + } + HILINK_SAL_DEBUG("%s BleGattsStartServiceEx enter srvHandle:%d.\n", BLE_HILINK_SERVER_LOG, *srvcHandle); + errcode_t ret = ERRCODE_BT_SUCCESS; + uint8_t is_indicate = 0; + BtUuid ble_uuid = {0}; + uint8_t temp_uuid[16] = {0}; + uint16_t service_handle = 0; + + if (g_server_id == INVALID_SERVER_ID) { + if (ble_uuid_server_init() != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s gatts_register_server fail.\n", BLE_HILINK_SERVER_LOG); + return -1; + } + } + + for (unsigned int i = 0; i < srvcInfo->attrNum; i++) { + BleGattAttr *attr = &(srvcInfo->attrList[i]); + (void)memcpy_s(temp_uuid, 16, attr->uuid, 16); + convert_uuid(temp_uuid, attr->uuidType, &ble_uuid); + + switch (attr->attrType) { + case OHOS_BLE_ATTRIB_TYPE_SERVICE: + ret = BleGattsAddService(g_server_id, ble_uuid, 1, srvcInfo->attrNum); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s BleGattsAddService failed, ret:0x%x\r\n", BLE_HILINK_SERVER_LOG, ret); + } + hilnk_group_add(); + break; + case OHOS_BLE_ATTRIB_TYPE_CHAR: + ret = BleGattsAddCharacteristic(g_server_id, g_srvc_handle, + ble_uuid, attr->properties, attr->permission); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s BleGattsAddCharacteristic failed, ret:0x%x\r\n", BLE_HILINK_SERVER_LOG, ret); + } + hilnk_group_add(); + break; + case OHOS_BLE_ATTRIB_TYPE_CHAR_VALUE: + break; + case OHOS_BLE_ATTRIB_TYPE_CHAR_CLIENT_CONFIG: + break; + case OHOS_BLE_ATTRIB_TYPE_CHAR_USER_DESCR: + ret = BleGattsAddDescriptor(g_server_id, g_srvc_handle, ble_uuid, attr->permission); + if (ret != ERRCODE_BT_SUCCESS) { + HILINK_SAL_ERROR("%s BleGattsAddDescriptor failed:%x.\n", BLE_HILINK_SERVER_LOG, ret); + } + hilnk_group_add(); + break; + default: + HILINK_SAL_ERROR("Unknown\n"); + } + + if ((attr->attrType == OHOS_BLE_ATTRIB_TYPE_CHAR_USER_DESCR) || (attr->attrType == OHOS_BLE_ATTRIB_TYPE_CHAR)) { + set_chara_func(attr, 0, g_srvc_handle + i); + } + + if ((attr->properties & OHOS_GATT_CHARACTER_PROPERTY_BIT_INDICATE) || + (attr->properties & OHOS_GATT_CHARACTER_PROPERTY_BIT_NOTIFY)) { + is_indicate = 1; + g_indicate_handle = g_cb_chara_handle; + } + + if (is_indicate) { + ble_uuid.uuid = g_hilink_cccd_uuid; + ble_uuid.uuidLen = sizeof(g_hilink_cccd_uuid); + ret = BleGattsAddDescriptor(g_server_id, g_srvc_handle, + ble_uuid, OHOS_GATT_PERMISSION_READ | OHOS_GATT_PERMISSION_WRITE); + if (ret == ERRCODE_BT_SUCCESS) { + set_chara_func(NULL, is_indicate, 0); + } + is_indicate = 0; + } + } + + if (g_srvc_handle != 0) { + ret = gatts_start_service(g_server_id, g_srvc_handle); + *srvcHandle = g_srvc_handle; + } + + return 0; +} + +/* + * @brief Stop service. + * This API will not described in the development manual, only for Hilink. + * @return 0-success, other-fail + */ +int BleGattsStopServiceEx(int srvcHandle) +{ + (void)srvcHandle; + HILINK_SAL_DEBUG("%s BleGattsStopServiceEx enter.\n", BLE_HILINK_SERVER_LOG); + return 0; +} diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_kv_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_kv_adapter.c new file mode 100755 index 0000000..50bb7a9 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_kv_adapter.c @@ -0,0 +1,428 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: HiLinkKV harmonyos file实现源文件(此文件为DEMO,需集成方适配修改) + */ + +#include "hilink_kv_adapter.h" +#include +#include "hilink_sal_defines.h" +#include "securec.h" +#include "hilink_str_adapter.h" +#include "lfs.h" +#include "fcntl.h" +#include "sfc.h" +#include "securec.h" +#include "soc_osal.h" +#include "littlefs_config.h" +#include "securec.h" +#include "partition.h" +#include "littlefs_adapt.h" + +#if defined(HILINK_SDK_BUILD_IN) && defined(HI_3861) +#define MAX_PATH_LEN 16 +#define MAX_FILENAME_LEN 16 +#else +#define MAX_PATH_LEN 32 +#define MAX_FILENAME_LEN 32 +#endif + +static bool g_isKVInit = false; + +typedef struct KeyNameItem { + const char *hilinkKey; + const char *fileName; +} KeyNameItem; + +/* 需要对key进行转换,防止key变更导致无法前向兼容 */ +static const KeyNameItem KEY_NAME_LIST[] = { + { + "hilink_running", + "running" + }, + { + "hilink_timer", + "timer" + }, + + { + "hilink_ble_sensitive", + "sensitive" + }, + { + "hilink_ble_regstate", + "regstate" + }, + { + "hilink_cert", + "cert" + }, +}; + +#ifdef DUAL_FILE_BACKUP +/* 使用双备份后对于非预置文件,以.bak为后缀做备份 */ +static const char *BACKUP_FILE_SUFFIX = ".bak"; +static const char *PRESET_FILE[] = {"hilink.cfg", "hilink_bak.cfg"}; + +static bool IsPresetFile(const char *fileName) +{ + for (unsigned int i = 0; i < sizeof(PRESET_FILE) / sizeof(char *); ++i) { + if (HILINK_Strcmp(fileName, PRESET_FILE[i]) == 0) { + return true; + } + } + return false; +} + +static const char *GetBackupFileName(const char *fileName, char *buf, unsigned int len) +{ + if (sprintf_s(buf, len, "%s%s", fileName, BACKUP_FILE_SUFFIX) <= 0) { + HILINK_SAL_WARN("sprintf error\r\n"); + return NULL; + } + return buf; +} +#endif + +static const char *FindFileName(const char *key) +{ + for (unsigned int i = 0; i < (sizeof(KEY_NAME_LIST) / sizeof(KEY_NAME_LIST[0])); ++i) { + if (HILINK_Strcmp(key, KEY_NAME_LIST[i].hilinkKey) == 0) { + return KEY_NAME_LIST[i].fileName; + } + } + return NULL; +} + +static int SetConfigInfoPath(const char *path) +{ + (void)path; + return HILINK_SAL_OK; +} + +static int CreateFileIfNotExists(const char *filePath) +{ + if (filePath == NULL) { + HILINK_SAL_ERROR("Create filepath is null.\r\n"); + return HILINK_SAL_KV_INTI_ERR; + } + + HILINK_SAL_DEBUG("Create file [%s]\r\n", filePath); + int fp = fs_adapt_open(filePath, O_RDWR | O_CREAT); + if (fp < 0) { + HILINK_SAL_ERROR("Create file failed.\r\n"); + return HILINK_SAL_KV_INTI_ERR; + } + + int ret = fs_adapt_close(fp); + if (ret < LFS_ERR_OK) { + HILINK_SAL_ERROR("close file %s failed\n", filePath); + return HILINK_SAL_NOK; + } + + HILINK_SAL_DEBUG("Create file %s SUCCESS\r\n", filePath); + + return HILINK_SAL_OK; +} + +static int ReadFile(const char *filePath, unsigned int offset, unsigned char *value, unsigned int len) +{ + if ((filePath == NULL) || (filePath[0] == '\0')) { + HILINK_SAL_ERROR("invalid path\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + HILINK_SAL_DEBUG("read %s, read len %u, offset %u\r\n", filePath, len, offset); + + int fp = fs_adapt_open(filePath, O_RDWR); + if (fp <= 0) { + HILINK_SAL_ERROR("open %s failed fp=%d\r\n", filePath, fp); + return HILINK_SAL_NOK; + } + + int ret = fs_adapt_seek(fp, (int)offset, LFS_SEEK_SET); + if (ret < LFS_ERR_OK) { + HILINK_SAL_ERROR("set file %s offset %u failed\n", filePath, offset); + goto unnormal_close; + } + + ret = fs_adapt_read(fp, (char *)value, len); + if (ret < 0) { + HILINK_SAL_ERROR("read file %s failed\n", filePath); + goto unnormal_close; + } + + ret = fs_adapt_close(fp); + if (ret < LFS_ERR_OK) { + HILINK_SAL_ERROR("close file %s failed\n", filePath); + return HILINK_SAL_NOK; + } + + return HILINK_SAL_OK; + +unnormal_close: + ret = fs_adapt_close(fp); + if (ret < LFS_ERR_OK) { + HILINK_SAL_ERROR("close file %s failed\n", filePath); + } + + return HILINK_SAL_NOK; +} + +static int WritFile(const char *filePath, unsigned int offset, const unsigned char *value, unsigned int len) +{ + HILINK_SAL_DEBUG("write %s, write len %u, offset %u\r\n", filePath, len, offset); + + int fp = fs_adapt_open(filePath, O_RDWR | O_CREAT); + if (fp < 0) { + HILINK_SAL_ERROR("open %s failed\r\n", filePath); + return HILINK_SAL_NOK; + } + + int ret = fs_adapt_seek(fp, (int)offset, LFS_SEEK_SET); + if (ret < LFS_ERR_OK) { + HILINK_SAL_ERROR("set file %s offset %u failed\n", filePath, offset); + goto unnormal_close; + } + + ret = fs_adapt_write(fp, (char *)value, len); + if (ret < 0) { + HILINK_SAL_ERROR("write file %s failed\n", filePath); + goto unnormal_close; + } + + ret = fs_adapt_close(fp); + if (ret < LFS_ERR_OK) { + HILINK_SAL_ERROR("close file %s failed\n", filePath); + return HILINK_SAL_NOK; + } + + return HILINK_SAL_OK; + +unnormal_close: + ret = fs_adapt_close(fp); + if (ret < LFS_ERR_OK) { + HILINK_SAL_ERROR("close file %s failed\n", filePath); + } + + return HILINK_SAL_NOK; +} + +static int CreateEmptyFileAfterDelete(const char *filePath) +{ + HILINK_SAL_NOTICE("delete %s\r\n", filePath); + int ret = fs_adapt_delete(filePath); + HILINK_SAL_NOTICE("fs_adapt_delete %d\r\n", ret); + return HILINK_SAL_OK; +} + +static int GetFilePathByKey(const char *key, char *buf, unsigned int len) +{ + if (len < 1) { + HILINK_SAL_ERROR("len\n"); + return HILINK_SAL_NOK; + } + const char *fileName = fileName = FindFileName(key); + if (fileName == NULL) { + HILINK_SAL_ERROR("get file path failed\n"); + return HILINK_SAL_NOK; + } + + if (memcpy_s(buf, len - 1, fileName, strlen(fileName)) != EOK) { + HILINK_SAL_ERROR("memcpy_s error\n"); + return HILINK_SAL_NOK; + } + + return HILINK_SAL_OK; +} + +#if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP) +static const char *GetBakFilePathByKey(const char *key, char *buf, unsigned int len) +{ + const char *fileName = FindFileName(key); + /* 预置文件不做备份 */ + if (IsPresetFile(fileName)) { + return NULL; + } + char bakFileName[MAX_FILENAME_LEN] = {0}; + if (GetBackupFileName(fileName, bakFileName, sizeof(bakFileName)) == NULL) { + return NULL; + } + + return GetFullFilePath(bakFileName, buf, len); +} +#endif + +static void DeleteFileByKey(const char *key) +{ + char filePath[MAX_PATH_LEN + MAX_FILENAME_LEN] = {0}; + if (GetFilePathByKey(key, filePath, sizeof(filePath)) != HILINK_SAL_OK) { + return; + } + (void)CreateEmptyFileAfterDelete(filePath); +#if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP) + (void)memset_s(filePath, sizeof(filePath), 0, sizeof(filePath)); + if (GetBakFilePathByKey(key, filePath, sizeof(filePath)) != NULL) { + (void)CreateEmptyFileAfterDelete(filePath); + } +#endif +} + +static int ReadFileByKey(const char *key, unsigned int offset, unsigned char *value, unsigned int len) +{ + char filePath[MAX_PATH_LEN + MAX_FILENAME_LEN] = {0}; + if (GetFilePathByKey(key, filePath, sizeof(filePath)) != HILINK_SAL_OK) { + return HILINK_SAL_KV_GET_ITEM_ERR; + } + int ret = ReadFile(filePath, offset, value, len); + if (ret == HILINK_SAL_OK) { + return HILINK_SAL_OK; + } +#if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP) + (void)memset_s(filePath, sizeof(filePath), 0, sizeof(filePath)); + if (GetBakFilePathByKey(key, filePath, sizeof(filePath)) != NULL) { + ret = ReadFile(filePath, offset, value, len); + if (ret == HILINK_SAL_OK) { + return HILINK_SAL_OK; + } + } +#endif + return ret; +} + +static int WriteFileByKey(const char *key, unsigned int offset, const unsigned char *value, unsigned int len) +{ + char filePath[MAX_PATH_LEN + MAX_FILENAME_LEN] = {0}; + if (GetFilePathByKey(key, filePath, sizeof(filePath)) != HILINK_SAL_OK) { + return HILINK_SAL_KV_SET_ITEM_ERR; + } + int ret = WritFile(filePath, offset, value, len); + if (ret != HILINK_SAL_OK) { + return ret; + } + +#if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP) + (void)memset_s(filePath, sizeof(filePath), 0, sizeof(filePath)); + if (GetBakFilePathByKey(key, filePath, sizeof(filePath)) != NULL) { + ret = WritFile(filePath, offset, value, len); + if (ret != HILINK_SAL_OK) { + return ret; + } + } +#endif + return HILINK_SAL_OK; +} + +static int InitFileByKey(const char *key) +{ + if ((key == NULL) || (key[0] == '\0')) { + HILINK_SAL_WARN("invalid parm\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + char filePath[MAX_PATH_LEN + MAX_FILENAME_LEN] = {0}; + if (GetFilePathByKey(key, filePath, sizeof(filePath)) != HILINK_SAL_OK) { + return HILINK_SAL_KV_INTI_ERR; + } + + int ret = CreateFileIfNotExists(filePath); + if (ret != 0) { + return ret; + } + +#if defined(HILINK_SDK_BUILD_IN) && defined(DUAL_FILE_BACKUP) + (void)memset_s(filePath, sizeof(filePath), 0, sizeof(filePath)); + if (GetBakFilePathByKey(key, filePath, sizeof(filePath)) == NULL) { + return HILINK_SAL_KV_INTI_ERR; + } + ret = CreateFileIfNotExists(filePath); + if (ret != 0) { + return ret; + } +#endif + return HILINK_SAL_OK; +} + +int HILINK_KVStoreInit(const char *path, const char *key[], unsigned int num) +{ + if ((key == NULL) || (num == 0) || (path == NULL)) { + HILINK_SAL_WARN("invalid parm\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + HILINK_SAL_DEBUG("HILINK_KVStoreInit path[%s], num %d\r\n", path, num); + if (SetConfigInfoPath(path) != HILINK_SAL_OK) { + HILINK_SAL_WARN("set config path error\r\n"); + return HILINK_SAL_KV_INTI_ERR; + } + int ret; + for (unsigned int i = 0; i < num; ++i) { + HILINK_SAL_DEBUG("HILINK_KVStoreInit key [%s]\r\n", key[i]); + ret = InitFileByKey(key[i]); + if (ret != HILINK_SAL_OK) { + return ret; + } + } + g_isKVInit = true; + return HILINK_SAL_OK; +} + +int HILINK_SetValue(const char *key, unsigned int offset, const unsigned char *value, unsigned int len) +{ + if ((key == NULL) || (key[0] == '\0') || (value == NULL) || (len == 0)) { + HILINK_SAL_WARN("invalid parm\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + if (!g_isKVInit) { + HILINK_SAL_WARN("not init\r\n"); + return HILINK_SAL_NOT_INIT; + } + + return WriteFileByKey(key, offset, value, len); +} + +int HILINK_GetValue(const char *key, unsigned int offset, unsigned char *value, unsigned int len) +{ + if ((key == NULL) || (key[0] == '\0') || (value == NULL) || (len == 0)) { + HILINK_SAL_WARN("invalid parm\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + if (!g_isKVInit) { + HILINK_SAL_WARN("not init\r\n"); + return HILINK_SAL_NOT_INIT; + } + + return ReadFileByKey(key, offset, value, len); +} + +void HILINK_DeleteValue(const char * key) +{ + if ((key == NULL) || (key[0] == '\0')) { + HILINK_SAL_WARN("invalid parm\r\n"); + return; + } + + if (!g_isKVInit) { + HILINK_SAL_WARN("not init\r\n"); + return; + } + + DeleteFileByKey(key); +} + +int HILINK_GetFileName(const char *key, char *out, unsigned int len) +{ + if (key == NULL || out == NULL || len < MAX_FILENAME_LEN) { + HILINK_SAL_WARN("invalid parm\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + const char *fileName = key; +#ifdef HILINK_SDK_BUILD_IN + fileName = FindFileName(key); +#endif + if (strcpy_s(out, len, fileName) != EOK) { + HILINK_SAL_WARN("cpy file name err\n"); + return HILINK_SAL_NOK; + } + return HILINK_SAL_OK; +} diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_mem_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_mem_adapter.c new file mode 100755 index 0000000..7c12e5b --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_mem_adapter.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 系统适配层内存接口实现源文件(此文件为DEMO,需集成方适配修改) + */ +#include "hilink_mem_adapter.h" +#include +#include + +void *HILINK_Malloc(unsigned int size) +{ + if (size == 0) { + return NULL; + } + + return malloc(size); +} + +void HILINK_Free(void *pt) +{ + if (pt == NULL) { + return; + } + free(pt); +} + +int HILINK_Memcmp(const void *buf1, const void *buf2, unsigned int len) +{ + if ((buf1 == NULL) && (buf2 == NULL)) { + return 0; + } + if ((buf1 != NULL) && (buf2 == NULL)) { + return 1; + } + if ((buf1 == NULL) && (buf2 != NULL)) { + return -1; + } + + return memcmp(buf1, buf2, len); +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_network_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_network_adapter.c new file mode 100755 index 0000000..b825259 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_network_adapter.c @@ -0,0 +1,930 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 网络适配实现 (此文件为DEMO,需集成方适配修改) + */ +#include "hilink_network_adapter.h" + +#include +#include +#include "wifi_device.h" +#include "wifi_event.h" +#include "wifi_device_config.h" +#include "hilink_sal_defines.h" +#include "hilink_socket_adapter.h" +#include "hilink_str_adapter.h" +#include "securec.h" +#include "hilink_thread_adapter.h" +#include "hilink_mem_adapter.h" +#include "soc_wifi_api.h" +#include "lwip/netifapi.h" +#include "nv.h" +#include "nv_common_cfg.h" +#include "efuse_porting.h" + +#define MAX_IP_LEN 40 +#define MAX_SCAN_TIMES 4 +#define DEF_SCAN_TIMEOUT 15 +#define MS_PER_SECOND 1000 +#define WIFI_SCANNING 1 + +static bool g_isRegisterWifiEvent = false; +static bool g_isStaScanSuccess = false; +static wifi_event_stru g_eventHandler; +static unsigned short g_disconnectReason = 0; +static bool g_isReasonRefresh = false; +static int g_offline_mode_scan_flag = 0; + +unsigned int get_wifi_recovery_type(void) +{ + return (0x01 | 0x02); /* 0x01|0x02 : 连线网络优化功能开启 */ +} + +static int sta_setup_dhcp(void) +{ + int ret = 0; + struct netif *netif_p = netifapi_netif_find("wlan0"); + if (netif_p == NULL) { + return HILINK_SAL_NOK; + } + ret = netifapi_dhcp_start(netif_p); + if (ret == 0) { + return HILINK_SAL_OK; + } + + return HILINK_SAL_NOK; +} +static int AddDeviceConfig(wifi_sta_config_stru *config) +{ + if (config == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + hilink_connect_info_t connect_info; + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + + if (memcpy_s(connect_info.ssid, sizeof(connect_info.ssid), config->ssid, strlen((char *)config->ssid)) != EOK) { + HILINK_SAL_ERROR("memcpy_s error\r\n"); + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_NOK; + } + + if (memcpy_s(connect_info.pwd, sizeof(connect_info.pwd), config->pre_shared_key, + strlen((char *)config->pre_shared_key)) != EOK) { + HILINK_SAL_ERROR("memcpy_s error\r\n"); + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_NOK; + } + + if (memcpy_s(connect_info.bssid, sizeof(connect_info.bssid), config->bssid, + sizeof(config->bssid)) != EOK) { + HILINK_SAL_ERROR("memcpy_s error\r\n"); + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_NOK; + } + + uint32_t nv_ret = ERRCODE_FAIL; + nv_ret = uapi_nv_write(NV_ID_HILINK_CONNECT_INFO, (uint8_t *)&connect_info, sizeof(connect_info)); + if (nv_ret != ERRCODE_SUCC) { + HILINK_SAL_ERROR("read write connect info to nv failed\r\n"); + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_NOK; + } + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_OK; +} + +static int GetDeviceConfigs(wifi_sta_config_stru *config) +{ + if (config == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + hilink_connect_info_t connect_info; + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + + uint16_t connect_info_len = 0; + uint32_t nv_ret = ERRCODE_FAIL; + nv_ret = uapi_nv_read(NV_ID_HILINK_CONNECT_INFO, sizeof(hilink_connect_info_t), &connect_info_len, + (uint8_t *)&connect_info); + if (nv_ret != ERRCODE_SUCC) { + HILINK_SAL_ERROR("read hilink connect info from nv failed\r\n"); + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_NOK; + } + + if (memcpy_s(config->ssid, sizeof(config->ssid), connect_info.ssid, sizeof(connect_info.ssid)) != EOK) { + HILINK_SAL_ERROR("memcpy_s error\r\n"); + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_NOK; + } + + if (memcpy_s(config->pre_shared_key, sizeof(config->pre_shared_key), connect_info.pwd, sizeof(connect_info.pwd)) != + EOK) { + HILINK_SAL_ERROR("memcpy_s error\r\n"); + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_NOK; + } + + if (memcpy_s(config->bssid, sizeof(config->bssid), connect_info.bssid, sizeof(connect_info.bssid)) != + EOK) { + HILINK_SAL_ERROR("memcpy_s error\r\n"); + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_NOK; + } + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + return HILINK_SAL_OK; +} + +static int RemoveDevice(void) +{ + hilink_connect_info_t connect_info; + (void)memset_s(&connect_info, sizeof(connect_info), 0, sizeof(connect_info)); + + uint32_t nv_ret = ERRCODE_FAIL; + nv_ret = uapi_nv_write(NV_ID_HILINK_CONNECT_INFO, (uint8_t *)&connect_info, sizeof(connect_info)); + if (nv_ret != ERRCODE_SUCC) { + HILINK_SAL_ERROR("remove connect info to nv failed.\r\n"); + } + + return HILINK_SAL_OK; +} + +static int get_softap_local_ip(char *localIp, unsigned char len) +{ + struct netif *lwip_netif = netifapi_netif_find("ap0"); + if (lwip_netif == NULL) { + lwip_netif = netifapi_netif_find("wlan0"); + if (lwip_netif == NULL) { + return HILINK_SAL_GET_IP_ERR; + } + } + + if (memcpy_s(localIp, len, ip4addr_ntoa(&(lwip_netif->ip_addr.u_addr.ip4)), + strlen(ip4addr_ntoa(&(lwip_netif->ip_addr.u_addr.ip4)))) != EOK) { + return HILINK_SAL_GET_IP_ERR; + } + + return HILINK_SAL_OK; +} + +int HILINK_GetLocalIp(char *localIp, unsigned char len) +{ + if ((localIp == NULL) || (len == 0)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + /* 避免循环调用导致的打印刷屏 */ + static bool isPrint = false; + if (get_softap_local_ip(localIp, len) != HILINK_SAL_OK) { + if (!isPrint) { + HILINK_SAL_NOTICE("HILINK_GetLocalIp fail.\r\n"); + isPrint = true; + } + return HILINK_SAL_GET_IP_ERR; + } + isPrint = false; + + return HILINK_SAL_OK; +} + +int HILINK_GetMacAddr(unsigned char *mac, unsigned char len) +{ + if ((mac == NULL) || (len < WIFI_MAC_LEN)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + /* 从efuse获取mac地址 */ + unsigned char efuse_left_count = 0; + if (efuse_read_mac(mac, WIFI_MAC_LEN, &efuse_left_count) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("get device macaddr from efuse fail\r\n"); + return HILINK_SAL_GET_MAC_ERR; + } + + return HILINK_SAL_OK; +} + +static int GetWifiConfigFromOhos(wifi_sta_config_stru *config) +{ + if (config == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + wifi_sta_config_stru wifiConfig; + (void)memset_s(&wifiConfig, sizeof(wifiConfig), 0, sizeof(wifiConfig)); + + static bool isPrint = false; + if (GetDeviceConfigs(&wifiConfig) != HILINK_SAL_OK) { + if (!isPrint) { + HILINK_SAL_ERROR("get device config fail\r\n"); + isPrint = true; + } + (void)memset_s(&wifiConfig, sizeof(wifiConfig), 0, sizeof(wifiConfig)); + return HILINK_SAL_GET_WIFI_INFO_ERR; + } + isPrint = false; + + if (memcpy_s(config, sizeof(wifi_sta_config_stru), &wifiConfig, sizeof(wifi_sta_config_stru)) != EOK) { + HILINK_SAL_ERROR("memcpy error\r\n"); + (void)memset_s(&wifiConfig, sizeof(wifiConfig), 0, sizeof(wifiConfig)); + return HILINK_SAL_MEMCPY_ERR; + } + (void)memset_s(&wifiConfig, sizeof(wifiConfig), 0, sizeof(wifiConfig)); + return HILINK_SAL_OK; +} + +int HILINK_GetWiFiSsid(char *ssid, unsigned int *ssidLen) +{ + if ((ssid == NULL) || (ssidLen == NULL) || (*ssidLen == 0)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + wifi_sta_config_stru result; + (void)memset_s(&result, sizeof(result), 0, sizeof(result)); + /* 避免循环调用导致的打印刷屏 */ + static bool isPrint = false; + *ssidLen = 0; + int ret = GetWifiConfigFromOhos(&result); + if ((ret != HILINK_SAL_OK) || (result.ssid[0] == '\0') || (HILINK_Strlen((char *)result.ssid) >= + sizeof(result.ssid))) { + if (!isPrint) { + HILINK_SAL_NOTICE("get wifi ssid fail\r\n"); + isPrint = true; + } + /* 初次配网获取不到ssid */ + (void)memset_s(&result, sizeof(result), 0, sizeof(result)); + return HILINK_SAL_OK; + } + isPrint = false; + if (strcpy_s(ssid, WIFI_MAX_SSID_LEN, (char *)result.ssid) != EOK) { + HILINK_SAL_ERROR("strcpy error\r\n"); + (void)memset_s(&result, sizeof(result), 0, sizeof(result)); + return HILINK_SAL_STRCPY_ERR; + } + *ssidLen = HILINK_Strlen(ssid); + (void)memset_s(&result, sizeof(result), 0, sizeof(result)); + return HILINK_SAL_OK; +} + +int HILINK_SetWiFiInfo(const char *ssid, unsigned int ssidLen, const char *pwd, unsigned int pwdLen) +{ + wifi_sta_config_stru config; + (void)memset_s(&config, sizeof(wifi_sta_config_stru), 0, sizeof(wifi_sta_config_stru)); + + /* 删除旧wifi配置 */ + if (RemoveDevice() != HILINK_SAL_OK) { + HILINK_SAL_ERROR("remove config error\r\n"); + return HILINK_SAL_REMOVE_WIFI_ERR; + } + + if ((ssidLen != 0) && (ssid != NULL)) { + if (memcpy_s(config.ssid, sizeof(config.ssid), ssid, ssidLen) != EOK) { + HILINK_SAL_ERROR("memcpy error\r\n"); + return HILINK_SAL_MEMCPY_ERR; + } + } else { + HILINK_SAL_NOTICE("clear wifi info\r\n"); + return HILINK_SAL_OK; + } + + if ((pwdLen != 0) && (pwd != NULL)) { + if (memcpy_s(config.pre_shared_key, sizeof(config.pre_shared_key), pwd, pwdLen) != EOK) { + HILINK_SAL_ERROR("memcpy error\r\n"); + return HILINK_SAL_MEMCPY_ERR; + } + config.security_type = WIFI_SEC_TYPE_WPA2_WPA_PSK_MIX; + } else { + config.security_type = WIFI_SEC_TYPE_OPEN; + } + + int ret = AddDeviceConfig(&config); + (void)memset_s(&config, sizeof(wifi_sta_config_stru), 0, sizeof(wifi_sta_config_stru)); + if (ret != HILINK_SAL_OK) { + HILINK_SAL_ERROR("add device config error %d\r\n", ret); + return HILINK_SAL_SET_WIFI_ERR; + } + + return HILINK_SAL_OK; +} + +void HILINK_ReconnectWiFi(void) +{ + if (wifi_sta_disconnect() != ERRCODE_SUCC) { + HILINK_SAL_ERROR("disconnect wifi error\r\n"); + return; + } + if (HILINK_ConnectWiFi() != HILINK_SAL_OK) { + HILINK_SAL_ERROR("connect wifi fail\r\n"); + return; + } +} + +static void OnWifiScanStateChangedCallback(int state, int size) +{ + (void)size; + if (state == WIFI_STATE_AVALIABLE) { + g_isStaScanSuccess = true; + } +} + +static void OnWifiConnectionChangedCallback(int state, const wifi_linked_info_stru *info, int reason_code) +{ + (void)state; + (void)info; + + /* 0x8002,0x800e,0x800f: 密码错误场景对端返回的错误码 */ + if ((reason_code == 0x8002) || (reason_code == 0x800e) || (reason_code == 0x800f)) { + g_disconnectReason = 15; /* 15: 密码错误场景统一上报错误码 15 */ + } else { + g_disconnectReason = reason_code; + } + HILINK_SAL_NOTICE("state: %d, disconnectedReason %u\r\n", state, g_disconnectReason); + g_isReasonRefresh = true; +} + +static void OnHotspotStaJoinCallback(const wifi_sta_info_stru *info) +{ + (void)info; + HILINK_SAL_NOTICE("OnHotspotStaJoinCallback...\r\n"); +} + +static void OnHotspotStaLeaveCallback(const wifi_sta_info_stru *info) +{ + (void)info; + HILINK_SAL_NOTICE("OnHotspotStaLeaveCallback...\r\n"); +} + +static void OnHotspotStateChangedCallback(int state) +{ + (void)state; + HILINK_SAL_NOTICE("OnHotspotStateChangedCallback, state[%d]\r\n", state); +} + +static int RegisterWifiEventToOhos(void) +{ + if (g_isRegisterWifiEvent) { + HILINK_SAL_NOTICE("wifievent has been registered.\r\n"); + return HILINK_SAL_OK; + } + + g_eventHandler.wifi_event_scan_state_changed = OnWifiScanStateChangedCallback; + g_eventHandler.wifi_event_connection_changed = OnWifiConnectionChangedCallback; + g_eventHandler.wifi_event_softap_sta_join = OnHotspotStaJoinCallback; + g_eventHandler.wifi_event_softap_sta_leave = OnHotspotStaLeaveCallback; + g_eventHandler.wifi_event_softap_state_changed = OnHotspotStateChangedCallback; + + if (wifi_register_event_cb(&g_eventHandler) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("Register wifi event fail.\r\n"); + return HILINK_SAL_SET_WIFI_ERR; + } + g_isRegisterWifiEvent = true; + return HILINK_SAL_OK; +} + +static int AdvanceScanWifiByOhos(const wifi_sta_config_stru *config) +{ + int scanTimeout = DEF_SCAN_TIMEOUT; + g_isStaScanSuccess = false; + + wifi_scan_params_stru scanParams; + (void)memset_s(&scanParams, sizeof(scanParams), 0, sizeof(scanParams)); + + if (memcpy_s(scanParams.ssid, sizeof(scanParams.ssid), config->ssid, + HILINK_Strlen((char *)config->ssid)) != EOK) { + HILINK_SAL_ERROR("memcpy error\r\n"); + return HILINK_SAL_MEMCPY_ERR; + } + scanParams.scan_type = WIFI_SSID_SCAN; + scanParams.ssid_len = (char)HILINK_Strlen((char *)config->ssid); + + if (wifi_sta_scan_advance(&scanParams) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("wifi advance scan fail\r\n"); + (void)memset_s(&scanParams, sizeof(scanParams), 0, sizeof(scanParams)); + return HILINK_SAL_SCAN_WIFI_ERR; + } + + while (scanTimeout > 0) { + HILINK_MilliSleep(MS_PER_SECOND); + scanTimeout--; + if (g_isStaScanSuccess == true) { + break; + } + } + if (scanTimeout == 0) { + HILINK_SAL_ERROR("wifi advance scan timeout\r\n"); + (void)memset_s(&scanParams, sizeof(scanParams), 0, sizeof(scanParams)); + return HILINK_SAL_SCAN_WIFI_ERR; + } + (void)memset_s(&scanParams, sizeof(scanParams), 0, sizeof(scanParams)); + return HILINK_SAL_OK; +} + +static bool GetScanWifiResultFromOhos(const wifi_sta_config_stru *config, wifi_scan_info_stru *info) +{ + bool ret = false; + unsigned int size = WIFI_SCAN_AP_LIMIT; + unsigned int resultSize = sizeof(wifi_scan_info_stru) * size; + wifi_scan_info_stru *result = (wifi_scan_info_stru *)HILINK_Malloc(resultSize); + if (result == NULL) { + HILINK_SAL_ERROR("malloc error\r\n"); + return false; + } + (void)memset_s(result, resultSize, 0, resultSize); + + if (wifi_sta_get_scan_info(result, &size) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("Get wifi scan info fail.\r\n"); + HILINK_Free(result); + return false; + } + + if ((size == 0) || (size > WIFI_SCAN_AP_LIMIT)) { + HILINK_SAL_WARN("can not scan any wifi or scan size over limit, size:%u\r\n", size); + HILINK_Free(result); + return false; + } + for (unsigned int i = 0; i < size; ++i) { + /* 匹配目标wifi:ssid完全匹配,且WiFi加密类型应同时open或者同时不为open */ + if ((HILINK_Strcmp((char *)result[i].ssid, (char *)config->ssid) == 0) && + ((config->security_type != WIFI_SEC_TYPE_OPEN && result[i].security_type != WIFI_SEC_TYPE_OPEN) || + (config->security_type == WIFI_SEC_TYPE_OPEN && result[i].security_type == WIFI_SEC_TYPE_OPEN))) { + HILINK_SAL_NOTICE("find target ssid success\r\n"); + if (memcpy_s(info, sizeof(wifi_scan_info_stru), &result[i], sizeof(wifi_scan_info_stru)) != EOK) { + HILINK_SAL_ERROR("memcpy error\r\n"); + break; + } + ret = true; + break; + } + } + + HILINK_Free(result); + return ret; +} + +static void SetSecurityTypeByScanInfo(wifi_sta_config_stru *config, const wifi_scan_info_stru *info) +{ + wifi_sta_config_stru tempConfig; + (void)memset_s(&tempConfig, sizeof(wifi_sta_config_stru), 0, sizeof(wifi_sta_config_stru)); + if (memcpy_s(&tempConfig, sizeof(wifi_sta_config_stru), config, sizeof(wifi_sta_config_stru)) != EOK) { + HILINK_SAL_ERROR("memcpy_s error\r\n"); + return; + } + + if (memset_s(config->bssid, sizeof(config->bssid), 0, sizeof(config->bssid)) != EOK) { + HILINK_SAL_ERROR("memset_s error\r\n"); + } + + if (info->security_type == WIFI_SEC_TYPE_INVALID) { + /* 扫描出的加密方式非法时根据有无密码使用默认的PSK或OPEN加密方式 */ + config->security_type = (config->pre_shared_key[0] == '\0') ? WIFI_SEC_TYPE_OPEN : + WIFI_SEC_TYPE_WPA2_WPA_PSK_MIX; + } else { + config->security_type = info->security_type; + } + + if (config->security_type == WIFI_SEC_TYPE_WEP) { + unsigned char pwdLen = HILINK_Strlen((char *)config->pre_shared_key); + /* 设置密码,海思要求WEP的5和13位ASCII密码需要用双引号包起来,对应长度需要-2处理 */ + if ((pwdLen == 5) || (pwdLen == 13)) { + char tmpSharedKey[WIFI_MAX_KEY_LEN] = {0}; + tmpSharedKey[0] = '\"'; + if (memcpy_s(tmpSharedKey + 1, sizeof(tmpSharedKey) - 2, config->pre_shared_key, pwdLen) != EOK) { + (void)memset_s(&tempConfig, sizeof(wifi_sta_config_stru), 0, sizeof(wifi_sta_config_stru)); + return; + } + tmpSharedKey[pwdLen + 1] = '\"'; + if (memcpy_s(config->pre_shared_key, sizeof(config->pre_shared_key), tmpSharedKey, + WIFI_MAX_KEY_LEN) != EOK) { + (void)memset_s(&tempConfig, sizeof(wifi_sta_config_stru), 0, sizeof(wifi_sta_config_stru)); + (void)memset_s(tmpSharedKey, sizeof(tmpSharedKey), 0, sizeof(tmpSharedKey)); + return; + } + (void)memset_s(tmpSharedKey, sizeof(tmpSharedKey), 0, sizeof(tmpSharedKey)); + } + } + + /* wifi配置与扫描后的结果对比,如果不同,需要刷新wifi配置 */ + if (HILINK_Memcmp(config, &tempConfig, sizeof(wifi_sta_config_stru)) != 0) { + if (RemoveDevice() != HILINK_SAL_OK) { + HILINK_SAL_ERROR("remove config error\r\n"); + (void)memset_s(&tempConfig, sizeof(wifi_sta_config_stru), 0, sizeof(wifi_sta_config_stru)); + return; + } + if (AddDeviceConfig(config) != HILINK_SAL_OK) { + HILINK_SAL_ERROR("add config fail\r\n"); + (void)memset_s(&tempConfig, sizeof(wifi_sta_config_stru), 0, sizeof(wifi_sta_config_stru)); + return; + } + } + + (void)memset_s(&tempConfig, sizeof(wifi_sta_config_stru), 0, sizeof(wifi_sta_config_stru)); + return; +} + +int HILINK_RestartWiFi(void) +{ + int ret; + if (wifi_is_sta_enabled() == 1) { + ret = wifi_sta_disable(); + if (ret != ERRCODE_SUCC) { + HILINK_SAL_ERROR("disable wifi error, ret = %d\r\n", ret); + return HILINK_SAL_NOK; + } + } + + ret = wifi_sta_enable(); + if (ret != ERRCODE_SUCC) { + HILINK_SAL_ERROR("enable wifi error, ret = %d\r\n", ret); + return HILINK_SAL_NOK; + } + HILINK_Printf("hilink restarted wifi station\r\n"); + return HILINK_SAL_OK; +} + +int HILINK_ConnectWiFiByBssid(int securityType, const unsigned char *bssid, unsigned int len) +{ + if ((bssid == NULL) || (len == 0)) { + HILINK_SAL_ERROR("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + /* 初始化WiFi */ + if (wifi_is_sta_enabled() != 1) { + if (wifi_sta_enable() != ERRCODE_SUCC) { + HILINK_SAL_ERROR("enable wifi fail\r\n"); + return HILINK_SAL_SET_WIFI_ERR; + } + } + + if (RegisterWifiEventToOhos() != HILINK_SAL_OK) { + HILINK_SAL_ERROR("register wifi event fail\r\n"); + return HILINK_SAL_SET_WIFI_ERR; + } + + g_isReasonRefresh = false; + + int netConnect = WIFI_DISCONNECTED; + if (HILINK_GetNetworkState(&netConnect) != HILINK_SAL_OK) { + /* 网络状态获取失败,不退出继续连接 */ + HILINK_SAL_ERROR("get network state failed\r\n"); + } + if (netConnect == WIFI_CONNECTED) { + /* 断开当前连接并重连 */ + if (wifi_sta_disconnect() != ERRCODE_SUCC) { + HILINK_SAL_ERROR("disconnect wifi error\r\n"); + return HILINK_SAL_CONENCT_WIFI_ERR; + } + } + + wifi_sta_config_stru config; + (void)memset_s(&config, sizeof(config), 0, sizeof(config)); + if (GetWifiConfigFromOhos(&config) != HILINK_SAL_OK) { + return HILINK_SAL_GET_WIFI_INFO_ERR; + } + + config.ip_type = DHCP; + if (memcpy_s(config.bssid, sizeof(config.bssid), bssid, len) != EOK) { + HILINK_SAL_ERROR("memcpy error\r\n"); + return HILINK_SAL_MEMCPY_ERR; + } + if (wifi_sta_connect(&config) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("connect to wifi fail.\n"); + return HILINK_SAL_CONENCT_WIFI_ERR; + } + + if (sta_setup_dhcp() != 0) { + HILINK_SAL_ERROR("set sta dhcp failed\r\n"); + return HILINK_SAL_CONENCT_WIFI_ERR; + } + + return HILINK_SAL_OK; +} + +int HILINK_GetLastConnectResult(int *result) +{ + if (result == NULL) { + HILINK_SAL_ERROR("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + if (!g_isReasonRefresh) { + return HILINK_SAL_NOK; + } + + *result = g_disconnectReason; + g_isReasonRefresh = false; + return HILINK_SAL_OK; +} + +static int BuildScanParam(const HILINK_APScanParam *param, wifi_scan_params_stru *scanParams) +{ + HILINK_WifiScanType scanType = param->scanType; + HILINK_SAL_DEBUG("scan type: %d\r\n", scanType); + + switch (scanType) { + case WIFI_SCAN_TPYE_SSID: { + unsigned int ssidLen = HILINK_Strlen((char *)param->ssid); + if ((param->ssid[0] == '\0') || (ssidLen != param->ssidLen)) { + HILINK_SAL_ERROR("invalid ssid param, len: %u, strlen: %u\r\n", param->ssidLen, ssidLen); + return HILINK_SAL_PARAM_INVALID; + } + if (memcpy_s(scanParams->ssid, sizeof(scanParams->ssid), param->ssid, param->ssidLen) != EOK) { + HILINK_SAL_ERROR("memcpy error\r\n"); + return HILINK_SAL_MEMCPY_ERR; + } + scanParams->scan_type = WIFI_SSID_SCAN; + scanParams->ssid_len = param->ssidLen; + break; + } + case WIFI_SCAN_TPYE_BSSID: { + if (memcpy_s(scanParams->bssid, sizeof(scanParams->bssid), param->bssid, sizeof(param->ssid)) != EOK) { + HILINK_SAL_ERROR("memcpy error\r\n"); + return HILINK_SAL_MEMCPY_ERR; + } + scanParams->scan_type = WIFI_BSSID_SCAN; + break; + } + case WIFI_SCAN_TPYE_FREQ: { + scanParams->scan_type = WIFI_CHANNEL_SCAN; + break; + } + default: + HILINK_SAL_ERROR("not support scan type, type: %d\r\n", scanType); + return HILINK_SAL_PARAM_INVALID; + } + + return HILINK_SAL_OK; +} + +int HILINK_ScanAP(const HILINK_APScanParam *param) +{ + if (param == NULL) { + HILINK_SAL_ERROR("scan param invalid\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + /* 激活WiFi */ + if (wifi_is_sta_enabled() != 1) { + if (wifi_sta_enable() != ERRCODE_SUCC) { + HILINK_SAL_ERROR("enable wifi fail\r\n"); + return HILINK_SAL_SET_WIFI_ERR; + } + } + if ((get_wifi_recovery_type() != 0) && (g_offline_mode_scan_flag == 0)) { + wifi_scan_strategy_stru scan_strategy; + scan_strategy.scan_time = 105; /* 105: 单信道扫描停留时间105ms */ + scan_strategy.scan_cnt = 2; /* 2: 每个信道扫描2次 */ + scan_strategy.single_probe_send_times = 1; /* 1: 单信道扫描每次发送一个probe request */ + scan_strategy.reserved = 0; + if (wifi_sta_set_scan_policy(IFTYPE_STA, &scan_strategy) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("sta_set_scan_policy failed\r\n"); + } + g_offline_mode_scan_flag = 1; /* 1: 已完成离线优化模式扫描策略设置 */ + } + + if (RegisterWifiEventToOhos() != HILINK_SAL_OK) { + HILINK_SAL_ERROR("register wifi event fail\r\n"); + return HILINK_SAL_SET_WIFI_ERR; + } + + /* 指定WiFi的ssid进行扫描 */ + g_isStaScanSuccess = false; + HILINK_SAL_ERROR("ready WIFI_SCAN_TPYE_BASIC\r\n"); + if (param->scanType == WIFI_SCAN_TPYE_BASIC) { + HILINK_SAL_ERROR("in WIFI_SCAN_TPYE_BASIC\r\n"); + if (wifi_sta_scan() != ERRCODE_SUCC) { + HILINK_SAL_ERROR("wifi scan fail\r\n"); + return HILINK_SAL_SCAN_WIFI_ERR; + } + return HILINK_SAL_OK; + } + HILINK_SAL_ERROR("out WIFI_SCAN_TPYE_BASIC\r\n"); + /* 组装扫描参数,填充SSID */ + wifi_scan_params_stru scanParams; + (void)memset_s(&scanParams, sizeof(scanParams), 0, sizeof(scanParams)); + int ret = BuildScanParam(param, &scanParams); + if (ret != HILINK_SAL_OK) { + HILINK_SAL_ERROR("build scan param failed\r\n"); + return ret; + } + if (wifi_sta_scan_advance(&scanParams) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("wifi advance scan fail\r\n"); + return HILINK_SAL_SCAN_WIFI_ERR; + } + (void)memset_s(&scanParams, sizeof(scanParams), 0, sizeof(scanParams)); + + return HILINK_SAL_OK; +} + +static int GetScanWifiResultList(wifi_scan_info_stru **list, unsigned int *listSize) +{ + unsigned int size = WIFI_SCAN_AP_LIMIT; + wifi_scan_info_stru *result = (wifi_scan_info_stru *)HILINK_Malloc(sizeof(wifi_scan_info_stru) * size); + if (result == NULL) { + HILINK_SAL_ERROR("malloc error\r\n"); + return HILINK_SAL_MALLOC_ERR; + } + (void)memset_s(result, sizeof(wifi_scan_info_stru) * size, 0, sizeof(wifi_scan_info_stru) * size); + + if (wifi_sta_get_scan_info(result, &size) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("Get wifi scan info fail.\r\n"); + HILINK_Free(result); + return HILINK_SAL_SCAN_WIFI_ERR; + } + *list = result; + *listSize = size; + return HILINK_SAL_OK; +} + +static int CopyScanWifiResultList(HILINK_APList *scanList, wifi_scan_info_stru *result, unsigned int resSize) +{ + unsigned int infoSize = sizeof(HILINK_APInfo) * resSize; + HILINK_APInfo *info = (HILINK_APInfo *)HILINK_Malloc(infoSize); + if (info == NULL) { + HILINK_SAL_ERROR("malloc error\r\n"); + return HILINK_SAL_MALLOC_ERR; + } + (void)memset_s(info, infoSize, 0, infoSize); + for (unsigned int i = 0; i < resSize; i++) { + if ((strcpy_s(info[i].ssid, sizeof(info[i].ssid), result[i].ssid) != EOK) || + (memcpy_s(info[i].bssid, sizeof(info[i].bssid), result[i].bssid, sizeof(result[i].bssid)) != EOK)) { + HILINK_Free(info); + return HILINK_SAL_MEMCPY_ERR; + } + info[i].rssi = result[i].rssi; + info[i].band = result[i].band; + info[i].securityType = result[i].security_type; + info[i].frequency = result[i].channel_num; + } + scanList->apList = info; + scanList->num = resSize; + return HILINK_SAL_OK; +} + +int HILINK_GetAPScanResult(HILINK_APList *scanList) +{ + if (scanList == NULL) { + HILINK_SAL_ERROR("invalid params\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + if (!g_isStaScanSuccess) { + // HILINK_SAL_NOTICE("AP scanning is not complete.\r\n"); + return WIFI_SCANNING; + } + + unsigned int size = 0; + wifi_scan_info_stru *scanInfo = NULL; + int ret = GetScanWifiResultList(&scanInfo, &size); + if (ret != HILINK_SAL_OK) { + HILINK_SAL_ERROR("get scan wifi list failed, ret = %d.\r\n", ret); + return ret; + } + + HILINK_SAL_NOTICE("scan result size: %u\r\n", size); + if (size == 0) { + HILINK_Free(scanInfo); + scanList->apList = NULL; + scanList->num = 0; + return HILINK_SAL_OK; + } + + ret = CopyScanWifiResultList(scanList, scanInfo, size); + if (ret != HILINK_SAL_OK) { + HILINK_SAL_ERROR("copy wifi list failed, ret = %d.\r\n", ret); + (void)memset_s(scanInfo, size * sizeof(wifi_scan_info_stru), 0, size * sizeof(wifi_scan_info_stru)); + HILINK_Free(scanInfo); + scanInfo = NULL; + return ret; + } + + (void)memset_s(scanInfo, size * sizeof(wifi_scan_info_stru), 0, size * sizeof(wifi_scan_info_stru)); + HILINK_Free(scanInfo); + scanInfo = NULL; + + return HILINK_SAL_OK; +} + +int HILINK_ConnectWiFi(void) +{ + int ret; + wifi_sta_config_stru config; + (void)memset_s(&config, sizeof(config), 0, sizeof(config)); + wifi_scan_info_stru info; + (void)memset_s(&info, sizeof(info), 0, sizeof(info)); + + if (wifi_is_sta_enabled() != 1) { + if (wifi_sta_enable() != ERRCODE_SUCC) { + HILINK_SAL_ERROR("enable wifi fail\r\n"); + return HILINK_SAL_SET_WIFI_ERR; + } + } + + if (RegisterWifiEventToOhos() != HILINK_SAL_OK) { + HILINK_SAL_ERROR("register wifi event fail\r\n"); + return HILINK_SAL_SET_WIFI_ERR; + } + + if (GetWifiConfigFromOhos(&config) != HILINK_SAL_OK) { + HILINK_SAL_ERROR("get wifi config fail\r\n"); + return HILINK_SAL_GET_WIFI_INFO_ERR; + } + + if (config.ssid[0] == '\0') { + HILINK_SAL_ERROR("ssid null\r\n"); + return HILINK_SAL_GET_WIFI_INFO_ERR; + } + + for (unsigned int i = 0; i < MAX_SCAN_TIMES; ++i) { + if (AdvanceScanWifiByOhos(&config) != HILINK_SAL_OK) { + HILINK_SAL_ERROR("advance scan wifi fail\r\n"); + (void)memset_s(&config, sizeof(wifi_sta_config_stru), 0, sizeof(wifi_sta_config_stru)); + return HILINK_SAL_SCAN_WIFI_ERR; + } + if (GetScanWifiResultFromOhos(&config, &info)) { + SetSecurityTypeByScanInfo(&config, &info); + break; + } + HILINK_SAL_NOTICE("not find target wifi, try again\r\n"); + } + + /* 1 5 10 5 :非离线优化模式使能自动重连,单次重连超时时间 5秒,重连间隔10秒 ,最大重连次数3600次 */ + if (wifi_sta_set_reconnect_policy(1, 5, 10, 3600) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("set reconnect policy error.\r\n"); + } + + config.ip_type = DHCP; + if (wifi_sta_connect(&config) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("connect to wifi fail.\n"); + return HILINK_SAL_CONENCT_WIFI_ERR; + } + + if (sta_setup_dhcp() != 0) { + HILINK_SAL_ERROR("set sta dhcp failed\r\n"); + return HILINK_SAL_CONENCT_WIFI_ERR; + } + return HILINK_SAL_OK; +} + +int HILINK_GetNetworkState(int *state) +{ + if (state == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + wifi_linked_info_stru info; + (void)memset_s(&info, sizeof(info), 0, sizeof(info)); + /* 获取不到linkinfo时认为网络未连接 */ + if (wifi_sta_get_ap_info(&info) != ERRCODE_SUCC) { + info.conn_state = WIFI_DISCONNECTED; + } + + *state = (info.conn_state == WIFI_CONNECTED) ? 1 : 0; + return HILINK_SAL_OK; +} + +int HILINK_GetWiFiBssid(unsigned char *bssid, unsigned char *bssidLen) +{ + if ((bssid == NULL) || (bssidLen == NULL) || (*bssidLen == 0)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + wifi_linked_info_stru info; + (void)memset_s(&info, sizeof(wifi_linked_info_stru), 0, sizeof(wifi_linked_info_stru)); + + if (wifi_sta_get_ap_info(&info) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("get wifi linked info fail\r\n"); + return HILINK_SAL_GET_WIFI_INFO_ERR; + } + + if (memcpy_s(bssid, *bssidLen, info.bssid, sizeof(info.bssid)) != EOK) { + HILINK_SAL_ERROR("memcpy error\r\n"); + return HILINK_SAL_MEMCPY_ERR; + } + + *bssidLen = WIFI_MAC_LEN; + return HILINK_SAL_OK; +} + +int HILINK_GetWiFiRssi(signed char *rssi) +{ + if (rssi == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + wifi_linked_info_stru info; + (void)memset_s(&info, sizeof(wifi_linked_info_stru), 0, sizeof(wifi_linked_info_stru)); + if (wifi_sta_get_ap_info(&info) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("get wifi linked info fail\r\n"); + return HILINK_SAL_GET_WIFI_INFO_ERR; + } + + *rssi = (signed char)info.rssi; + return HILINK_SAL_OK; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_open_ota_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_open_ota_adapter.c new file mode 100755 index 0000000..b730da9 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_open_ota_adapter.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: OTA适配实现 (此文件为DEMO,需集成方适配修改) + */ +#include "hilink_open_ota_adapter.h" +#include "securec.h" +#include "sfc.h" +#include "partition.h" +#include "upg_porting.h" +#include "upg_common_porting.h" +#include "partition_resource_id.h" +#include "hilink_sal_defines.h" +#include "watchdog.h" + +typedef struct { + /* 升级的偏移 */ + unsigned int write_offset; + /* 可升级区域的总大小 */ + unsigned int max_size; +} upg_param; + +/* 记录升级相关的信息,比如开始地址,擦写块信息,可升级的最大区域 */ +static upg_param g_upgrade; + +const sfc_flash_config_t sfc_cfg = { + .read_type = FAST_READ_QUAD_OUTPUT, + .write_type = PAGE_PROGRAM, + .mapping_addr = 0x200000, + .mapping_size = 0x800000, +}; + +static errcode_t upg_get_upgrade_part_start_addr(uint32_t *start_address) +{ + errcode_t ret_val; + partition_information_t info; + ret_val = uapi_partition_get_info(PARTITION_FOTA_DATA, &info); + if (ret_val != ERRCODE_SUCC) { + return ret_val; + } + *start_address = info.part_info.addr_info.addr; + return ERRCODE_SUCC; +} + +static errcode_t upg_get_upgrade_part_size(uint32_t *size) +{ + errcode_t ret_val; + partition_information_t info; + ret_val = uapi_partition_get_info(PARTITION_FOTA_DATA, &info); + if (ret_val != ERRCODE_SUCC) { + return ret_val; + } + if (info.part_info.addr_info.size < UPG_UPGRADE_FLAG_LENGTH) { + HILINK_SAL_WARN("size=%u,%u\r\n", info.part_info.addr_info.size , UPG_UPGRADE_FLAG_LENGTH); + return -1; + } + *size = info.part_info.addr_info.size - UPG_UPGRADE_FLAG_LENGTH; + return ERRCODE_SUCC; +} + +/* + * Flash初始化 + * 返回值是true时,表示初始化正常 + * 返回值是false时,表示初始化异常 + */ +bool HILINK_OtaAdapterFlashInit(void) +{ + uint32_t ret = uapi_sfc_init((sfc_flash_config_t *)&sfc_cfg); + if (ret != ERRCODE_SUCC) { + return false; + } + if (memset_s(&g_upgrade, sizeof(upg_param), 0, sizeof(upg_param)) != EOK) { + return false; + } + uint32_t size = 0; + if (upg_get_upgrade_part_size(&size) != 0) { + HILINK_SAL_WARN("get upgrade max file len fail.\r\n"); + return false; + } + g_upgrade.max_size = size; + return true; +} + +/* + * 判断需要升级的分区 + * 返回值是UPGRADE_FW_BIN1时,表示升级固件到分区1 + * 返回值是UPGRADE_FW_BIN2时,表示升级固件到分区2 + */ +unsigned int HILINK_OtaAdapterGetUpdateIndex(void) +{ + return UPGRADE_FW_BIN1; +} + +/* + * 擦除需要升级的分区 + * size表示需要擦除的分区大小 + * 返回值是RETURN_OK时,表示擦除成功 + * 返回值是RETURN_ERROR时,表示擦除失败 + */ +int HILINK_OtaAdapterFlashErase(unsigned int size) +{ + errcode_t ret_val; + if (size > g_upgrade.max_size) { + return RETURN_ERROR; + } + upg_prepare_info_t prepare_info; + + prepare_info.package_len = size; + ret_val = uapi_upg_prepare(&prepare_info); + if (ret_val != ERRCODE_SUCC) { + return RETURN_ERROR; + } + return RETURN_OK; +} + +/* + * 升级数据写入升级的分区 + * buf表示待写入数据 + * bufLen表示待写入数据的长度 + * 返回值是RETURN_OK时,表示写入成功 + * 返回值是RETURN_ERROR时,表示写入失败 + */ + +/* TODO 需要记录写入后的offset */ +int HILINK_OtaAdapterFlashWrite(const unsigned char *buf, unsigned int bufLen) +{ + if ((buf == NULL) || (bufLen == 0)) { + return RETURN_ERROR; + } + (void)uapi_watchdog_kick(); + + errcode_t ret_val; + uint32_t start_addr; + if ((g_upgrade.write_offset + bufLen) > g_upgrade.max_size) { + return RETURN_ERROR; + } + ret_val = upg_get_upgrade_part_start_addr(&start_addr); + if (ret_val != ERRCODE_SUCC) { + return RETURN_ERROR; + } + // 写入 + ret_val = upg_flash_write(start_addr + g_upgrade.write_offset, bufLen, buf, false); + if (ret_val != ERRCODE_SUCC) { + return RETURN_ERROR; + } + g_upgrade.write_offset += bufLen; + return RETURN_OK; +} + +/* + * 读取升级分区数据 + * offset表示读写偏移 + * buf表示输出数据的内存地址 + * bufLen表示输出数据的内存长度 + * 返回值是RETURN_OK时,表示读取成功 + * 返回值是RETURN_ERROR时,表示读取失败 + */ +int HILINK_OtaAdapterFlashRead(unsigned int offset, unsigned char *buf, unsigned int bufLen) +{ + errcode_t ret_val; + uint32_t start_addr; + if ((buf == NULL) || (bufLen == 0) || ((offset + bufLen) > g_upgrade.max_size)) { + return RETURN_ERROR; + } + ret_val = upg_get_upgrade_part_start_addr(&start_addr); + if (ret_val != ERRCODE_SUCC) { + return RETURN_ERROR; + } + // 读取 + ret_val = upg_flash_read(start_addr + offset, bufLen, buf); + if (ret_val != ERRCODE_SUCC) { + return RETURN_ERROR; + } + return RETURN_OK; +} + +/* + * 分区升级结束 + * 返回值是true时,表示结束正常 + * 返回值是false时,表示结束异常 + */ + + /* 下载镜像结束,需要调起本地升级的接口 */ +bool HILINK_OtaAdapterFlashFinish(void) +{ + errcode_t ret; + ret = uapi_upg_request_upgrade(false); + if (ret != ERRCODE_SUCC) { + return false; + } + + return true; +} + +/* 获取升级区间最大长度 */ +unsigned int HILINK_OtaAdapterFlashMaxSize(void) +{ + errcode_t ret_val; + uint32_t size; + ret_val = upg_get_upgrade_part_size(&size); + if (ret_val != ERRCODE_SUCC) { + return 0; + } + return size; +} + +/* + * 根据标志重启模组 + * flag表示重启标志 + * 当flag是RESTART_FLAG_NOW时,表示只有MCU升级时立即重启 + * 当flag是RESTART_FLAG_LATER时,表示有模组时切换分区后再重启 + */ +void HILINK_OtaAdapterRestart(int flag) +{ + upg_reboot(); + return; +} + +/* + * 开始模组升级 + * type表示升级类型 + * 当type是UPDATE_TYPE_MANUAL时,表示本次升级流程是由用户主动发起的手动升级 + * 当type是UPDATE_TYPE_AUTO时,表示本次升级流程是经过用户同意的自动升级 + * 返回值是RETURN_OK时,表示处理成功,HiLink SDK将开始启动升级流程 + * 返回值是RETURN_ERROR时,表示处理不成功,HiLink SDK将终止本次升级流程 + * 注意:在手动场景场景下,HiLink SDK在接收到用户发出的升级指令后,将直接调用此接口; + * 在自动升级场景下,当HiLink SDK在调用HilinkGetRebootFlag接口返回值是MODULE_CAN_REBOOT时,HiLink SDK将调用此接口。 + * 厂商可在此接口中完成和升级流程相关的处理。 + * 开机后10分钟到1小时内随机时间检测一次是否有新版本,之后以当前时间为起点,23小时加1小时内随机值周期性检测新版本。 + * 如果用户打开了自动升级开关,检测到有新版本并且是可以重启的情况下,就进行新版本的下载,下载完成后自动重启。 + * 自动升级流程可能在凌晨进行,因此厂商在实现升级流程相关功能时,确保在升级的下载安装固件和重启设备时避免对用户产生 + * 影响,比如发出声音,光亮等。 + */ +int HILINK_OtaStartProcess(int type) +{ + return RETURN_OK; +} + +/* + * 模组升级结束 + * status表示升级结果 + * 当status是100时,表示升级成功 + * 当status不是100时,表示升级失败 + * 返回值是RETURN_OK时,表示处理成功,HiLink SDK将置升级标志或切换运行区标志 + * 返回值不是RETURN_OK时,表示处理不成功,HiLink SDK将终止本次升级流程 + * 注意:HiLink SDK在将固件写入到OTA升级区后,且完整性校验通过后,将调用厂商适配的此接口; + * 厂商可在此接口中完成和升级流程相关的处理。 + * 开机后10分钟到1小时内随机时间检测一次是否有新版本,之后以当前时间为起点,23小时加1小时内随机值周期性检测新版本。 + * 如果用户打开了自动升级开关,检测到有新版本并且是可以重启的情况下,就进行新版本的下载,下载完成后自动重启。 + * 自动升级流程可能在凌晨进行,因此厂商在实现升级流程相关功能时,确保在升级的下载安装固件和重启设备时避免对用户产生 + * 影响,比如发出声音,光亮等;升级类型是否为自动升级可参考接口HilinkOtaStartProcess的参数type的描述。 + */ +int HILINK_OtaEndProcess(int status) +{ + return RETURN_OK; +} + +/* + * 判断模组是否能立即升级并重启 + * 返回值是MODULE_CAN_REBOOT时,表示模组可以立即升级并重启,HiLink SDK将开始自动升级流程。 + * 返回值是MODULE_CANNOT_REBOOT时,表示模组不能立即升级并重启,HiLink SDK将不进行本次自动升级流程。 + * 注意:在用户同意设备可以自动升级的情况下,HiLink SDK调用此接口获取设备当前业务状态下,模组是否可以立即升级并重启的标志。 + * 只有当设备处于业务空闲状态时,接口才可以返回MODULE_CAN_REBOOT。 + * 当设备处于业务非空闲状态时,接口返回MODULE_CANNOT_REBOOT。 + */ +int HILINK_GetRebootFlag(void) +{ + return MODULE_CAN_REBOOT; +} diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_open_ota_mcu_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_open_ota_mcu_adapter.c new file mode 100755 index 0000000..5990234 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_open_ota_mcu_adapter.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 外挂MCU升级适配实现(此文件为DEMO,需集成方适配修改) + */ + +#include "hilink_open_ota_mcu_adapter.h" +#ifdef HF_MCU_OTA +#include "mcu_update.h" +#include "hsf.h" +#endif +/* + * 获取MCU当前版本 + * version表示版本字符串 + * inLen表示输入字符串长度 + * outLen表示输出字符串长度 + * 返回值是RETURN_OK时,表示获取成功 + * 返回值是RETURN_ERROR_NO_MCU时,表示没有MCU + * 返回值是RETURN_ERROR时,表示获取失败 + * 返回值是RETURN_MCU_NO_NEED_OTA时,表示不需要MCU升级 + * 注意:如果获取不到MCU的版本,则不对MCU进行升级。 + * 建议厂商在MCU正常启动后,或升级启动后,就将MCU的版本号传递给模组,确保模组可以获取到MCU的版本。 + */ +int HILINK_GetMcuVersion(char *version, unsigned int inLen, unsigned int *outLen) +{ + /* 厂商实现此接口 */ + #ifdef HF_MCU_OTA + *outLen = sprintf(version, "%s", hf_get_mcu_ver()); + u_printf("mcu version:%s len:%d\r\n", version, *outLen); + #endif + return RETURN_OK; +} + +/* + * HiLink SDK调用厂商适配的此接口通知MCU固件传输的状态 + * flag表示升级流程标志 + * 当flag是START_SEND_DATA时,表示通知模组即将开始发送MCU固件数据包 + * 当flag是STOP_SEND_DATA时,表示通知模组完整的MCU固件包已发送完成 + * 当flag是SEND_DATA_ERROR时,表示通知模组本次MCU固件升级异常终止 + * len表示MCU固件包的大小 + * type表示升级类型 + * 当type是UPDATE_TYPE_MANUAL时,表示本次升级流程是由用户主动发起的手动升级 + * 当type是UPDATE_TYPE_AUTO时,表示本次升级流程是经过用户同意的自动升级 + * 返回值是RETURN_OK时,表示处理成功,HiLink SDK继续正常处理后续流程 + * 返回值是RETURN_ERROR时,表示处理失败,HiLink SDK将终止本次MCU升级流程 + * 注意:当flag是STOP_SEND_DATA时,此接口需返回MCU侧固件升级的结果;当flag是其它值时,需返回接口接收到此消息后的处理结果。 + * 开机后10分钟到1小时内随机时间检测一次是否有新版本,之后以当前时间为起点,23小时加1小时内随机值周期性检测新版本。 + * 如果用户打开了自动升级开关,检测到有新版本并且是可以重启的情况下,就进行新版本的下载,下载完成后自动重启。 + * 自动升级流程可能在凌晨进行,因此厂商在实现升级流程相关功能时,确保在升级的下载安装固件和重启设备时避免对用户产生 + * 影响,比如发出声音,光亮等。 + */ +int HILINK_NotifyOtaStatus(int flag, unsigned int len, unsigned int type) +{ + /* 厂商实现此接口 */ + #ifdef HF_MCU_OTA + u_printf("mcu ota flag:%d type:%d len:%d\n", flag, type, len); + hf_save_mcu_status(flag, len); + if(flag == 0) + { + int offset=0; + int page=32*1024; + while(offset < MAX_UPGRADE_FILE_SIZE) + { + flash_erase_page(UPGRADE_ADDRESS+offset,8); + offset+=page; + } + u_printf("erase flash len:%d\r\n", offset); + } + #endif + return RETURN_OK; +} + +/* + * HiLink SDK调用厂商适配的此接口通知厂商发送MCU固件文件数据 + * data表示发送的数据 + * len表示发送的数据的长度 + * offset表示发送的数据起始位置相对于完整固件包的偏移量 + * 此接口需要返回MCU接收这部分数据的处理结果 + * 返回值是RETURN_OK时,模组将通知的数据正确发送给MCU,且MCU正确处理发送的数据,HiLink SDK将继续正常处理后续流程 + * 返回值是RETURN_ERROR时,模组或MCU未能正常处理通知的MCU的固件文件数据,HiLink SDK将终止本次MCU固件升级流程 + */ +int HILINK_NotifyOtaData(const unsigned char *data, unsigned int len, unsigned int offset) +{ + /* 厂商实现此接口 */ + #ifdef HF_MCU_OTA + u_printf("write flash addr:%x len:%d\r\n", UPGRADE_ADDRESS + offset, len); + flash_write(UPGRADE_ADDRESS + offset, (unsigned char *)data, len,0); + #endif + return RETURN_OK; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_quick_netcfg_demo.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_quick_netcfg_demo.c new file mode 100755 index 0000000..b4e8ad5 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_quick_netcfg_demo.c @@ -0,0 +1,319 @@ + +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved. + * Description: 设备通过80211 wifi管理帧实现文件demo + */ + +#ifdef SUPPORT_QUICK_NETCFG + +#include "hilink_quick_netcfg_demo.h" +#include +#include +#include +#include +#include "soc_wifi_api.h" +#include "hilink.h" +#include "hilink_custom.h" +#include "hilink_quick_netcfg_api.h" +#include "hilink_quick_netcfg_adapter.h" +#include "hilink_thread_adapter.h" +#include "hilink_softap_adapter.h" +#include "hilink_str_adapter.h" +#include "hilink_network_adapter.h" +#include "wifi_device_config.h" +#include "securec.h" +#include "nv_common_cfg.h" +#include "nv.h" +#include "hilink_sal_defines.h" + + +#define QUICK_NETCFG_TASK_SIZE 4096 +#define CMD_MAX_LEN 2048 +#define QUICK_CFG_DELEAY 1500 +#define CHAN_DEFAULT 6 +#define SCAN_WIFI_SSID "TestScanAp" + +static osal_char g_ifName[WIFI_IFNAME_MAX_SIZE + 1] = "ap0"; +static void *g_quickCfgTask = NULL; +static bool g_isRecvReginfo = false; + +extern int HILINK_Printf(const char *format, ...); +#define BATCH_CFG "batchCfg" +#define BATCH_CFG_PRINTF(fmt, args...) HILINK_Printf("[%s][%s:%d] " fmt "\n", BATCH_CFG, __FUNCTION__, __LINE__, ##args); + +static bool IsWifiExsit(void) +{ + hilink_connect_info_t result = {0}; + + uint16_t result_len = 0; + uint32_t nv_ret = ERRCODE_FAIL; + nv_ret = uapi_nv_read(NV_ID_HILINK_CONNECT_INFO, sizeof(hilink_connect_info_t), &result_len, + (uint8_t *)&result); + if (nv_ret != ERRCODE_SUCC) { + BATCH_CFG_PRINTF("read hilink connect info from nv failed"); + return false; + } + if ((result.ssid[0] != 0) && (strlen((char *)result.ssid) > 0) && + (result.pwd[0] != 0) && (strlen((char *)result.pwd) > 0)) { + return true; + } + + return false; +} + +static int SetRoutName(WiFiMode mode) +{ + (void)memset_s(g_ifName, sizeof(g_ifName), 0, sizeof(g_ifName)); + if (mode == STA_MODE) { + if (memcpy_s(g_ifName, sizeof(g_ifName), "wlan0", strlen("wlan0")) != 0) { + return -1; + } + } else if (mode == AP_MODE) { + if (memcpy_s(g_ifName, sizeof(g_ifName), "ap0", strlen("ap0")) != 0) { + return -1; + } + } else { + return -1; + } + return 0; +} + +/* + * 功能:开启Wifi混杂模式时注册此函数 + * 参数: frame: 802.11 frame,len:长度 + * 返回:失败返回-1,成功返回0 + */ +static int QuickCfgReceiveFrame(void* frame, int len, signed char rssi) +{ + (void)rssi; + return HILINK_FrameParse((const unsigned char *)frame, (unsigned int)len); +} + +/* + * 功能:开启wifi帧混杂模式,需注册IEEE 802.11 frames收包回调函数 + * 返回:成功返回0,失败返回非零 + */ +static int QuickCfgStartPromisMode(void) +{ + if (check_wifi_is_station()) { + BATCH_CFG_PRINTF("SetRoutName STA_MODE"); + SetRoutName(STA_MODE); + } else { + BATCH_CFG_PRINTF("SetRoutName AP_MODE"); + SetRoutName(AP_MODE); + } + + ext_wifi_ptype_filter_stru filter = {0}; + filter.mdata_en = 0; + filter.udata_en = 0; + filter.mmngt_en = 1; // 开启管理帧接收 + filter.umngt_en = 1; // 开启管理帧接收 + filter.custom_en = 0; + uapi_wifi_promis_set_rx_callback(QuickCfgReceiveFrame); + int ret = uapi_wifi_promis_enable(g_ifName, 1, &filter); + if (ret != 0) { + BATCH_CFG_PRINTF("hi_wifi_promis_enable: set error! ifName: %s, ret: %d", g_ifName, ret); + return ret; + } + BATCH_CFG_PRINTF("Start Promis Mode success, ifName: %s", g_ifName); + return 0; +} + +/* 关闭wifi帧混杂模式 */ +static int QuickCfgStopPromisMode(void) +{ + ext_wifi_ptype_filter_stru filter = {0}; + BATCH_CFG_PRINTF("QuickCfgStopPromisMode:: g_ifName: %s", g_ifName); + int ret = uapi_wifi_promis_enable(g_ifName, 0, &filter); + if (ret != 0) { + BATCH_CFG_PRINTF("hi_wifi_promis_disable:: set error. ret: %d", ret); + return ret; + } + BATCH_CFG_PRINTF("Stop Promis Mode success, ifName: %s", g_ifName); + return 0; +} + +/* 切换wifi模式 */ +static int QuickCfgSetWifiMode(WiFiMode mode) +{ + int ret; + BATCH_CFG_PRINTF("[SetWifiMode] set mode=%u\n", mode); + if (mode == STA_MODE) { + HILINK_StopSoftAp(); + memset_s(g_ifName, sizeof(g_ifName), 0, sizeof(g_ifName)); + int len = sizeof(g_ifName); + ret = uapi_wifi_sta_start(g_ifName, &len); + if (ret != EXT_WIFI_OK) { + BATCH_CFG_PRINTF("hi_wifi_sta_start fail, ret=%d\n", ret); + return -1; + } + } else { + if (!IsWifiExsit()) { + ret = uapi_wifi_sta_stop(); + if (ret != EXT_WIFI_OK) { + BATCH_CFG_PRINTF("hi_wifi_sta_stop fail, ret=%d\n", ret); + return ret; + } + ret = HILINK_SetSoftAPMode(); + if (ret != 0) { + BATCH_CFG_PRINTF("Start SoftAP fail, ret=%d\n", ret); + return ret; + } + } + } + return 0; +} + +/* 切换wifi信道(平台相关) */ +static int QuickCfgWiFiSetChannel(int chan) +{ + return uapi_wifi_set_channel(g_ifName, WIFI_IFNAME_MAX_SIZE + 1, chan); +} + +/* 获取wifi信道(平台相关) */ +static int QuickCfgWiFiGetChannel(int *chan) +{ + if (chan == NULL) { + return -1; + } + + *chan = uapi_wifi_get_channel(g_ifName, WIFI_IFNAME_MAX_SIZE + 1); + return 0; +} + +/* IEEE 802.11 frames的发送函数 */ +static int QuickCfgSendFrame(const unsigned char *buff, unsigned int len) +{ + return uapi_wifi_send_custom_pkt(g_ifName, buff, len); +} + +/* 获取设备mac地址 */ +static int QuickCfgGetDevMac(unsigned char *mac, unsigned int len) +{ + return HILINK_GetMacAddr(mac, len); +} + +/* + * 设置配网信息, 作为设备端必须设置,配置端不需要 + * 返回0表示设置成功,其他表示设置失败(-2表示HiLink未处于接收配网数据状态) + */ +static int QuickCfgSetNetConfigInfo(const char *info) +{ + if (info == NULL) { + BATCH_CFG_PRINTF("[QuickCfgSetNetConfigInfo]Invalid param\n"); + return -1; + } + + int ret = uapi_wifi_sta_stop(); + if (ret != EXT_WIFI_OK) { + BATCH_CFG_PRINTF("[QuickCfgSetNetConfigInfo]hi_wifi_sta_stop fail, ret=%d\n", ret); + } + ret = HILINK_SetNetConfigInfo(info); + if (ret != 0) { + BATCH_CFG_PRINTF("[QuickCfgSetNetConfigInfo]Set NetConfig Info fail, ret=%d\n", ret); + return ret; + } + + g_isRecvReginfo = true; + return 0; +} + +/* 获取设备wifi信息 */ +static int QuickCfgGetWifiInfo(char *payload, unsigned int len) +{ + hilink_connect_info_t result = {0}; + uint16_t result_len = 0; + uint32_t nv_ret = ERRCODE_FAIL; + nv_ret = uapi_nv_read(NV_ID_HILINK_CONNECT_INFO, sizeof(hilink_connect_info_t), &result_len, + (uint8_t *)&result); + if (nv_ret != ERRCODE_SUCC) { + BATCH_CFG_PRINTF("read hilink connect info from nv failed"); + return -1; + } + + BATCH_CFG_PRINTF("[QuickCfgGetWifiInfo]ssid: %s, pwd: %s. ret=%d\n", result.ssid, result.pwd); + int ret = sprintf_s(payload, len, "{\"ssid\":\"%s\",\"pwd\":\"%s\"}", result.ssid, result.pwd); + if (ret <= 0) { + BATCH_CFG_PRINTF("[QuickCfgGetWifiInfo]sBATCH_CFG_PRINTF_s fail, ret=%d\n", ret); + return -1; + } + return 0; +} + +/* 启动扫描wifi信息 */ +static int QuickCfgScanWifi(void) +{ + HILINK_APScanParam param; + (void)memset_s(¶m, sizeof(HILINK_APScanParam), 0, sizeof(HILINK_APScanParam)); + if (strcpy_s(param.ssid, sizeof(param.ssid), SCAN_WIFI_SSID) != 0) { + BATCH_CFG_PRINTF("[QuickCfgScanWifi]copy ssid failed"); + return -1; + } + param.ssidLen = HILINK_Strlen(SCAN_WIFI_SSID); + int ret = HILINK_ScanAP(¶m); + if (ret != 0) { + BATCH_CFG_PRINTF("[QuickCfgScanWifi]wifi scan failed, ret=%d", ret); + return -1; + } + return 0; +} + +static void QuickCfgProcess(void *arg) +{ + /* 批量配网注册wifi驱动相关接口 */ + QuickCfgWifiLoader wifiLoader = { + QuickCfgStartPromisMode, + QuickCfgStopPromisMode, + QuickCfgWiFiGetChannel, + QuickCfgWiFiSetChannel, + QuickCfgSetWifiMode, + QuickCfgSendFrame, + QuickCfgScanWifi, + }; + HILINK_SetQuickCfgWifiLoader(&wifiLoader, sizeof(QuickCfgWifiLoader)); + + /* 批量配网注册通用相关接口 */ + QuickCfgCommonLoader commonLoader = { + DEVICE_TYPE, + CMD_MAX_LEN, + DISABLE_SET_CHAN, + QuickCfgGetDevMac, + QuickCfgGetWifiInfo, + NULL, + QuickCfgSetNetConfigInfo, + HILINK_RequestRegInfo, + }; + HILINK_SetQuickCfgCommonLoader(&commonLoader, sizeof(QuickCfgCommonLoader)); + + /* 延时等待HILINK_Main完全启动后启动批量配网 */ + HILINK_MilliSleep(QUICK_CFG_DELEAY); + /* 如果设备已注册不启动批量配网 */ + if (HILINK_IsRegister() != 0 || IsWifiExsit()) { + return; + } + + HILINK_StartQuickCfg(); +} + +/* + * 启动批量配网任务 + * 注意:为兼容softap配网在HILINK_Main启动后再启动次任务 + */ +int StartQuickNetCfg(void) +{ + HiLinkTaskParam taskParam = { + (HiLinkTaskEntryFunc)QuickCfgProcess, + HILINK_TASK_PRIORITY_MID, + QUICK_NETCFG_TASK_SIZE, + NULL, + "QuickCfgTask", + }; + g_quickCfgTask = HILINK_CreateTask(&taskParam); + if (g_quickCfgTask == NULL) { + BATCH_CFG_PRINTF("[StartQuickNetCfg]Create TestWifiProcess task failed"); + return -1; + } + BATCH_CFG_PRINTF("[StartQuickNetCfg]Create g_quickCfgTask ok"); + return 0; +} +#endif \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_aes.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_aes.c new file mode 100755 index 0000000..52d8981 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_aes.c @@ -0,0 +1,418 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: AES加解密适配层接口mbedTLS实现(此文件为DEMO,需集成方适配修改) + */ +#include "hilink_sal_aes.h" +#include +#include "securec.h" +#include "mbedtls/gcm.h" +#include "mbedtls/aes.h" +#include "osal_debug.h" + +#if defined(HILINK_MBEDTLS_CCM_SUPPORT) || !defined(HILINK_SDK_BUILD_IN) +#include "mbedtls/cipher.h" +#include "mbedtls/ccm.h" +#endif + +#define BITS_PER_BYTES 8 + +static bool IsAesGcmParamValid(const HiLinkAesGcmParam *param) +{ + if (param == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return false; + } + + if ((param->iv == NULL) || (param->ivLen == 0)) { + HILINK_SAL_WARN("invalid iv\r\n"); + return false; + } + + if ((param->key == NULL) || + ((param->keyLen != HILINK_AES_128_KEY_BYTE_LEN) && + (param->keyLen != HILINK_AES_192_KEY_BYTE_LEN) && + (param->keyLen != HILINK_AES_256_KEY_BYTE_LEN))) { + HILINK_SAL_WARN("invalid key\r\n"); + return false; + } + + if ((param->data == NULL) || (param->dataLen == 0)) { + HILINK_SAL_WARN("invalid data\r\n"); + return false; + } + + if (((param->addLen != 0) && (param->add == NULL)) || + ((param->addLen == 0) && (param->add != NULL))) { + HILINK_SAL_WARN("invalid add\r\n"); + return false; + } + + return true; +} +//static void hilink_dump_gcm(mbedtls_gcm_context *ctx, mbedtls_cipher_id_t id, const unsigned char *key, +// unsigned int keybits) +//{ +// int i; +// osal_printk("\r\nhilink mbedtls_gcm_context:\r\n"); +// char *tmp = (char *)ctx; +// for (i = 0; i < sizeof(mbedtls_gcm_context); i++) { +// osal_printk("%02x ", tmp[i]); +// } +// osal_printk("\r\nid: %d\r\n", id); +// osal_printk("\r\nkey:\r\n"); +// for (i = 0; i < keybits / BITS_PER_BYTES; i++) { +// osal_printk("%02x ", key[i]); +// } +// osal_printk("\r\nkeylen: %d\r\n", keybits / BITS_PER_BYTES); +//} +int HILINK_SAL_AesGcmEncrypt(const HiLinkAesGcmParam *param, unsigned char *tag, + unsigned int tagLen, unsigned char *buf) +{ + if (!IsAesGcmParamValid(param)) { + return HILINK_SAL_PARAM_INVALID; + } + + mbedtls_gcm_context context; + mbedtls_gcm_init(&context); + int ret; + do { +// hilink_dump_gcm(&context, MBEDTLS_CIPHER_ID_AES, +// param->key, param->keyLen * BITS_PER_BYTES); + ret = mbedtls_gcm_setkey(&context, MBEDTLS_CIPHER_ID_AES, + param->key, param->keyLen * BITS_PER_BYTES); + if (ret != 0) { + HILINK_SAL_ERROR("set key err %d\r\n", ret); + break; + } + + ret = mbedtls_gcm_crypt_and_tag(&context, MBEDTLS_GCM_ENCRYPT, param->dataLen, + param->iv, param->ivLen, param->add, param->addLen, param->data, + buf, tagLen, tag); + if (ret != 0) { + HILINK_SAL_ERROR("encrypt err %d\r\n", ret); + break; + } + } while (false); + + mbedtls_gcm_free(&context); + return ret; +} + +int HILINK_SAL_AesGcmDecrypt(const HiLinkAesGcmParam *param, const unsigned char *tag, + unsigned int tagLen, unsigned char *buf) +{ + if (!IsAesGcmParamValid(param)) { + return HILINK_SAL_PARAM_INVALID; + } + + mbedtls_gcm_context context; + mbedtls_gcm_init(&context); + int ret; + do { +// hilink_dump_gcm(&context, MBEDTLS_CIPHER_ID_AES, +// param->key, param->keyLen * BITS_PER_BYTES); + ret = mbedtls_gcm_setkey(&context, MBEDTLS_CIPHER_ID_AES, + param->key, param->keyLen * BITS_PER_BYTES); + if (ret != 0) { + HILINK_SAL_ERROR("set key err %d\r\n", ret); + break; + } + + ret = mbedtls_gcm_auth_decrypt(&context, param->dataLen, param->iv, param->ivLen, + param->add, param->addLen, tag, tagLen, + param->data, buf); + if (ret != 0) { + HILINK_SAL_ERROR("decrypt err %d\r\n", ret); + break; + } + } while (false); + + mbedtls_gcm_free(&context); + return ret; +} + +static mbedtls_cipher_padding_t GetMbedtlsPaddingMode(HiLinkPaddingMode mode) +{ + switch (mode) { + case HILINK_PADDING_PKCS7: + return MBEDTLS_PADDING_PKCS7; + case HILINK_PADDING_ONE_AND_ZEROS: + return MBEDTLS_PADDING_ONE_AND_ZEROS; + case HILINK_PADDING_ZEROS_AND_LEN: + return MBEDTLS_PADDING_ZEROS_AND_LEN; + case HILINK_PADDING_ZEROS: + return MBEDTLS_PADDING_ZEROS; + default: + HILINK_SAL_WARN("invalid mode\r\n"); + return MBEDTLS_PADDING_NONE; + } +} + +static int MbedtlsPaddingCipherInit(HiLinkPaddingMode mode, mbedtls_cipher_context_t *ctx, + mbedtls_cipher_info_t *info) +{ + (void)memset_s(info, sizeof(mbedtls_cipher_info_t), 0, sizeof(mbedtls_cipher_info_t)); + mbedtls_cipher_init(ctx); +#ifdef MBEDTLS_VERSION_3 + ctx->MBEDTLS_PRIVATE(cipher_info) = info; + info->MBEDTLS_PRIVATE(mode) = MBEDTLS_MODE_CBC; +#else + ctx->cipher_info = info; + info->mode = MBEDTLS_MODE_CBC; +#endif + + int ret = mbedtls_cipher_set_padding_mode(ctx, GetMbedtlsPaddingMode(mode)); + if (ret != 0) { + HILINK_SAL_ERROR("set padding mode failed %d\r\n", ret); + return ret; + } + return HILINK_SAL_OK; +} + +int HILINK_SAL_AddPadding(HiLinkPaddingMode mode, unsigned char *out, unsigned int outLen, unsigned int dataLen) +{ + if ((out == NULL) || (outLen == 0) || (dataLen == 0) || (outLen < dataLen)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + mbedtls_cipher_context_t cipherContext; + mbedtls_cipher_info_t cipherInfo; + int ret = MbedtlsPaddingCipherInit(mode, &cipherContext, &cipherInfo); + if (ret != 0) { + return ret; + } + +#ifdef MBEDTLS_VERSION_3 + if (cipherContext.MBEDTLS_PRIVATE(add_padding) == NULL) { +#else + if (cipherContext.add_padding == NULL) { +#endif + HILINK_SAL_ERROR("add padding func err %d\r\n", mode); + return HILINK_SAL_NOT_SUPPORT; + } +#ifdef MBEDTLS_VERSION_3 + cipherContext.MBEDTLS_PRIVATE(add_padding)(out, outLen, dataLen); +#else + cipherContext.add_padding(out, outLen, dataLen); +#endif + return HILINK_SAL_OK; +} + +int HILINK_SAL_GetPadding(HiLinkPaddingMode mode, const unsigned char *input, unsigned int inputLen, + unsigned int *dataLen) +{ + if ((input == NULL) || (inputLen == 0) || (dataLen == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + mbedtls_cipher_context_t cipherContext; + mbedtls_cipher_info_t cipherInfo; + int ret = MbedtlsPaddingCipherInit(mode, &cipherContext, &cipherInfo); + if (ret != 0) { + return ret; + } + +#ifdef MBEDTLS_VERSION_3 + if (cipherContext.MBEDTLS_PRIVATE(get_padding) == NULL) { +#else + if (cipherContext.get_padding == NULL) { +#endif + HILINK_SAL_ERROR("get padding func err %d\r\n", mode); + return HILINK_SAL_NOT_SUPPORT; + } + + size_t outLen = *dataLen; +#ifdef MBEDTLS_VERSION_3 + ret = cipherContext.MBEDTLS_PRIVATE(get_padding)((unsigned char *)input, inputLen, &outLen); +#else + ret = cipherContext.get_padding((unsigned char *)input, inputLen, &outLen); +#endif + if (ret != 0) { + HILINK_SAL_ERROR("get padding err %d\r\n", ret); + return ret; + } + *dataLen = outLen; + return HILINK_SAL_OK; +} + +static bool IsAesCbcParamValid(const HiLinkAesCbcParam *param) +{ + if (param == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return false; + } + + if (param->iv == NULL) { + HILINK_SAL_WARN("invalid iv\r\n"); + return false; + } + + if ((param->key == NULL) || + ((param->keyLen != HILINK_AES_128_KEY_BYTE_LEN) && + (param->keyLen != HILINK_AES_192_KEY_BYTE_LEN) && + (param->keyLen != HILINK_AES_256_KEY_BYTE_LEN))) { + HILINK_SAL_WARN("invalid key\r\n"); + return false; + } + + if ((param->data == NULL) || (param->dataLen == 0) || + /* cbc加解密要求数据长度为16的倍数 */ + (param->dataLen % 16 != 0)) { + HILINK_SAL_WARN("invalid data\r\n"); + return false; + } + + return true; +} + +static int AesCbcCrypt(const HiLinkAesCbcParam *param, unsigned char *buf, int mode) +{ + mbedtls_aes_context context; + mbedtls_aes_init(&context); + + int ret; + if (mode == MBEDTLS_AES_DECRYPT) { + ret = mbedtls_aes_setkey_dec(&context, param->key, param->keyLen * BITS_PER_BYTES); + } else { + ret = mbedtls_aes_setkey_enc(&context, param->key, param->keyLen * BITS_PER_BYTES); + } + if (ret != 0) { + HILINK_SAL_ERROR("set key err %d\r\n", ret); + return ret; + } + + /* mbedtls_aes_crypt_cbc接口调用后会修改iv值,所以使用局部变量而非原始iv值 */ + unsigned char iv[HILINK_AES_CBC_IV_LEN] = {0}; + if (memcpy_s(iv, sizeof(iv), param->iv, HILINK_AES_CBC_IV_LEN) != EOK) { + HILINK_SAL_ERROR("memcpy err\r\n"); + return HILINK_SAL_MEMCPY_ERR; + } + + ret = mbedtls_aes_crypt_cbc(&context, mode, param->dataLen, iv, param->data, buf); + (void)memset_s(iv, sizeof(iv), 0, sizeof(iv)); + if (ret != 0) { + HILINK_SAL_ERROR("crypt err %d mode %d\r\n", ret, mode); + } +#if defined(MBEDTLS_HARDEN_OPEN) + mbedtls_aes_free(&context); +#endif + return ret; +} + +int HILINK_SAL_AesCbcEncrypt(const HiLinkAesCbcParam *param, unsigned char *buf) +{ + if (!IsAesCbcParamValid(param)) { + return HILINK_SAL_PARAM_INVALID; + } + return AesCbcCrypt(param, buf, MBEDTLS_AES_ENCRYPT); +} + +int HILINK_SAL_AesCbcDecrypt(const HiLinkAesCbcParam *param, unsigned char *buf) +{ + if (!IsAesCbcParamValid(param)) { + return HILINK_SAL_PARAM_INVALID; + } + return AesCbcCrypt(param, buf, MBEDTLS_AES_DECRYPT); +} + +#if defined(HILINK_MBEDTLS_CCM_SUPPORT) || !defined(HILINK_SDK_BUILD_IN) +static bool IsAesCcmParamValid(const HiLinkAesCcmParam *param) +{ + if (param == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return false; + } + + if ((param->iv == NULL) || (param->ivLen == 0)) { + HILINK_SAL_WARN("invalid iv\r\n"); + return false; + } + + if ((param->key == NULL) || + ((param->keyLen != HILINK_AES_128_KEY_BYTE_LEN) && + (param->keyLen != HILINK_AES_192_KEY_BYTE_LEN) && + (param->keyLen != HILINK_AES_256_KEY_BYTE_LEN))) { + HILINK_SAL_WARN("invalid key\r\n"); + return false; + } + + if ((param->data == NULL) || (param->dataLen == 0)) { + HILINK_SAL_WARN("invalid data\r\n"); + return false; + } + + if ((param->addLen != 0) && (param->add == NULL)) { + HILINK_SAL_WARN("invalid add\r\n"); + return false; + } + + return true; +} + +int HILINK_SAL_AesCcmDecrypt(const HiLinkAesCcmParam *param, const unsigned char *tag, + unsigned int tagLen, unsigned char *buf) +{ + if (!IsAesCcmParamValid(param)) { + return HILINK_SAL_PARAM_INVALID; + } + + mbedtls_ccm_context context; + mbedtls_ccm_init(&context); + + int ret; + do { + ret = mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, + param->key, param->keyLen * BITS_PER_BYTES); + if (ret != 0) { + HILINK_SAL_ERROR("set key err %d\r\n", ret); + break; + } + + ret = mbedtls_ccm_auth_decrypt(&context, param->dataLen, param->iv, param->ivLen, + param->add, param->addLen, param->data, buf, + tag, tagLen); + if (ret != 0) { + HILINK_SAL_ERROR("decrypt err %d\r\n", ret); + break; + } + } while (0); + + mbedtls_ccm_free(&context); + HILINK_SAL_INFO("Decrypt outdata success\r\n"); + return ret; +} +int HILINK_SAL_AesCcmEncrypt(const HiLinkAesCcmParam *param, unsigned char *tag, unsigned int tagLen, + unsigned char *buf) +{ + if (!IsAesCcmParamValid(param)) { + return HILINK_SAL_PARAM_INVALID; + } + + mbedtls_ccm_context context; + mbedtls_ccm_init(&context); + int ret; + do { + ret = mbedtls_ccm_setkey(&context, MBEDTLS_CIPHER_ID_AES, + param->key, param->keyLen * BITS_PER_BYTES); + if (ret != 0) { + HILINK_SAL_ERROR("set key err %d\r\n", ret); + break; + } + + ret = mbedtls_ccm_encrypt_and_tag(&context, param->dataLen, + param->iv, param->ivLen, + param->add, param->addLen, + param->data, buf, + tag, tagLen); + if (ret != 0) { + HILINK_SAL_ERROR("encrypt err %d\r\n", ret); + break; + } + } while (0); + + mbedtls_ccm_free(&context); + return ret; +} +#endif \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_base64.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_base64.c new file mode 100755 index 0000000..e14081d --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_base64.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: base64编码解码适配层接口mbedTLS实现(此文件为DEMO,需集成方适配修改) + */ +#include "hilink_sal_base64.h" + +#include +#include "hilink_sal_defines.h" +#include "mbedtls/base64.h" + +int HILINK_SAL_Base64Encode(const unsigned char *inData, unsigned int inLen, + unsigned char *outData, unsigned int *outLen) +{ + if ((inData == NULL) || (inLen == 0) || (outLen == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + size_t outSize = *outLen; + int ret; + + if ((outData == NULL) || (*outLen == 0)) { + ret = mbedtls_base64_encode(NULL, 0, &outSize, inData, inLen); + if ((ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) || (outSize == 0)) { + HILINK_SAL_ERROR("get base64 max size error, ret %d\r\n", ret); + return HILINK_SAL_PARAM_INVALID; + } + *outLen = outSize; + return HILINK_SAL_OK; + } + + ret = mbedtls_base64_encode(outData, outSize, &outSize, inData, inLen); + if (ret != 0) { + HILINK_SAL_ERROR("base64 encode error, ret %d\r\n", ret); + return ret; + } + *outLen = outSize; + + return HILINK_SAL_OK; +} + +int HILINK_SAL_Base64Decode(const unsigned char *inData, unsigned int inLen, + unsigned char *outData, unsigned int *outLen) +{ + if ((inData == NULL) || (inLen == 0) || (outLen == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + size_t outSize = *outLen; + int ret; + + if ((outData == NULL) || (*outLen == 0)) { + ret = mbedtls_base64_decode(NULL, 0, &outSize, inData, inLen); + if ((ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) || (outSize == 0)) { + HILINK_SAL_ERROR("get base64 max size error, ret %d\r\n", ret); + return HILINK_SAL_PARAM_INVALID; + } + *outLen = outSize; + return HILINK_SAL_OK; + } + + ret = mbedtls_base64_decode(outData, outSize, &outSize, inData, inLen); + if (ret != 0) { + HILINK_SAL_ERROR("base64 decode error, ret %d\r\n", ret); + return ret; + } + *outLen = outSize; + + return HILINK_SAL_OK; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_drbg.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_drbg.c new file mode 100755 index 0000000..d90dacc --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_drbg.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 安全随机数适配层接口mbedTLS实现(此文件为DEMO,需集成方适配修改) + */ + +#include "hilink_sal_drbg.h" +#include +#include +#include "mbedtls/entropy.h" +#ifndef MBEDTLS_VERSION_3 +#include "mbedtls/entropy_poll.h" +#endif +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/platform.h" +#include "hilink_sal_defines.h" +#include "hilink_thread_adapter.h" +#include "hilink_time_adapter.h" +#include "hilink_stdio_adapter.h" +#include "hilink_str_adapter.h" +#include "securec.h" +#include "hilink_mem_adapter.h" + +#ifdef MBEDTLS_VERSION_3 +#define HILINK_MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 +#endif + +typedef struct HiLinkDrbgContextInner { + HiLinkMutexId mutex; + mbedtls_ctr_drbg_context drbg; + mbedtls_entropy_context entropy; +} HiLinkDrbgContextInner; + +/* 此函数为注册到mbedtls的熵源回调函数,按照mbedtls_entropy_f_source_ptr的定义进行实现 */ +static int HiLinkMbedtlsEntropySourceCallback(void *data, unsigned char *output, size_t len, size_t *outLen) +{ + (void)data; + if ((output == NULL) || (outLen == NULL)) { + HILINK_SAL_ERROR("invalid param\r\n"); + return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + } + + /* 支持安全随机数的平台直接使用安全随机数做熵源 */ + if (HILINK_Trng(output, len) == 0) { + *outLen = len; + return 0; + } + + HiLinkTimeval timeval = {0, 0}; + if (HILINK_GetOsTime(&timeval) != 0) { + HILINK_SAL_ERROR("get time err\r\n"); + return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + } + + if (memcpy_s(output, len, &timeval, sizeof(HiLinkTimeval)) != EOK) { + HILINK_SAL_ERROR("memcpy_s error\r\n"); + return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + } + *outLen = sizeof(HiLinkTimeval); + + return 0; +} + +static void *PlatformCalloc(size_t n, size_t size) +{ + if (size == 0) { + return NULL; + } + if (n > (UINT_MAX / size)) { + return NULL; + } + + /* 上层调用保证不会出现溢出 */ + unsigned int len = (unsigned int)(n * size); + if (len == 0) { + return NULL; + } + + void *data = HILINK_Malloc(len); + if (data != NULL) { + (void)memset_s((char *)data, len, 0, len); + } + + return data; +} + +HiLinkDrbgContext HILINK_SAL_DrbgInit(const char *custom) +{ + static bool isMbedtlsMemHookInit = false; + if (!isMbedtlsMemHookInit) { + (void)mbedtls_platform_set_calloc_free(PlatformCalloc, HILINK_Free); + isMbedtlsMemHookInit = true; + } + + HiLinkDrbgContextInner *ctx = (HiLinkDrbgContextInner *)HILINK_Malloc(sizeof(HiLinkDrbgContextInner)); + if (ctx == NULL) { + HILINK_SAL_ERROR("malloc err\r\n"); + return NULL; + } + (void)memset_s(ctx, sizeof(HiLinkDrbgContextInner), 0, sizeof(HiLinkDrbgContextInner)); + + do { + ctx->mutex = HILINK_MutexCreate(); + if (ctx->mutex == NULL) { + HILINK_SAL_ERROR("create mutex err\r\n"); + break; + } + + mbedtls_entropy_init(&ctx->entropy); + mbedtls_ctr_drbg_init(&ctx->drbg); + +#ifdef MBEDTLS_VERSION_3 + int ret = mbedtls_entropy_add_source(&ctx->entropy, HiLinkMbedtlsEntropySourceCallback, + NULL, HILINK_MBEDTLS_ENTROPY_MIN_HARDCLOCK, MBEDTLS_ENTROPY_SOURCE_STRONG); +#else + int ret = mbedtls_entropy_add_source(&ctx->entropy, HiLinkMbedtlsEntropySourceCallback, + NULL, MBEDTLS_ENTROPY_MIN_HARDCLOCK, MBEDTLS_ENTROPY_SOURCE_STRONG); +#endif + if (ret != 0) { + HILINK_SAL_ERROR("add entropy source error -0x%04x\r\n", -ret); + break; + } + + ret = mbedtls_ctr_drbg_seed(&ctx->drbg, mbedtls_entropy_func, &ctx->entropy, + (const unsigned char *)custom, custom == NULL ? 0 : HILINK_Strlen(custom)); + if (ret != 0) { + HILINK_SAL_ERROR("seed error -0x%04x\r\n", -ret); + break; + } + + mbedtls_ctr_drbg_set_prediction_resistance(&ctx->drbg, MBEDTLS_CTR_DRBG_PR_OFF); + + return ctx; + } while (false); + + HILINK_SAL_DrbgDeinit(ctx); + return NULL; +} + +void HILINK_SAL_DrbgDeinit(HiLinkDrbgContext ctx) +{ + if (ctx == NULL) { + return; + } + + HiLinkDrbgContextInner *innerCtx = (HiLinkDrbgContextInner *)ctx; + mbedtls_entropy_free(&innerCtx->entropy); + mbedtls_ctr_drbg_free(&innerCtx->drbg); + if (innerCtx->mutex != NULL) { + HILINK_MutexDestroy(innerCtx->mutex); + innerCtx->mutex = NULL; + } + HILINK_Free(innerCtx); +} + +int HILINK_SAL_DrbgRandom(HiLinkDrbgContext ctx, unsigned char *out, unsigned int outLen) +{ + if ((ctx == NULL) || (out == NULL) || (outLen == 0)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + HiLinkDrbgContextInner *innerCtx = (HiLinkDrbgContextInner *)ctx; + if (HILINK_MutexLock(innerCtx->mutex, HILINK_WAIT_FOREVER) != 0) { + HILINK_SAL_ERROR("mutex lock fail\r\n"); + return HILINK_SAL_MUTEX_ERR; + } + + int ret = mbedtls_ctr_drbg_random((void *)&innerCtx->drbg, out, outLen); + (void)HILINK_MutexUnlock(innerCtx->mutex); + if (ret != 0) { + HILINK_SAL_ERROR("get mbedtls random error -0x%04x\r\n", -ret); + return ret; + } + + return HILINK_SAL_OK; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_kdf.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_kdf.c new file mode 100755 index 0000000..7d56572 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_kdf.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 密钥派生算法适配层接口mbedTLS实现(此文件为DEMO,需集成方适配修改) + */ +#include "hilink_sal_kdf.h" + +#include +#include +#include "mbedtls/md.h" +#include "mbedtls/hkdf.h" +#include "mbedtls/pkcs5.h" +#include "hilink_mbedtls_utils.h" + +int HILINK_SAL_Hkdf(const HiLinkHkdfParam *param, unsigned char *key, unsigned int keyLen) +{ + bool isInvalid = ((param == NULL) || (param->material == NULL) || (key == NULL) || + (param->materialLen == 0) || (keyLen == 0)); + if (isInvalid) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(GetMbedtlsMdType(param->md)); + if (mdInfo == NULL) { + return HILINK_SAL_NOK; + } + + int ret = mbedtls_hkdf(mdInfo, param->salt, param->saltLen, param->material, + param->materialLen, param->info, param->infoLen, key, keyLen); + if (ret != 0) { + HILINK_SAL_WARN("hkdf error %d\r\n", ret); + return ret; + } + + return HILINK_SAL_OK; +} + +int HILINK_SAL_Pkcs5Pbkdf2Hmac(const HiLinkPbkdf2HmacParam *param, unsigned char *key, unsigned int keyLen) +{ + bool isInvalid = ((param == NULL) || (param->password == NULL) || (param->passwordLen == 0) || + (param->salt == NULL) || (param->saltLen == 0) || (key == NULL) || (keyLen == 0)); + if (isInvalid) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(GetMbedtlsMdType(param->md)); + if (mdInfo == NULL) { + HILINK_SAL_WARN("invalid md info\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + mbedtls_md_context_t context; + mbedtls_md_init(&context); + int ret; + + do { + /* 数字1表示使用HMAC */ + ret = mbedtls_md_setup(&context, mdInfo, 1); + if (ret != 0) { + HILINK_SAL_ERROR("md setup error %d\r\n", ret); + break; + } + + ret = mbedtls_pkcs5_pbkdf2_hmac(&context, param->password, param->passwordLen, + param->salt, param->saltLen, param->iterCount, keyLen, key); + if (ret != 0) { + HILINK_SAL_ERROR("mbedtls_pkcs5_pbkdf2_hmac error %d\r\n", ret); + break; + } + } while (false); + + mbedtls_md_free(&context); + return ret; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_md.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_md.c new file mode 100755 index 0000000..4fe5d45 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_md.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 消息摘要算法适配层接口mbedTLS实现(此文件为DEMO,需集成方适配修改) + */ +#include "hilink_sal_md.h" + +#include +#include +#include "mbedtls/sha256.h" +#ifdef SHA_384_512_SUPPROT +#include "mbedtls/sha512.h" +#endif +#include "mbedtls/md.h" +#include "securec.h" +#include "hilink_mem_adapter.h" + +typedef struct HiLinkMdContextInner { + HiLinkMdType type; + void *mbedtlsMdContext; +} HiLinkMdContextInner; + +mbedtls_md_type_t GetMbedtlsMdType(HiLinkMdType type) +{ + switch (type) { + case HILINK_MD_NONE: + return MBEDTLS_MD_NONE; + case HILINK_MD_SHA256: + return MBEDTLS_MD_SHA256; + case HILINK_MD_SHA384: + return MBEDTLS_MD_SHA384; + case HILINK_MD_SHA512: + return MBEDTLS_MD_SHA512; + default: + HILINK_SAL_WARN("invalid mode\r\n"); + return MBEDTLS_MD_NONE; + } +} + +bool IsMdLenInvalid(HiLinkMdType type, unsigned int len) +{ + if (type == HILINK_MD_SHA256) { + return len >= HILINK_MD_SHA256_BYTE_LEN; + } else if (type == HILINK_MD_SHA384) { + return len >= HILINK_MD_SHA384_BYTE_LEN; + } else if (type == HILINK_MD_SHA512) { + return len >= HILINK_MD_SHA512_BYTE_LEN; + } + HILINK_SAL_WARN("invalid type\r\n"); + return false; +} + +int HILINK_SAL_MdCalc(HiLinkMdType type, const unsigned char *inData, unsigned int inLen, + unsigned char *md, unsigned int mdLen) +{ + if ((inData == NULL) || (inLen == 0) || (md == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + int ret; + switch (type) { + case HILINK_MD_SHA256: + if (mdLen != HILINK_MD_SHA256_BYTE_LEN) { + HILINK_SAL_WARN("invalid md len\r\n"); + return HILINK_SAL_PARAM_INVALID; + } +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha256(inData, inLen, md, 0); +#else + ret = mbedtls_sha256_ret(inData, inLen, md, 0); +#endif + if (ret != 0) { + HILINK_SAL_ERROR("error, ret %d\r\n", ret); + } + return ret; +#ifdef SHA_384_512_SUPPROT + case HILINK_MD_SHA384: + if (mdLen != HILINK_MD_SHA384_BYTE_LEN) { + HILINK_SAL_WARN("invalid md len\r\n"); + return HILINK_SAL_PARAM_INVALID; + } +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha512(inData, inLen, md, 1); +#else + ret = mbedtls_sha512_ret(inData, inLen, md, 1); +#endif + if (ret != 0) { + HILINK_SAL_ERROR("error, ret %d\r\n", ret); + } + return ret; + case HILINK_MD_SHA512: + if (mdLen != HILINK_MD_SHA512_BYTE_LEN) { + HILINK_SAL_WARN("invalid md len\r\n"); + return HILINK_SAL_PARAM_INVALID; + } +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha512(inData, inLen, md, 0); +#else + ret = mbedtls_sha512_ret(inData, inLen, md, 0); +#endif + if (ret != 0) { + HILINK_SAL_ERROR("error, ret %d\r\n", ret); + } + return ret; +#endif + default: + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_NOT_SUPPORT; + } +} + +int HILINK_SAL_HmacCalc(const HiLinkHmacParam *param, unsigned char *hmac, unsigned int hmacLen) +{ + if ((param == NULL) || (param->key == NULL) || (param->keyLen == 0) || + (param->data == NULL) || (param->dataLen == 0) || (hmac == NULL) || + (!IsMdLenInvalid(param->md, hmacLen))) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(GetMbedtlsMdType(param->md)); + if (mdInfo == NULL) { + HILINK_SAL_WARN("invalid md type\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + int ret = mbedtls_md_hmac(mdInfo, param->key, param->keyLen, param->data, param->dataLen, hmac); + if (ret != 0) { + HILINK_SAL_ERROR("hmac error, ret %d\r\n", ret); + } + return ret; +} + +HiLinkMdContext HILINK_SAL_MdInit(HiLinkMdType type) +{ + HiLinkMdContextInner *ctx = (HiLinkMdContextInner *)HILINK_Malloc(sizeof(HiLinkMdContextInner)); + if (ctx == NULL) { + HILINK_SAL_ERROR("malloc error\r\n"); + return NULL; + } + (void)memset_s(ctx, sizeof(HiLinkMdContextInner), 0, sizeof(HiLinkMdContextInner)); + ctx->type = type; + if (ctx->type == HILINK_MD_SHA256) { + ctx->mbedtlsMdContext = (void *)HILINK_Malloc(sizeof(mbedtls_sha256_context)); +#ifdef SHA_384_512_SUPPROT + } else if ((ctx->type == HILINK_MD_SHA384) || (ctx->type == HILINK_MD_SHA512)) { + ctx->mbedtlsMdContext = (void *)HILINK_Malloc(sizeof(mbedtls_sha512_context)); +#endif + } + if (ctx->mbedtlsMdContext == NULL) { + HILINK_SAL_ERROR("invalid md type or malloc error\r\n"); + HILINK_Free(ctx); + return NULL; + } + int ret = HILINK_SAL_NOT_SUPPORT; + if (ctx->type == HILINK_MD_SHA256) { + mbedtls_sha256_init(ctx->mbedtlsMdContext); +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha256_starts(ctx->mbedtlsMdContext, 0); +#else + ret = mbedtls_sha256_starts_ret(ctx->mbedtlsMdContext, 0); +#endif +#ifdef SHA_384_512_SUPPROT + } else if (ctx->type == HILINK_MD_SHA384) { + mbedtls_sha512_init(ctx->mbedtlsMdContext); +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha512_starts(ctx->mbedtlsMdContext, 1); +#else + ret = mbedtls_sha512_starts_ret(ctx->mbedtlsMdContext, 1); +#endif + } else if (ctx->type == HILINK_MD_SHA512) { + mbedtls_sha512_init(ctx->mbedtlsMdContext); +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha512_starts(ctx->mbedtlsMdContext, 0); +#else + ret = mbedtls_sha512_starts_ret(ctx->mbedtlsMdContext, 0); +#endif +#endif + } + if (ret != 0) { + HILINK_SAL_ERROR("md init error %d\r\n", ret); + HILINK_Free(ctx->mbedtlsMdContext); + HILINK_Free(ctx); + return NULL; + } + return ctx; +} + +int HILINK_SAL_MdUpdate(HiLinkMdContext ctx, const unsigned char *inData, unsigned int inLen) +{ + if (ctx == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + HiLinkMdContextInner *ctxInner = (HiLinkMdContextInner *)ctx; + int ret = HILINK_SAL_NOT_SUPPORT; + if (ctxInner->type == HILINK_MD_SHA256) { +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha256_update(ctxInner->mbedtlsMdContext, inData, inLen); +#else + ret = mbedtls_sha256_update_ret(ctxInner->mbedtlsMdContext, inData, inLen); +#endif +#ifdef SHA_384_512_SUPPROT + } else if ((ctxInner->type == HILINK_MD_SHA384) || (ctxInner->type == HILINK_MD_SHA512)) { +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha512_update(ctxInner->mbedtlsMdContext, inData, inLen); +#else + ret = mbedtls_sha512_update_ret(ctxInner->mbedtlsMdContext, inData, inLen); +#endif +#endif + } + return ret; +} + +int HILINK_SAL_MdFinish(HiLinkMdContext ctx, unsigned char *outData, unsigned int outLen) +{ + if (ctx == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + HiLinkMdContextInner *ctxInner = (HiLinkMdContextInner *)ctx; + if (!IsMdLenInvalid(ctxInner->type, outLen)) { + HILINK_SAL_WARN("invalid outlen\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + int ret = HILINK_SAL_NOT_SUPPORT; + if (ctxInner->type == HILINK_MD_SHA256) { +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha256_finish(ctxInner->mbedtlsMdContext, outData); +#else + ret = mbedtls_sha256_finish_ret(ctxInner->mbedtlsMdContext, outData); +#endif +#ifdef SHA_384_512_SUPPROT + } else if ((ctxInner->type == HILINK_MD_SHA384) || (ctxInner->type == HILINK_MD_SHA512)) { +#ifdef MBEDTLS_VERSION_3 + ret = mbedtls_sha512_finish(ctxInner->mbedtlsMdContext, outData); +#else + ret = mbedtls_sha512_finish_ret(ctxInner->mbedtlsMdContext, outData); +#endif +#endif + } + return ret; +} + +void HILINK_SAL_MdFree(HiLinkMdContext ctx) +{ + if (ctx == NULL) { + return; + } + HiLinkMdContextInner *ctxInner = (HiLinkMdContextInner *)ctx; + if (ctxInner->mbedtlsMdContext != NULL) { + if (ctxInner->type == HILINK_MD_SHA256) { + mbedtls_sha256_free(ctxInner->mbedtlsMdContext); +#ifdef SHA_384_512_SUPPROT + } else if ((ctxInner->type == HILINK_MD_SHA384) || (ctxInner->type == HILINK_MD_SHA512)) { + mbedtls_sha512_free(ctxInner->mbedtlsMdContext); +#endif + } + HILINK_Free(ctxInner->mbedtlsMdContext); + } + + HILINK_Free(ctxInner); +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_mpi.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_mpi.c new file mode 100755 index 0000000..9445c7c --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_mpi.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 多精度整数(Multi-precision integer)mbedTLS实现(此文件为DEMO,需集成方适配修改) + */ +#include "hilink_sal_mpi.h" + +#include +#include "mbedtls/bignum.h" +#include "hilink_mem_adapter.h" +#include "hilink_sal_defines.h" + +HiLinkMpi HILINK_SAL_MpiInit(void) +{ + mbedtls_mpi *mpi = (mbedtls_mpi *)HILINK_Malloc(sizeof(mbedtls_mpi)); + if (mpi == NULL) { + HILINK_SAL_WARN("malloc error\r\n"); + return NULL; + } + mbedtls_mpi_init(mpi); + return mpi; +} + +mbedtls_mpi *GetMbedtlsMpi(HiLinkMpi mpi) +{ + return mpi; +} + +void HILINK_SAL_MpiFree(HiLinkMpi mpi) +{ + if (mpi == NULL) { + return; + } + mbedtls_mpi_free(mpi); + HILINK_Free(mpi); +} + +int HILINK_SAL_MpiExpMod(HiLinkMpi x, HiLinkMpi a, HiLinkMpi e, HiLinkMpi n) +{ + if ((x == NULL) || (a == NULL) || (e == NULL) || (n == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + int ret = mbedtls_mpi_exp_mod(x, a, e, n, NULL); + if (ret != 0) { + HILINK_SAL_WARN("exp mod error %d\r\n", ret); + } + return ret; +} + +int HILINK_SAL_MpiCmpInt(HiLinkMpi x, int64_t z) +{ + if (x == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + return mbedtls_mpi_cmp_int(x, z); +} + +int HILINK_SAL_MpiSubInt(HiLinkMpi x, HiLinkMpi a, int64_t b) +{ + if ((x == NULL) || (a == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + int ret = mbedtls_mpi_sub_int(x, a, b); + if (ret != 0) { + HILINK_SAL_WARN("sub int error %d\r\n", ret); + } + return ret; +} + +int HILINK_SAL_MpiCmpMpi(HiLinkMpi x, HiLinkMpi y) +{ + if ((x == NULL) || (y == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + return mbedtls_mpi_cmp_mpi(x, y); +} + +int HILINK_SAL_MpiReadString(HiLinkMpi mpi, unsigned char radix, const char *s) +{ + if ((mpi == NULL) || (s == NULL) || (radix < 2) || (radix > 16)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + int ret = mbedtls_mpi_read_string(mpi, radix, s); + if (ret != 0) { + HILINK_SAL_WARN("read string error %d\r\n", ret); + } + return ret; +} + +int HILINK_SAL_MpiWriteString(HiLinkMpi mpi, unsigned int radix, char *buf, unsigned int *bufLen) +{ + if ((mpi == NULL) || (buf == NULL) || (radix < 2) || (radix > 16) || (bufLen == NULL) || + (*bufLen == 0)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + size_t oLen = 0; + int ret = mbedtls_mpi_write_string(mpi, radix, buf, *bufLen, &oLen); + if (ret != 0) { + HILINK_SAL_WARN("write string error %d\r\n", ret); + } else { + *bufLen = oLen; + } + return ret; +} + +int HILINK_SAL_MpiReadBinary(HiLinkMpi mpi, const unsigned char *buf, unsigned int bufLen) +{ + if ((mpi == NULL) || (buf == NULL) || (bufLen == 0)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + int ret = mbedtls_mpi_read_binary(mpi, buf, bufLen); + if (ret != 0) { + HILINK_SAL_WARN("read binary error %d\r\n", ret); + } + return ret; +} + +int HILINK_SAL_MpiWriteBinary(HiLinkMpi mpi, unsigned char *buf, unsigned int bufLen) +{ + if ((mpi == NULL) || (buf == NULL) || (bufLen == 0)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + int ret = mbedtls_mpi_write_binary(mpi, buf, bufLen); + if (ret != 0) { + HILINK_SAL_WARN("write binary error %d\r\n", ret); + } + return ret; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_rsa.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_rsa.c new file mode 100755 index 0000000..cd879b0 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sal_rsa.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: RSA加解密适配层接口mbedTLS实现(此文件为DEMO,需集成方适配修改) + */ + +#include "hilink_sal_rsa.h" + +#include +#include +#include "mbedtls/rsa.h" +#include "hilink_mem_adapter.h" +#include "securec.h" +#include "hilink_mbedtls_utils.h" + +#define MBEDTLS_RADIX_NUM_BASE 16 + +typedef struct HiLinkRsaContextInner { + HiLinkRsaPkcs1Mode padding; + HiLinkMdType md; + mbedtls_rsa_context ctx; + int (*rng)(unsigned char *out, unsigned int len); +} HiLinkRsaContextInner; + +HiLinkRsaContext HILINK_SAL_RsaInit(HiLinkRsaPkcs1Mode padding, HiLinkMdType md) +{ + HiLinkRsaContextInner *ctx = HILINK_Malloc(sizeof(HiLinkRsaContextInner)); + if (ctx == NULL) { + HILINK_SAL_WARN("malloc error\r\n"); + return NULL; + } + (void)memset_s(ctx, sizeof(HiLinkRsaContextInner), 0, sizeof(HiLinkRsaContextInner)); + ctx->padding = padding; + ctx->md = md; +#ifdef MBEDTLS_VERSION_3 + mbedtls_rsa_init(&ctx->ctx); + mbedtls_rsa_set_padding(&ctx->ctx, padding, GetMbedtlsMdType(md)); +#else + mbedtls_rsa_init(&ctx->ctx, padding, GetMbedtlsMdType(md)); +#endif + return ctx; +} + +void HILINK_SAL_RsaFree(HiLinkRsaContext ctx) +{ + if (ctx == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return; + } + mbedtls_rsa_free(&((HiLinkRsaContextInner *)ctx)->ctx); + HILINK_Free(ctx); +} + +int HILINK_SAL_RsaParamImport(HiLinkRsaContext ctx, const HiLinkRsaParam *param) +{ + if ((ctx == NULL) || (param == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + int ret = mbedtls_rsa_import(&((HiLinkRsaContextInner *)ctx)->ctx, + GetMbedtlsMpi(param->n), GetMbedtlsMpi(param->p), + GetMbedtlsMpi(param->q), GetMbedtlsMpi(param->d), GetMbedtlsMpi(param->e)); + if (ret != 0) { + HILINK_SAL_WARN("import error %d\r\n", ret); + } + return ret; +} + +int HILINK_RsaPkcs1Verify(HiLinkRsaContext ctx, HiLinkMdType md, const unsigned char *hash, + unsigned int hashLen, const unsigned char *sig, unsigned int sigLen) +{ +#ifdef MBEDTLS_VERSION_3 + if ((ctx == NULL) || (hash == NULL) || (hashLen == 0) || + (sig == NULL) || (sigLen != ((HiLinkRsaContextInner *)ctx)->ctx.MBEDTLS_PRIVATE(len)) || + ((md != HILINK_MD_NONE) && !IsMdLenInvalid(md, hashLen))) { +#else + if ((ctx == NULL) || (hash == NULL) || (hashLen == 0) || + (sig == NULL) || (sigLen != ((HiLinkRsaContextInner *)ctx)->ctx.len) || + ((md != HILINK_MD_NONE) && !IsMdLenInvalid(md, hashLen))) { +#endif + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + mbedtls_rsa_context *rsa = &((HiLinkRsaContextInner *)ctx)->ctx; + int ret = mbedtls_rsa_check_pubkey(rsa); + if (ret != 0) { + HILINK_SAL_WARN("check error\r\n"); + return ret; + } + + ret = mbedtls_rsa_pkcs1_verify(rsa, +#ifndef MBEDTLS_VERSION_3 + NULL, NULL, MBEDTLS_RSA_PUBLIC, +#endif + GetMbedtlsMdType(md), hashLen, hash, sig); + if (ret != 0) { + HILINK_SAL_WARN("verify error\r\n"); + return ret; + } + + return HILINK_SAL_OK; +} + +static int RngForMbedtls(void *param, unsigned char *out, size_t len) +{ + HiLinkRsaContextInner *ctx = (HiLinkRsaContextInner *)param; + if ((ctx == NULL) || (ctx->rng == NULL) || (out == NULL) || (len == 0)) { + return -1; + } + return ctx->rng(out, len); +} + +int HILINK_RsaPkcs1Decrypt(const HiLinkRsaCryptParam *param, unsigned char *buf, unsigned int *len) +{ +#ifdef MBEDTLS_VERSION_3 + if ((param == NULL) || (param->ctx == NULL) || (param->input == NULL) || + (buf == NULL) || (param->inLen != ((HiLinkRsaContextInner *)(param->ctx))->ctx.MBEDTLS_PRIVATE(len)) || + (len == NULL) || (*len == 0)) { +#else + if ((param == NULL) || (param->ctx == NULL) || (param->input == NULL) || + (buf == NULL) || (param->inLen != ((HiLinkRsaContextInner *)(param->ctx))->ctx.len) || + (len == NULL) || (*len == 0)) { +#endif + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + HiLinkRsaContextInner *ctx = (HiLinkRsaContextInner *)param->ctx; + int ret; + if (param->mode == HILINK_RSA_OP_PRIVATE) { + if (param->rng == NULL) { + HILINK_SAL_WARN("invalid rng\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + ctx->rng = param->rng; + ret = mbedtls_rsa_check_privkey(&ctx->ctx); + } else { +#ifdef MBEDTLS_VERSION_3 + HILINK_SAL_WARN("mode not support public key\r\n"); + ret = HILINK_SAL_NOT_SUPPORT; +#else + ret = mbedtls_rsa_check_pubkey(&ctx->ctx); +#endif + } + if (ret != 0) { + HILINK_SAL_WARN("check error\r\n"); + return ret; + } + + size_t oLen = 0; + ret = mbedtls_rsa_pkcs1_decrypt(&ctx->ctx, RngForMbedtls, ctx, +#ifndef MBEDTLS_VERSION_3 + param->mode, +#endif + &oLen, param->input, buf, *len); + if (ret != 0) { + HILINK_SAL_WARN("decrypt error\r\n"); + return ret; + } + *len = oLen; + return HILINK_SAL_OK; +} + +int HILINK_RsaPkcs1Encrypt(const HiLinkRsaCryptParam *param, unsigned char *buf, unsigned int len) +{ +#ifdef MBEDTLS_VERSION_3 + if ((param == NULL) || (param->ctx == NULL) || (param->input == NULL) || + (buf == NULL) || (len < ((HiLinkRsaContextInner *)(param->ctx))->ctx.MBEDTLS_PRIVATE(len))) { +#else + if ((param == NULL) || (param->ctx == NULL) || (param->input == NULL) || + (buf == NULL) || (len < ((HiLinkRsaContextInner *)(param->ctx))->ctx.len)) { +#endif + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + HiLinkRsaContextInner *ctx = (HiLinkRsaContextInner *)param->ctx; + int ret; + if (param->mode == HILINK_RSA_OP_PRIVATE) { +#ifdef MBEDTLS_VERSION_3 + HILINK_SAL_WARN("mode not support private key\r\n"); + ret = HILINK_SAL_NOT_SUPPORT; +#else + ret = mbedtls_rsa_check_privkey(&ctx->ctx); +#endif + } else { + ret = mbedtls_rsa_check_pubkey(&ctx->ctx); + } + if (ret != 0) { + HILINK_SAL_WARN("check error\r\n"); + return ret; + } + bool isNeedRng = false; + if ((param->mode == HILINK_RSA_OP_PUBLIC) || (ctx->padding == HILINK_RSA_PKCS1_V21)) { + if (param->rng == NULL) { + HILINK_SAL_WARN("invalid rng\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + ctx->rng = param->rng; + isNeedRng = true; + } + + ret = mbedtls_rsa_pkcs1_encrypt(&ctx->ctx, isNeedRng ? RngForMbedtls : NULL, isNeedRng ? ctx : NULL, +#ifndef MBEDTLS_VERSION_3 + param->mode, +#endif + param->inLen, param->input, buf); + if (ret != 0) { + HILINK_SAL_WARN("encrypt error\r\n"); + return ret; + } + return HILINK_SAL_OK; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_socket_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_socket_adapter.c new file mode 100755 index 0000000..26d8889 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_socket_adapter.c @@ -0,0 +1,699 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 系统适配层网络Socket接口实现(此文件为DEMO,需集成方适配修改) + */ + +#include "hilink_socket_adapter.h" +#include +#include +#include +#include +#include "securec.h" +#ifdef HILINK_SDK_BUILD_IN +#ifndef _LINUX_OS_ +#include "lwip.h" +#else +#include +#include +#include +#include +#include +#include +#include +#endif +#else +/* 在此处引入平台socket接口头文件 */ +#include "lwip/pbuf.h" +#include "lwip/dns.h" +#include "lwip/inet.h" +#include "lwip/sockets.h" +#endif /* HILINK_SDK_BUILD_IN */ +#include "hilink_network_adapter.h" +#include "hilink_str_adapter.h" +#include "hilink_sal_defines.h" +#include "hilink_mem_adapter.h" + +#define MS_PER_SEC 1000 +#define US_PER_MS 1000 +#define MAX_IP_LEN 40 +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#define IPV6_ADDR_LEN 28 +#define MAX_ADDR_LEN IPV6_ADDR_LEN +#define MAX_DNS_RES_NUM 10 + +typedef struct AddrInfoInner { + HiLinkAddrInfo hiAddr; + struct addrinfo *addr; +} AddrInfoInner; + +typedef struct { + HiLinkSocketOption option; + int (*setOptionFunc)(int fd, const void *value, unsigned int len); +} OptionItem; + +typedef struct { + int hiType; + int sockType; +} HiLinkSocketTypePair; + +static const HiLinkSocketTypePair AF_MAP[] = { + {HILINK_SOCKET_DOMAIN_AF_INET, AF_INET}, + {HILINK_SOCKET_DOMAIN_AF_INET6, AF_INET6}, + {HILINK_SOCKET_DOMAIN_UNSPEC, AF_UNSPEC}, +}; + +static const HiLinkSocketTypePair AP_MAP[] = { + {HILINK_SOCKET_PROTO_IP, IPPROTO_IP}, + {HILINK_SOCKET_PROTO_TCP, IPPROTO_TCP}, + {HILINK_SOCKET_PROTO_UDP, IPPROTO_UDP}, +}; + +static const HiLinkSocketTypePair AS_MAP[] = { + {HILINK_SOCKET_TYPE_STREAM, SOCK_STREAM}, + {HILINK_SOCKET_TYPE_DGRAM, SOCK_DGRAM}, + {HILINK_SOCKET_TYPE_RAW, SOCK_RAW}, +}; + +static int HiLinkAiFamily2Socket(int af) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(AF_MAP); ++i) { + if (AF_MAP[i].hiType == af) { + return AF_MAP[i].sockType; + } + } + return af; +} + +static int SocketAiFamily2HiLink(int af) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(AF_MAP); ++i) { + if (AF_MAP[i].sockType == af) { + return AF_MAP[i].hiType; + } + } + return af; +} + +static int HiLinkAiProtocal2Socket(int ap) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(AP_MAP); ++i) { + if (AP_MAP[i].hiType == ap) { + return AP_MAP[i].sockType; + } + } + return ap; +} + +static int SocketAiProtocal2HiLink(int ap) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(AP_MAP); ++i) { + if (AP_MAP[i].sockType == ap) { + return AP_MAP[i].hiType; + } + } + return ap; +} + +static int HiLinkAiSocktype2Socket(int as) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(AS_MAP); ++i) { + if (AS_MAP[i].hiType == as) { + return AS_MAP[i].sockType; + } + } + return as; +} + +static int SocketAiSocktype2HiLink(int as) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(AS_MAP); ++i) { + if (AS_MAP[i].sockType == as) { + return AS_MAP[i].hiType; + } + } + return as; +} + +static void GetHiLinkAddrInfo(HiLinkAddrInfo *out, struct addrinfo *in, int level, int maxLevel) +{ + if ((level > maxLevel) || (in == NULL) || (out == NULL)) { + return; + } + + out->aiFlags = in->ai_flags; + out->aiFamily = SocketAiFamily2HiLink(in->ai_family); + out->aiProtocol = SocketAiProtocal2HiLink(in->ai_protocol); + out->aiSocktype = SocketAiSocktype2HiLink(in->ai_socktype); + out->aiAddrlen = in->ai_addrlen; + out->aiAddr = (HiLinkSockaddr *)in->ai_addr; + out->aiCanonname = in->ai_canonname; + + if (in->ai_next != NULL) { + out->aiNext = (HiLinkAddrInfo *)HILINK_Malloc(sizeof(HiLinkAddrInfo)); + if (out->aiNext == NULL) { + HILINK_SAL_WARN("malloc error\r\n"); + } else { + (void)memset_s(out->aiNext, sizeof(HiLinkAddrInfo), 0, sizeof(HiLinkAddrInfo)); + /* 递归函数,+1表示递归深度+1 */ + GetHiLinkAddrInfo(out->aiNext, in->ai_next, level + 1, maxLevel); + } + } + + return; +} + +static void FreeHiLinkAddrInfo(HiLinkAddrInfo *addr) +{ + if (addr->aiNext != NULL) { + FreeHiLinkAddrInfo(addr->aiNext); + addr->aiNext = NULL; + } + HILINK_Free(addr); +} + +static void FreeAddrInfoInner(AddrInfoInner *addrInner) +{ + if (addrInner->addr != NULL) { + freeaddrinfo(addrInner->addr); + addrInner->addr = NULL; + } + + FreeHiLinkAddrInfo((HiLinkAddrInfo *)addrInner); +} + +static HiLinkAddrInfo *GetAddrInfoInner(struct addrinfo *addr) +{ + if (addr == NULL) { + return NULL; + } + AddrInfoInner *addrInner = (AddrInfoInner *)HILINK_Malloc(sizeof(AddrInfoInner)); + if (addrInner == NULL) { + HILINK_SAL_WARN("malloc error\r\n"); + freeaddrinfo(addr); + return NULL; + } + (void)memset_s(addrInner, sizeof(AddrInfoInner), 0, sizeof(AddrInfoInner)); + /* 递归函数,1代表第一层 */ + GetHiLinkAddrInfo(&addrInner->hiAddr, addr, 1, MAX_DNS_RES_NUM); + addrInner->addr = addr; + return (HiLinkAddrInfo *)addrInner; +} + +int HILINK_GetAddrInfo(const char *nodename, const char *servname, + const HiLinkAddrInfo *hints, HiLinkAddrInfo **result) +{ + if ((nodename == NULL) || (result == NULL)) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + + struct addrinfo *resInfo = NULL; + struct addrinfo *hintsInfoP = NULL; + struct addrinfo hintsInfo = {0}; + + HILINK_SAL_DEBUG_LIMITED("get addrinfo %s\r\n", nodename); + if (hints != NULL) { + if (memcpy_s(&hintsInfo, sizeof(struct addrinfo), hints, sizeof(HiLinkAddrInfo)) != EOK) { + HILINK_SAL_ERROR("memcpy error"); + return HILINK_SAL_MEMCPY_ERR; + } + hintsInfo.ai_family = HiLinkAiFamily2Socket(hintsInfo.ai_family); + hintsInfo.ai_protocol = HiLinkAiProtocal2Socket(hintsInfo.ai_protocol); + hintsInfo.ai_socktype = HiLinkAiSocktype2Socket(hintsInfo.ai_socktype); + hintsInfoP = &hintsInfo; + } + + int ret = getaddrinfo(nodename, servname, hintsInfoP, &resInfo); + if ((ret != 0) || (resInfo == NULL)) { + HILINK_SAL_ERROR_LIMITED("getaddrinfo failed, ret %d\r\n", ret); + return HILINK_SAL_DNS_ERR; + } + + *result = GetAddrInfoInner(resInfo); + return HILINK_SAL_OK; +} + +void HILINK_FreeAddrInfo(HiLinkAddrInfo *addrInfo) +{ + if (addrInfo == NULL) { + HILINK_SAL_WARN("invalid param"); + return; + } + FreeAddrInfoInner((AddrInfoInner *)addrInfo); + return; +} + +int HILINK_Socket(HiLinkSocketDomain domain, HiLinkSocketType type, HiLinkSocketProto proto) +{ + int af = HiLinkAiFamily2Socket(domain); + int st = HiLinkAiSocktype2Socket(type); + int ap = HiLinkAiProtocal2Socket(proto); + + return socket(af, st, ap); +} + +void HILINK_Close(int fd) +{ + (void)lwip_close(fd); +} + +static int SetFcntl(int fd, bool isBlock) +{ + int flags = lwip_fcntl(fd, F_GETFL, 0); + if (flags < 0) { + HILINK_SAL_WARN("fcntl get failed, ret %d\r\n", flags); + return HILINK_SAL_FCNTL_ERR; + } + if (isBlock) { + flags &= (~O_NONBLOCK); + } else { + flags |= O_NONBLOCK; + } + if (lwip_fcntl(fd, F_SETFL, flags) < 0) { + HILINK_SAL_WARN("fcntl set failed\r\n"); + return HILINK_SAL_FCNTL_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketOptionNonblock(int fd, const void *value, unsigned int len) +{ + (void)value; + (void)len; + + return SetFcntl(fd, false); +} + +static int SetSocketOptionBlock(int fd, const void *value, unsigned int len) +{ + (void)value; + (void)len; + + return SetFcntl(fd, true); +} + +static int SetSocketTimeout(int fd, unsigned int timeout, bool isRead) +{ + struct timeval tv; + int flag = isRead ? SO_RCVTIMEO : SO_SNDTIMEO; + + tv.tv_sec = timeout / MS_PER_SEC; + tv.tv_usec = timeout % MS_PER_SEC * US_PER_MS; + if (setsockopt(fd, SOL_SOCKET, flag, &tv, sizeof(struct timeval)) != 0) { + HILINK_SAL_WARN("set [%d][%u] failed\r\n", flag, timeout); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketOptionReadTimeouot(int fd, const void *value, unsigned int len) +{ + if (len < sizeof(unsigned int)) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + unsigned int timeout = *(const unsigned int *)value; + + return SetSocketTimeout(fd, timeout, true); +} + +static int SetSocketOptionSendTimeouot(int fd, const void *value, unsigned int len) +{ + if (len < sizeof(unsigned int)) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + unsigned int timeout = *(const unsigned int *)value; + + return SetSocketTimeout(fd, timeout, false); +} + +static int SetSocketOptionEnableReuseAddr(int fd, const void *value, unsigned int len) +{ + (void)value; + (void)len; + int opt = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) != 0) { + HILINK_SAL_WARN("set reuse addr failed\r\n"); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketOptionDisableReuseAddr(int fd, const void *value, unsigned int len) +{ + (void)value; + (void)len; + int opt = 0; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) != 0) { + HILINK_SAL_WARN("close reuse addr failed\r\n"); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketMultiGroup(int fd, const char *multicastIp, bool isAdd) +{ + struct ip_mreq group; + (void)memset_s(&group, sizeof(struct ip_mreq), 0, sizeof(struct ip_mreq)); + group.imr_multiaddr.s_addr = HILINK_InetAddr(multicastIp); + char localIp[MAX_IP_LEN] = {0}; + if ((HILINK_GetLocalIp(localIp, sizeof(localIp)) != 0) || + (HILINK_Strlen(localIp) == 0) || (HILINK_Strcmp(localIp, "0.0.0.0") == 0)) { + group.imr_interface.s_addr = HILINK_Htonl(INADDR_ANY); + HILINK_SAL_NOTICE("use any addr\r\n"); + } else { + group.imr_interface.s_addr = HILINK_InetAddr(localIp); + } + + int flag = isAdd ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; + if (setsockopt(fd, IPPROTO_IP, flag, (void *)&group, sizeof(group)) < 0) { + HILINK_SAL_WARN("set opt %d failed\r\n", flag); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketOptionAddMultiGroup(int fd, const void *value, unsigned int len) +{ + if (HILINK_Strlen((const char *)value) > len) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + return SetSocketMultiGroup(fd, (const char *)value, true); +} + +static int SetSocketOptionDropMultiGroup(int fd, const void *value, unsigned int len) +{ + if (HILINK_Strlen((const char *)value) > len) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + return SetSocketMultiGroup(fd, (const char *)value, false); +} + +static int SetSocketOptionEnableBroadcast(int fd, const void *value, unsigned int len) +{ + (void)value; + (void)len; + int opt = 1; + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt)) != 0) { + HILINK_SAL_WARN("set broadcast failed\r\n"); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketOptionDisableBroadcast(int fd, const void *value, unsigned int len) +{ + (void)value; + (void)len; + int opt = 0; + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt)) != 0) { + HILINK_SAL_WARN("close broadcast failed\r\n"); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketOptionEnableMultiLoop(int fd, const void *value, unsigned int len) +{ + (void)value; + (void)len; + int opt = 1; + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&opt, sizeof(opt)) != 0) { + HILINK_SAL_WARN("set loop failed\r\n"); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketOptionDisableMultiLoop(int fd, const void *value, unsigned int len) +{ + (void)value; + (void)len; + int opt = 0; + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&opt, sizeof(opt)) != 0) { + HILINK_SAL_WARN("close loop failed\r\n"); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketOptionSendBuffer(int fd, const void *value, unsigned int len) +{ + if (len < sizeof(unsigned int)) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + unsigned int bufferLen = *(unsigned int *)value; + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&bufferLen, sizeof(bufferLen)) < 0) { + HILINK_SAL_WARN("set sendbuf %u failed\r\n", bufferLen); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +static int SetSocketOptionReadBuffer(int fd, const void *value, unsigned int len) +{ + if (len < sizeof(unsigned int)) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + unsigned int bufferLen = *(unsigned int *)value; + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void *)&bufferLen, sizeof(bufferLen)) < 0) { + HILINK_SAL_WARN("set recvbuf %u failed\r\n", bufferLen); + return HILINK_SAL_SET_SOCK_OPT_ERR; + } + return HILINK_SAL_OK; +} + +int HILINK_SetSocketOpt(int fd, HiLinkSocketOption option, const void *value, unsigned int len) +{ + static const OptionItem optionList[] = { + {HILINK_SOCKET_OPTION_SETFL_BLOCK, SetSocketOptionBlock}, + {HILINK_SOCKET_OPTION_SETFL_NONBLOCK, SetSocketOptionNonblock}, + {HILINK_SOCKET_OPTION_READ_TIMEOUT, SetSocketOptionReadTimeouot}, + {HILINK_SOCKET_OPTION_SEND_TIMEOUT, SetSocketOptionSendTimeouot}, + {HILINK_SOCKET_OPTION_ENABLE_REUSEADDR, SetSocketOptionEnableReuseAddr}, + {HILINK_SOCKET_OPTION_DISABLE_REUSEADDR, SetSocketOptionDisableReuseAddr}, + {HILINK_SOCKET_OPTION_ADD_MULTI_GROUP, SetSocketOptionAddMultiGroup}, + {HILINK_SOCKET_OPTION_DROP_MULTI_GROUP, SetSocketOptionDropMultiGroup}, + {HILINK_SOCKET_OPTION_ENABLE_BROADCAST, SetSocketOptionEnableBroadcast}, + {HILINK_SOCKET_OPTION_DISABLE_BROADCAST, SetSocketOptionDisableBroadcast}, + {HILINK_SOCKET_OPTION_ENABLE_MULTI_LOOP, SetSocketOptionEnableMultiLoop}, + {HILINK_SOCKET_OPTION_DISABLE_MULTI_LOOP, SetSocketOptionDisableMultiLoop}, + {HILINK_SOCKET_OPTION_SEND_BUFFER, SetSocketOptionSendBuffer}, + {HILINK_SOCKET_OPTION_READ_BUFFER, SetSocketOptionReadBuffer}, + }; + for (unsigned int i = 0; i < (sizeof(optionList) / sizeof(OptionItem)); ++i) { + if (option == optionList[i].option) { + return optionList[i].setOptionFunc(fd, value, len); + } + } + HILINK_SAL_WARN("unsupport option %d\r\n", option); + return HILINK_SAL_NOT_SUPPORT; +} + +int HILINK_Bind(int fd, const HiLinkSockaddr *addr, unsigned int addrLen) +{ + (void)addrLen; + if (addr == NULL) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + struct sockaddr addrIn; + addrIn.sa_family = HiLinkAiFamily2Socket(addr->saFamily); + if (memcpy_s(addrIn.sa_data, sizeof(addrIn.sa_data), addr->saData, sizeof(addr->saData)) != EOK) { + HILINK_SAL_WARN("memcpy error"); + return HILINK_SAL_MEMCPY_ERR; + } + + return bind(fd, &addrIn, sizeof(struct sockaddr)); +} + + +int HILINK_Connect(int fd, const HiLinkSockaddr *addr, unsigned int addrLen) +{ + (void)addrLen; + if (addr == NULL) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + struct sockaddr addrIn; + addrIn.sa_family = HiLinkAiFamily2Socket(addr->saFamily); + if (memcpy_s(addrIn.sa_data, sizeof(addrIn.sa_data), addr->saData, sizeof(addr->saData)) != EOK) { + HILINK_SAL_WARN("memcpy error"); + return HILINK_SAL_MEMCPY_ERR; + } + return connect(fd, &addrIn, sizeof(struct sockaddr)); +} + +int HILINK_Recv(int fd, unsigned char *buf, unsigned int len) +{ + return recv(fd, buf, len, MSG_DONTWAIT); +} + +int HILINK_Send(int fd, const unsigned char *buf, unsigned int len) +{ + return send(fd, buf, len, MSG_DONTWAIT); +} + +int HILINK_RecvFrom(int fd, unsigned char *buf, unsigned int len, + HiLinkSockaddr *from, unsigned int *fromLen) +{ + if ((from == NULL) || (fromLen == NULL)) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + struct sockaddr addr; + (void)memset_s(&addr, sizeof(struct sockaddr), 0, sizeof(struct sockaddr)); + int ret = recvfrom(fd, buf, len, 0, &addr, (socklen_t *)fromLen); + from->saFamily = addr.sa_family; + if (memcpy_s(from->saData, sizeof(from->saData), addr.sa_data, sizeof(addr.sa_data)) != EOK) { + HILINK_SAL_WARN("memcpy error"); + return HILINK_SAL_MEMCPY_ERR; + } + return ret; +} + +int HILINK_SendTo(int fd, const unsigned char *buf, unsigned int len, + const HiLinkSockaddr *to, unsigned int toLen) +{ + if ((to == NULL) || (toLen == 0)) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + struct sockaddr addr; + addr.sa_family = HiLinkAiFamily2Socket(to->saFamily); + if (memcpy_s(addr.sa_data, sizeof(addr.sa_data), to->saData, sizeof(to->saData)) != EOK) { + HILINK_SAL_WARN("memcpy error"); + return HILINK_SAL_MEMCPY_ERR; + } + return sendto(fd, buf, len, 0, &addr, toLen); +} + +static void GetFdSet(HiLinkFdSet *set, fd_set *fdSet, int *maxfd) +{ + if ((set != NULL) && (set->fdSet != NULL)) { + (void)memset_s(fdSet, sizeof(fd_set), 0, sizeof(fd_set)); + for (unsigned int i = 0; i < set->num; ++i) { + if (set->fdSet[i] >= 0) { + FD_SET(set->fdSet[i], fdSet); + *maxfd = MAX(*maxfd, set->fdSet[i]); + } + } + } +} + +static void FdIsSet(HiLinkFdSet *set, fd_set *fdSet) +{ + if ((set == NULL) || (fdSet == NULL)) { + return; + } + for (unsigned int i = 0; i < set->num; ++i) { + if (FD_ISSET(set->fdSet[i], fdSet) == 0) { + set->fdSet[i] = -1; + } + } + return; +} + +int HILINK_Select(HiLinkFdSet *readSet, HiLinkFdSet *writeSet, HiLinkFdSet *exceptSet, unsigned int ms) +{ + int maxfd = -1; + fd_set read, write, except; + GetFdSet(readSet, &read, &maxfd); + GetFdSet(writeSet, &write, &maxfd); + GetFdSet(exceptSet, &except, &maxfd); + + struct timeval timeout; + timeout.tv_sec = ms / MS_PER_SEC; + timeout.tv_usec = ms % MS_PER_SEC * US_PER_MS; + int ret = lwip_select(maxfd + 1, (readSet == NULL) ? NULL : &read, + (writeSet == NULL) ? NULL : &write, + (exceptSet == NULL) ? NULL : &except, &timeout); + if (ret <= 0) { + return ret; + } + FdIsSet(readSet, &read); + FdIsSet(writeSet, &write); + FdIsSet(exceptSet, &except); + return ret; +} + +int HILINK_GetSocketErrno(int fd) +{ +#if defined(_LINUX_OS_) && defined(errno) + if (fd < 0) { + return errno; + } +#endif + int socketErr; + unsigned int len = sizeof(socklen_t); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &socketErr, (socklen_t *)&len) != 0) { + HILINK_SAL_WARN("get socket errno error\r\n"); + return HILINK_SAL_GET_SOCK_OPT_ERR; + } + + switch (socketErr) { + case EINTR: + return HILINK_SOCKET_ERRNO_EINTR; + case EAGAIN: + return HILINK_SOCKET_ERRNO_EAGAIN; + case EINPROGRESS: + return HILINK_SOCKET_ERRNO_EINPROGRESS; + default: + break; + } + + return socketErr; +} + +int get_os_errno(void) +{ + int errCode = errno; + return errCode; +} + +unsigned int HILINK_Htonl(unsigned int hl) +{ + return htonl(hl); +} + +unsigned int HILINK_Ntohl(unsigned int nl) +{ + return ntohl(nl); +} + +unsigned short HILINK_Htons(unsigned short hs) +{ + return htons(hs); +} + +unsigned short HILINK_Ntohs(unsigned short ns) +{ + return ntohs(ns); +} + +unsigned int HILINK_InetAton(const char *ip, unsigned int *addr) +{ + return inet_aton(ip, (struct in_addr *)addr); +} + +unsigned int HILINK_InetAddr(const char *ip) +{ + return inet_addr(ip); +} + +const char *HILINK_InetNtoa(unsigned int addr, char *buf, unsigned int buflen) +{ + struct in_addr tempAddr; + tempAddr.s_addr = addr; +#ifndef _LINUX_OS_ + return inet_ntoa_r(tempAddr, buf, buflen); +#else + return inet_ntop(AF_INET, &tempAddr, buf, buflen); +#endif +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_softap_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_softap_adapter.c new file mode 100755 index 0000000..8721473 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_softap_adapter.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: SoftAP适配实现 (此文件为DEMO,需集成方适配修改) + */ +#include "hilink_softap_adapter.h" + +#include +#include "securec.h" +#include "wifi_device.h" +#include "wifi_hotspot.h" +#include "hilink_sal_defines.h" +#include "lwip/netifapi.h" +#include "lwip/nettool/ifconfig.h" +#include "osal_task.h" + +#define IP_LEN 40 + +typedef struct { + const char *ifname; + const char *ip_str; + const char *netmask; + const char *netmask_value; + const char *gateway; + const char *gateway_value; +} ifcfg_args_t; + +static void CheckWifiStateBeforeStartSoftap(void) +{ + /* 套餐2存在hilink重入,重入后起softap需要保证sta与ap已关闭 */ + if (wifi_is_sta_enabled() == 1) { + HILINK_SAL_NOTICE("sta active, try stop!\r\n"); + if (wifi_sta_disable() != ERRCODE_SUCC) { + HILINK_SAL_WARN("stop sta fail\r\n"); + } + } + + if (wifi_is_softap_enabled() == 1) { + HILINK_SAL_NOTICE("ap active, try stop!\r\n"); + if (wifi_softap_disable() != ERRCODE_SUCC) { + HILINK_SAL_WARN("stop ap fail\r\n"); + } + } +} + +static int softap_start_dhcps(void) +{ + int ret; + struct netif *netif_p = netifapi_netif_find("ap0"); + if (netif_p == NULL) { + HILINK_SAL_WARN("netif_p is null\r\n"); + return HILINK_SAL_NOK; + } + if (ip_addr_isany_val(netif_p->ip_addr)) { + HILINK_SAL_WARN("Please set ip address for dhcp server\r\n"); + return HILINK_SAL_NOK; + } + + ret = netifapi_dhcps_start(netif_p, NULL, 0); + if (ret == 0) { + HILINK_SAL_WARN("softap dhcps set OK\r\n"); + return HILINK_SAL_OK; + } + + return HILINK_SAL_NOK; +} + +static char *GetGateWayIp(unsigned int i1, unsigned int i2, unsigned int i3, unsigned int i4) +{ + static char ip[IP_LEN] = {0}; + if (sprintf_s(ip, sizeof(ip), "%u.%u.%u.%u", i1, i2, i3, i4) <= 0) { + return NULL; + } + return ip; +} + +static int softap_config_static_ip(void) +{ + int ret = 0; + ifcfg_args_t ifconfig_param; + (void)memset_s(&ifconfig_param, sizeof(ifconfig_param), 0, sizeof(ifconfig_param)); + + ifconfig_param.ifname = "ap0"; + ifconfig_param.ip_str = GetGateWayIp(192, 168, 3, 1); + ifconfig_param.netmask = "netmask"; + ifconfig_param.netmask_value = "255.255.255.0"; + ifconfig_param.gateway = "gateway"; + ifconfig_param.gateway_value = GetGateWayIp(192, 168, 3, 1); + + lwip_ifconfig(6, &ifconfig_param.ifname); // 6: ifconfig param number + + return HILINK_SAL_OK; +} + +int HILINK_StartSoftAp(const char *ssid, unsigned int ssidLen) +{ + if ((ssid == NULL) || (ssidLen == 0)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + CheckWifiStateBeforeStartSoftap(); + + softap_config_stru config; + (void)memset_s(&config, sizeof(softap_config_stru), 0, sizeof(softap_config_stru)); + + if (strcpy_s((char *)config.ssid, sizeof(config.ssid), ssid) != EOK) { + HILINK_SAL_WARN("strcpy error\r\n"); + (void)memset_s(&config, sizeof(softap_config_stru), 0, sizeof(softap_config_stru)); + return HILINK_SAL_STRCPY_ERR; + } + + config.security_type = WIFI_SEC_TYPE_OPEN; + config.channel_num = 6; /* 6: channel num */ + + if (wifi_softap_enable(&config) != ERRCODE_SUCC) { + HILINK_SAL_ERROR("enable hotspot fail\r\n"); + (void)memset_s(&config, sizeof(softap_config_stru), 0, sizeof(softap_config_stru)); + return HILINK_SAL_SET_SOFTAP_ERR; + } + + if (softap_config_static_ip() != HILINK_SAL_OK) { + HILINK_SAL_ERROR("set softap ip failed\r\n"); + (void)memset_s(&config, sizeof(softap_config_stru), 0, sizeof(softap_config_stru)); + return HILINK_SAL_SET_SOFTAP_ERR; + } + osal_msleep(4000); /* 4000:配置静态ip之后要睡眠4秒之后再开启dhcps */ + + if (softap_start_dhcps() != 0) { + HILINK_SAL_ERROR("set softap dhcps failed\r\n"); + (void)memset_s(&config, sizeof(softap_config_stru), 0, sizeof(softap_config_stru)); + return HILINK_SAL_SET_SOFTAP_ERR; + } + (void)memset_s(&config, sizeof(softap_config_stru), 0, sizeof(softap_config_stru)); + return HILINK_SAL_OK; +} + +int HILINK_StopSoftAp(void) +{ + if (wifi_is_softap_enabled() == 1) { + if (wifi_softap_disable() != ERRCODE_SUCC) { + HILINK_SAL_ERROR("Stop softAp disable hotspot fail.\r\n"); + return HILINK_SAL_SET_SOFTAP_ERR; + } + } + return HILINK_SAL_OK; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_stdio_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_stdio_adapter.c new file mode 100755 index 0000000..86a4158 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_stdio_adapter.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 系统适配层标准输出接口实现(此文件为DEMO,需集成方适配修改) + */ + +#include "hilink_stdio_adapter.h" +#include +#include +#include +#include +#include +#include "securec.h" +#include "hilink_sal_defines.h" + +int HILINK_Vprintf(const char *format, va_list ap) +{ +#if defined(_HSF_) && !defined(_PRE_WLAN_FEATURE_MFG_TEST) + extern int hf_off_factory_log(void); + if(hf_off_factory_log()) + return HILINK_SAL_OK; +#endif + + ConsoleVprintf(format, ap); // 此接口无返回值 + return HILINK_SAL_OK; +} + +int HILINK_Printf(const char *format, ...) +{ +#if defined(_HSF_) && !defined(_PRE_WLAN_FEATURE_MFG_TEST) + extern int hf_off_factory_log(void); + if(hf_off_factory_log()) + return HILINK_SAL_OK; +#endif + + if (format == NULL) { + return HILINK_SAL_OK; + } + va_list ap; + va_start(ap, format); + int ret = HILINK_Vprintf(format, ap); + va_end(ap); + + return ret; +} + +int HILINK_Rand(unsigned char *input, unsigned int len) +{ + (void)input; + (void)len; + return HILINK_SAL_NOK; +} + +int HILINK_Trng(unsigned char *input, unsigned int len) +{ + (void)input; + (void)len; + return HILINK_SAL_NOK; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_str_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_str_adapter.c new file mode 100755 index 0000000..95c156c --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_str_adapter.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 系统适配层字符串接口实现(此文件为DEMO,需集成方适配修改) + */ +#include "hilink_str_adapter.h" +#include +#include + +unsigned int HILINK_Strlen(const char *src) +{ + if (src == NULL) { + return 0; + } + return (unsigned int)strlen(src); +} + +char *HILINK_Strchr(const char *str, int ch) +{ + if (str == NULL) { + return NULL; + } + + return strchr(str, ch); +} + +char *HILINK_Strrchr(const char *str, int ch) +{ + if (str == NULL) { + return NULL; + } + + return strrchr(str, ch); +} + +int HILINK_Atoi(const char *str) +{ + if (str == NULL) { + return 0; + } + return atoi(str); +} + +char *HILINK_Strstr(const char *str1, const char *str2) +{ + if ((str1 == NULL) || (str2 == NULL)) { + return NULL; + } + return strstr(str1, str2); +} + +int HILINK_Strcmp(const char *str1, const char *str2) +{ + if ((str1 == NULL) && (str2 == NULL)) { + return 0; + } + if ((str1 != NULL) && (str2 == NULL)) { + return 1; + } + if ((str1 == NULL) && (str2 != NULL)) { + return -1; + } + + return strcmp(str1, str2); +} + +int HILINK_Strncmp(const char *str1, const char *str2, unsigned int len) +{ + if ((str1 == NULL) && (str2 == NULL)) { + return 0; + } + if ((str1 != NULL) && (str2 == NULL)) { + return 1; + } + if ((str1 == NULL) && (str2 != NULL)) { + return -1; + } + + return strncmp(str1, str2, len); +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sys_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sys_adapter.c new file mode 100755 index 0000000..8f6018e --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_sys_adapter.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 系统适配层接口实现(此文件为DEMO,需集成方适配修改) + */ + +#include "hilink_sys_adapter.h" +#include "hilink_network_adapter.h" + +int HILINK_Restart(void) +{ + HILINK_ReconnectWiFi(); + return 0; +} + +unsigned char HILINK_GetSystemBootReason(void) +{ + return HILINK_NORMAL_BOOT; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_thread_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_thread_adapter.c new file mode 100755 index 0000000..34beaad --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_thread_adapter.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 线程适配层接口cmsis2实现源文件(此文件为DEMO,需集成方适配修改) + */ + +#include "hilink_thread_adapter.h" +#include +#include +#include +#include "cmsis_os2.h" +#include "securec.h" +#include "hilink_sal_defines.h" +#include "hilink_thread_adapter.h" +#ifdef SUPPORT_MUTEX_DEBUG +#undef HILINK_MutexLock +#undef HILINK_MutexUnlock +#undef HILINK_MutexCreate +#undef HILINK_MutexDestroy +#endif + +#ifndef MS_PER_SECOND +#define MS_PER_SECOND 1000 +#endif + +HiLinkTaskId HILINK_CreateTask(HiLinkTaskParam *param) +{ + if ((param == NULL) || (param->func == NULL) || (param->prio > HILINK_TASK_PRIORITY_MAX) || + (param->stackSize == 0)) { + HILINK_SAL_WARN("invalid param"); + return NULL; + } + + const osPriority_t prioMap[] = { + osPriorityLow1, + osPriorityBelowNormal1, + osPriorityNormal2, + osPriorityNormal7, + osPriorityHigh + }; + + osThreadAttr_t attr; + (void)memset_s(&attr, sizeof(osThreadAttr_t), 0, sizeof(osThreadAttr_t)); + attr.name = param->name; + attr.priority = prioMap[param->prio]; + attr.stack_size = param->stackSize; + + return (HiLinkTaskId)osThreadNew((osThreadFunc_t)param->func, param->arg, &attr); +} + +int HILINK_ThreadSuspend(HiLinkTaskId handle) +{ + if (handle == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + osStatus_t status = osThreadSuspend((osThreadId_t)handle); + if (status != osOK) { + HILINK_SAL_WARN("suspend error %d\r\n", status); + return HILINK_SAL_THREAD_ERR; + } + return HILINK_SAL_OK; +} + +int HILINK_ThreadResume(HiLinkTaskId handle) +{ + if (handle == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + osStatus_t status = osThreadResume((osThreadId_t)handle); + if (status != osOK) { + HILINK_SAL_WARN("resume error %d\r\n", status); + return HILINK_SAL_THREAD_ERR; + } + return HILINK_SAL_OK; +} + +void HILINK_DeleteTask(HiLinkTaskId handle) +{ + if (handle == NULL) { + HILINK_SAL_NOTICE("invalid param\r\n"); + return; + } + + osStatus_t status = osThreadTerminate((osThreadId_t)handle); + if (status != osOK) { + HILINK_SAL_NOTICE("delete task error %d\r\n", status); + } +} + +HiLinkTaskId HILINK_GetCurrentTaskId(void) +{ + return (HiLinkTaskId)osThreadGetId(); +} + +HiLinkMutexId HILINK_MutexCreate(void) +{ + return (HiLinkMutexId)osMutexNew(NULL); +} + +static inline unsigned int MsToTick(unsigned int ms) +{ + uint64_t tick = (uint64_t)ms * osKernelGetTickFreq() / MS_PER_SECOND; + if (tick > UINT32_MAX) { + return UINT32_MAX; + } + return (unsigned int)tick; +} + +int HILINK_MutexLock(HiLinkMutexId mutex, unsigned int ms) +{ + if (mutex == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + osStatus_t status = osMutexAcquire((osMutexId_t)mutex, MsToTick(ms)); + if (status != osOK) { + if (status == osErrorTimeout) { + return HILINK_SAL_TIMEOUT; + } + HILINK_SAL_WARN("mutex lock error %d\r\n", status); + return HILINK_SAL_MUTEX_ERR; + } + + return HILINK_SAL_OK; +} + +int HILINK_MutexUnlock(HiLinkMutexId mutex) +{ + if (mutex == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + osStatus_t status = osMutexRelease((osMutexId_t)mutex); + if (status != osOK) { + HILINK_SAL_WARN("mutex unlock error %d\r\n", status); + return HILINK_SAL_MUTEX_ERR; + } + return HILINK_SAL_OK; +} + +void HILINK_MutexDestroy(HiLinkMutexId mutex) +{ + if (mutex == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return; + } + + osStatus_t status = osMutexDelete((osMutexId_t)mutex); + if (status != osOK) { + HILINK_SAL_WARN("mutex delete error %d\r\n", status); + } +} + +HiLinkSemId HILINK_SemCreate(unsigned int count) +{ + /* count为0是默认为二元信号量 */ + return (HiLinkSemId)osSemaphoreNew(count > 0 ? count : 1, count, NULL); +} + +int HILINK_SemWait(HiLinkSemId handle, unsigned int ms) +{ + if (handle == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + osStatus_t status = osSemaphoreAcquire((osSemaphoreId_t)handle, MsToTick(ms)); + if (status != osOK) { + return HILINK_SAL_SEM_ERR; + } + + return HILINK_SAL_OK; +} + +int HILINK_SemPost(HiLinkSemId handle) +{ + if (handle == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + osStatus_t status = osSemaphoreRelease((osSemaphoreId_t)handle); + if (status != osOK) { + HILINK_SAL_WARN("post sem error %d\r\n", status); + return HILINK_SAL_SEM_ERR; + } + + return HILINK_SAL_OK; +} + +void HILINK_SemDestroy(HiLinkSemId handle) +{ + if (handle == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return; + } + + osStatus_t status = osSemaphoreDelete((osSemaphoreId_t)handle); + if (status != osOK) { + HILINK_SAL_WARN("sem delete error %d\r\n", status); + } +} + +int HILINK_MilliSleep(unsigned int ms) +{ + osStatus_t status = osDelay(MsToTick(ms)); + if (status != osOK) { +// HILINK_SAL_WARN("delay %u ms error %d\r\n", ms, status);//chenxq commended out + return -1; + } + return HILINK_SAL_SLEEP_ERR; +} + +void HILINK_SchedYield(void) +{ + (void)osDelay(0); +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_time_adapter.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_time_adapter.c new file mode 100755 index 0000000..3195e29 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_time_adapter.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: 时间适配层接口cmsis2实现源文件(此文件为DEMO,需集成方适配修改) + */ + +#include "hilink_time_adapter.h" +#include "cmsis_os2.h" +#include "hilink_sal_defines.h" + +#ifndef MS_PER_SECOND +#define MS_PER_SECOND 1000 +#endif +#ifndef US_PER_MS +#define US_PER_MS 1000 +#endif + +int HILINK_GetOsTime(HiLinkTimeval *time) +{ + if (time == NULL) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + if (osKernelGetTickFreq() == 0) { + HILINK_SAL_CRIT("invalid tick freq\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + uint64_t ms = ((uint64_t)osKernelGetTickCount() * MS_PER_SECOND / osKernelGetTickFreq()); + time->sec = ms / MS_PER_SECOND; + time->usec = ms % MS_PER_SECOND * US_PER_MS; + + return HILINK_SAL_OK; +} + +int HILINK_GetUtcTime(HiLinkTimeval *time) +{ + (void)time; + return HILINK_SAL_NOT_SUPPORT; +} +uint32_t hf_get_os_time(void) +{ + HiLinkTimeval hf_time={0}; + HILINK_GetOsTime(&hf_time); + return hf_time.sec*MS_PER_SECOND+hf_time.usec/US_PER_MS; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_tls_client.c b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_tls_client.c new file mode 100755 index 0000000..25c1a46 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/adapter/hilink_tls_client.c @@ -0,0 +1,949 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: TLS 客户端常用操作,包括会话的创建、销毁等(此文件为DEMO,需集成方适配修改) + * Note: 由于此文件在采用外部mbedtls编译的时候会打包到外部,所以修改本函数代码的时候 + * 不应涉及引用hilink库编译要使用的宏以及非对外头文件函数 + */ + +#include "hilink_tls_client.h" + +#include +#include + +#include "securec.h" + +#include "hilink_sal_defines.h" +#include "hilink_str_adapter.h" +#include "hilink_mem_adapter.h" +#include "hilink_time_adapter.h" +#include "hilink_stdio_adapter.h" +#include "hilink_stdio_adapter.h" +#include "hilink_thread_adapter.h" + +#include "mbedtls/ssl.h" +#include "hilink_sal_drbg.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/x509.h" +#include "mbedtls/platform_time.h" +#include "mbedtls/net_sockets.h" +#include "mbedtls/debug.h" +#include "mbedtls/platform.h" + +/* 检查宏定义是否一致 */ +#if (HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 != \ + MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) +#error "HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" +#endif +#if (HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 != \ + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) +#error "HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" +#endif +#if (HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 != \ + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) +#error "HILINK_MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" +#endif +#if (HILINK_MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 != \ + MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256) +#error "HILINK_MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256" +#endif +#if (HILINK_MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 != \ + MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384) +#error "HILINK_MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384" +#endif + +#if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_NONE != \ + MBEDTLS_SSL_MAX_FRAG_LEN_NONE) +#error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_NONE" +#endif +#if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_512 != \ + MBEDTLS_SSL_MAX_FRAG_LEN_512) +#error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_512" +#endif +#if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_1024 != \ + MBEDTLS_SSL_MAX_FRAG_LEN_1024) +#error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_1024" +#endif +#if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_2048 != \ + MBEDTLS_SSL_MAX_FRAG_LEN_2048) +#error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_2048" +#endif +#if (HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_4096 != \ + MBEDTLS_SSL_MAX_FRAG_LEN_4096) +#error "HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_4096" +#endif + +#ifndef MS_PER_SECOND +#define MS_PER_SECOND 1000 +#endif +#ifndef US_PER_MS +#define US_PER_MS 1000 +#endif +#define MAX_PORT_STR_LEN 20 +#define MAX_CUSTOM_STR_LEN 32 +#define MAX_HOSTNAME_STR_LEN 64 + +#ifdef MBEDTLS_DEBUG_C +#undef HILINK_TLS_DEBUG /* 用于调试tls通信,默认不开 */ +#endif /* MBEDTLS_DEBUG_C */ + +#define MBEDTLS_DEBUG_LEVEL 4 +#define TLS_READ_TIMEOUT_MS 10 +#define TLS_HANDSHAKE_TIMEOUT 4000 +#define TLS_WRITE_TIMEOUT_MS 10000 + +#ifndef TCP_COAP_MAX_PDU_SIZE +#define TCP_COAP_MAX_PDU_SIZE 65536 +#endif + +#ifdef MBEDTLS_VERSION_3 +#define HILINK_MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 +#endif + +struct HiLinkTlsClient { + char *custom; + /* 算法套件白名单相关数据 */ + int *supportedCiphersuites; + /* 证书相关数据 */ + const char **certs; + unsigned int certsNum; + mbedtls_x509_time validFrom; + mbedtls_x509_time validTo; + bool isDelayVerifyCert; + /* mbedtls相关数据 */ + mbedtls_net_context serverFd; + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; + HiLinkDrbgContext drbg; + mbedtls_x509_crt caCert; + unsigned short port; + char *hostName; +}; + +static HiLinkMbedtlsGetTimeCb g_mbedtlsGetTimeCb = NULL; + +typedef struct { + HiLinkTlsOption option; + int (*setOptionFunc)(HiLinkTlsClient *ctx, const void *value, unsigned int len); +} OptionItem; + +static unsigned int GetTlsTimeoutTime(unsigned int packetLen) +{ + return ((packetLen / TCP_COAP_MAX_PDU_SIZE) + 1) * TLS_WRITE_TIMEOUT_MS; +} + +static int GetOsTime(unsigned long *ms) +{ + if (ms == NULL) { + return HILINK_SAL_NOK; + } + HiLinkTimeval cur = {0, 0}; + + if (HILINK_GetOsTime(&cur) != 0) { + return HILINK_SAL_TIME_ERR; + } + + *ms = (cur.sec * MS_PER_SECOND) + (cur.usec / US_PER_MS); + + return HILINK_SAL_OK; +} + +static unsigned long DeltaTime(unsigned long timeNew, unsigned long timeOld) +{ + unsigned long deltaTime; + + if (timeNew >= timeOld) { + deltaTime = timeNew - timeOld; + } else { + deltaTime = ((unsigned long)(-1) - timeOld) + timeNew + 1; /* 处理时间翻转 */ + } + + return deltaTime; +} + +static mbedtls_time_t MbedtlsPlatformGetTime(mbedtls_time_t *timeNow) +{ + (void)timeNow; /* 此参数可能为空 */ + + time_t rawSeconds = 0; + unsigned long long timeMs = 0; + if (g_mbedtlsGetTimeCb == NULL) { + HILINK_SAL_NOTICE("no cb\r\n"); + return (mbedtls_time_t)rawSeconds; + } + int ret = g_mbedtlsGetTimeCb(&timeMs); + if (ret == HILINK_SAL_OK) { + rawSeconds = (time_t)(timeMs / MS_PER_SECOND); + } else { + HILINK_SAL_NOTICE("get local time failed, set rawSeconds=0\r\n"); + } + + return (mbedtls_time_t)rawSeconds; +} + +static void *MbedtlsPlatformCalloc(size_t n, size_t size) +{ + if ((n == 0) || (size == 0)) { + return NULL; + } + if (n > (UINT_MAX / size)) { + return NULL; + } + + /* 上层调用保证不会出现溢出 */ + unsigned int len = (unsigned int)(n * size); + void *data = HILINK_Malloc(len); + if (data != NULL) { + (void)memset_s(data, len, 0, len); + } + + return data; +} + +static void InitMbedtls(void) +{ + static bool isInitmbedtls = false; + if (!isInitmbedtls) { + mbedtls_platform_set_calloc_free(MbedtlsPlatformCalloc, HILINK_Free); + (void)mbedtls_platform_set_time(MbedtlsPlatformGetTime); +#if defined(HILINK_TLS_DEBUG) + mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL); +#endif /* HILINK_TLS_DEBUG */ + isInitmbedtls = true; + } +} + +#if defined(HILINK_TLS_DEBUG) +static void TlsDebug(void *context, int level, const char *file, int line, const char *str) +{ + (void)level; + (void)file; + (void)line; + if (ctx == NULL) { + return; + } + HiLinkTlsClient *ctx = (HiLinkTlsClient *)(context); + HILINK_SAL_INFO("custom=%s,mbeddebug: %s", ctx->custom, str); +} +#endif /* HILINK_TLS_DEBUG */ + +static void InitTlsContextData(HiLinkTlsClient *context) +{ + mbedtls_ssl_init((mbedtls_ssl_context *)&context->ssl); + mbedtls_x509_crt_init((mbedtls_x509_crt *)&context->caCert); + mbedtls_net_init((mbedtls_net_context *)&context->serverFd); + mbedtls_ssl_config_init((mbedtls_ssl_config *)&context->conf); +} + +static int InitTlsContext(HiLinkTlsClient *context) +{ + InitTlsContextData(context); +#if defined(HILINK_TLS_DEBUG) + mbedtls_ssl_conf_dbg(&(context->conf), TlsDebug, context); +#endif /* HILINK_TLS_DEBUG */ + + return HILINK_SAL_OK; +} + +/* 该函数为注册到mbedtls中获取随机数的回调 */ +static int SslRngGenerater(void *param, unsigned char *output, size_t len) +{ + HiLinkDrbgContext drbg = (HiLinkDrbgContext)param; + if ((drbg == NULL) || (output == NULL) || (len == 0)) { + HILINK_SAL_ERROR("param invalid\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + return HILINK_SAL_DrbgRandom(drbg, output, len); +} + +static int SetTlsRandomMember(HiLinkTlsClient *context, const char *custom) +{ + context->drbg = HILINK_SAL_DrbgInit(custom); + if (context->drbg == NULL) { + HILINK_SAL_ERROR("drbg init error\r\n"); + return HILINK_SAL_NOK; + } + + return HILINK_SAL_OK; +} + +static bool X509CheckTime(const mbedtls_x509_time *before, const mbedtls_x509_time *after) +{ + if (before->year > after->year) { + return true; + } else if (before->year < after->year) { + return false; + } + if (before->mon > after->mon) { + return true; + } else if (before->mon < after->mon) { + return false; + } + if (before->day > after->day) { + return true; + } else if (before->day < after->day) { + return false; + } + if (before->hour > after->hour) { + return true; + } else if (before->hour < after->hour) { + return false; + } + if (before->min > after->min) { + return true; + } else if (before->min < after->min) { + return false; + } + if (before->sec > after->sec) { + return true; + } else if (before->sec < after->sec) { + return false; + } + + return true; +} + +static int RecordVaildCertTime(HiLinkTlsClient *context, mbedtls_x509_crt *crt) +{ + HILINK_SAL_DEBUG("vaild cert validFrom=%04d/%02d/%02d %02d:%02d:%02d\r\n", + crt->valid_from.year, crt->valid_from.mon, crt->valid_from.day, + crt->valid_from.hour, crt->valid_from.min, crt->valid_from.sec); + HILINK_SAL_DEBUG("vaild cert validTo=%04d/%02d/%02d %02d:%02d:%02d\r\n", + crt->valid_to.year, crt->valid_to.mon, crt->valid_to.day, + crt->valid_to.hour, crt->valid_to.min, crt->valid_to.sec); + /* 取证书验证通过里面最大的有效时间 */ + if (!X509CheckTime(&context->validTo, &crt->valid_to)) { + if ((memcpy_s(&context->validFrom, sizeof(mbedtls_x509_time), + &crt->valid_from, sizeof(mbedtls_x509_time)) != EOK) || + (memcpy_s(&context->validTo, sizeof(mbedtls_x509_time), + &crt->valid_to, sizeof(mbedtls_x509_time)) != EOK)) { + HILINK_SAL_ERROR("memcpy_s\r\n"); + return HILINK_SAL_NOK; + } + } + HILINK_SAL_DEBUG("record cert validFrom=%04d/%02d/%02d %02d:%02d:%02d\r\n", + context->validFrom.year, context->validFrom.mon, context->validFrom.day, + context->validFrom.hour, context->validFrom.min, context->validFrom.sec); + HILINK_SAL_DEBUG("record cert validTo=%04d/%02d/%02d %02d:%02d:%02d\r\n", + context->validTo.year, context->validTo.mon, context->validTo.day, + context->validTo.hour, context->validTo.min, context->validTo.sec); + + return HILINK_SAL_OK; +} + +static int VerifyCertProc(void *data, mbedtls_x509_crt *crt, uint32_t *flags) +{ + if (data == NULL) { + HILINK_SAL_ERROR("invaild context\r\n"); + return HILINK_SAL_NOK; + } + + int ret; + HiLinkTlsClient *context = (HiLinkTlsClient *)data; + for (unsigned int i = 0; i < context->certsNum; i++) { + mbedtls_x509_crt caCert; + mbedtls_x509_crt_init(&caCert); + ret = mbedtls_x509_crt_parse(&caCert, (const unsigned char *)context->certs[i], + HILINK_Strlen(context->certs[i]) + 1); + if (ret != 0) { + mbedtls_x509_crt_free(&caCert); + HILINK_SAL_WARN("i=%u,ret=[-0x%04x]\r\n", i, -ret); + continue; + } + ret = mbedtls_x509_crt_verify(crt, &caCert, NULL, NULL, flags, NULL, NULL); + mbedtls_x509_crt_free(&caCert); + HILINK_SAL_DEBUG("i=%u,flags=%08x,ret=[-0x%04x]\r\n", i, *flags, -ret); + if (ret == 0) { + if ((*flags) == 0) { + if (RecordVaildCertTime(context, crt) != HILINK_SAL_OK) { + HILINK_SAL_ERROR("record vaild cert time\r\n"); + return HILINK_SAL_NOK; + } + HILINK_SAL_DEBUG("verify cert okay\r\n"); + return HILINK_SAL_OK; + } + } else if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { + /* 只处理校验时间的错误 */ + if (((*flags) == MBEDTLS_X509_BADCERT_EXPIRED) || ((*flags) == MBEDTLS_X509_BADCERT_FUTURE) || + ((*flags) == (MBEDTLS_X509_BADCERT_EXPIRED + MBEDTLS_X509_BADCERT_FUTURE))) { + if (RecordVaildCertTime(context, crt) != HILINK_SAL_OK) { + HILINK_SAL_ERROR("record vaild cert time\r\n"); + return HILINK_SAL_NOK; + } + if (context->isDelayVerifyCert) { + /* 此时先不检查证书时间,待同步到时间后再校验 */ + HILINK_SAL_NOTICE("delay verify cert\r\n"); + *flags &= ~(MBEDTLS_X509_BADCERT_EXPIRED | MBEDTLS_X509_BADCERT_FUTURE); + return HILINK_SAL_OK; + } + } + } + } + + return HILINK_SAL_NOK; +} + +static int VerifyCertCb(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) +{ + (void)depth; + if ((data == NULL) || (crt == NULL) || (flags == NULL)) { + HILINK_SAL_ERROR("param invaild\r\n"); + return HILINK_SAL_NOK; + } + +#if defined(HILINK_TLS_DEBUG) + char buf[64] = {0}; /* 64为缓冲buf大小 */ + HILINK_SAL_NOTICE("\nVerify requested for (Depth %d):\n", depth); + mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt); + HILINK_SAL_NOTICE("%s", buf); + if ((*flags) == 0) { + HILINK_SAL_NOTICE("\n This certificate has no flags\n"); + } else { + mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", *flags); + HILINK_SAL_NOTICE("%s\n", buf); + } +#endif /* HILINK_TLS_DEBUG */ + + if (VerifyCertProc(data, crt, flags) != HILINK_SAL_OK) { + HILINK_SAL_ERROR("verify cert\r\n"); + } + return HILINK_SAL_OK; +} + +static int SetTlsConfigMaxFragLen(HiLinkTlsClient *context, unsigned char maxFragLen) +{ + int ret; + if (maxFragLen != HILINK_MBEDTLS_SSL_MAX_FRAG_LEN_DEFAULT) { + ret = mbedtls_ssl_conf_max_frag_len(&context->conf, maxFragLen); + if (ret != 0) { + HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret); + return HILINK_SAL_NOK; + } + } + return HILINK_SAL_OK; +} + +static int SetTlsConfigBase(HiLinkTlsClient *context) +{ + int ret = mbedtls_ssl_config_defaults(&context->conf, MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); + if (ret != 0) { + HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret); + return HILINK_SAL_NOK; + } + mbedtls_ssl_conf_rng(&context->conf, SslRngGenerater, context->drbg); + mbedtls_ssl_conf_min_version(&context->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); + mbedtls_ssl_conf_max_version(&context->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); + mbedtls_ssl_conf_authmode(&context->conf, MBEDTLS_SSL_VERIFY_REQUIRED); + return HILINK_SAL_OK; +} + +static int SetTlsConfigCiphersuites(HiLinkTlsClient *context, + const int *ciphersuiteWhiteList, const unsigned int ciphersuiteWhiteListNum) +{ + if (ciphersuiteWhiteList != NULL && ciphersuiteWhiteListNum != 0 && context->supportedCiphersuites == NULL) { + /* 支持的白名单算法库肯定比白名单数量少,ciphersuites数组以0为结尾,需预留 */ + unsigned int maxCiphersuitesNum = ciphersuiteWhiteListNum; + int maxSupportedCiphersuitesSize = (maxCiphersuitesNum + 1) * sizeof(int); + int *supportedCiphersuites = HILINK_Malloc(maxSupportedCiphersuitesSize); + if (supportedCiphersuites == NULL) { + HILINK_SAL_ERROR("malloc\r\n"); + return HILINK_SAL_NOK; + } + (void)memset_s(supportedCiphersuites, maxSupportedCiphersuitesSize, 0, maxSupportedCiphersuitesSize); + /* 从白名单中找到库里支持的 */ + int *supportSuite = supportedCiphersuites; + for (unsigned int i = 0; i < maxCiphersuitesNum; i++) { + if (mbedtls_ssl_ciphersuite_from_id(ciphersuiteWhiteList[i]) == NULL) { + HILINK_SAL_NOTICE("i=[%u],ciphersuiteWhiteList=[%04x]\r\n", i, ciphersuiteWhiteList[i]); + continue; + } + if (supportSuite < supportedCiphersuites + maxCiphersuitesNum) { + *supportSuite = ciphersuiteWhiteList[i]; + ++supportSuite; + } + } + *supportSuite = 0; + if (supportSuite == supportedCiphersuites) { + HILINK_Free(supportedCiphersuites); + HILINK_SAL_ERROR("no support ciphersuites\r\n"); + return HILINK_SAL_NOK; + } + context->supportedCiphersuites = supportedCiphersuites; + mbedtls_ssl_conf_ciphersuites(&context->conf, context->supportedCiphersuites); + } + + return HILINK_SAL_OK; +} + +static int SetTlsConfigCert(HiLinkTlsClient *context, + const char **caCerts, const unsigned int certsNum, const bool isDelayVerifyCert) +{ + (void)context; + if ((caCerts != NULL) && (certsNum != 0)) { + /* 对于多个证书,这里只注入一个证书,其他证书在回调函数里验证 */ + int ret = mbedtls_x509_crt_parse(&context->caCert, (const unsigned char *)caCerts[0], strlen(caCerts[0]) + 1); + if (ret < 0) { + HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret); + return HILINK_SAL_NOK; + } + mbedtls_ssl_conf_ca_chain(&context->conf, &context->caCert, NULL); + mbedtls_ssl_conf_verify(&context->conf, VerifyCertCb, context); + context->certs = caCerts; + context->certsNum = certsNum; + context->isDelayVerifyCert = isDelayVerifyCert; + } + + return HILINK_SAL_OK; +} + +static int SetTlsConfigPsk(HiLinkTlsClient *context, + const unsigned char *psk, const size_t pskLen, const unsigned char *pskIdentity, const size_t pskIdentityLen) +{ + (void)context; + if ((psk != NULL) && (pskLen != 0) && (pskIdentity != NULL) && (pskIdentityLen != 0)) { + /* + * 如下是配置psk加密的tls客户端,现在hilink用在与中枢的连接 + */ +#if (defined(HILINK_SDK_BUILD_IN) && defined(SUPPORT_CENTRAL_TLS)) || \ + (!defined(HILINK_SDK_BUILD_IN)) + int ret = mbedtls_ssl_conf_psk(&context->conf, psk, pskLen, pskIdentity, pskIdentityLen); + if (ret < 0) { + HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret); + return HILINK_SAL_NOK; + } +#endif + } + return HILINK_SAL_OK; +} + +static int InitTlsSocket(HiLinkTlsClient *context) +{ + int ret; + if (context->serverFd.fd < 0) { + if (context->hostName != NULL) { + char portStr[MAX_PORT_STR_LEN]; + if (sprintf_s(portStr, sizeof(portStr), "%u", context->port) <= 0) { + HILINK_SAL_ERROR("sprintf_s error\r\n"); + return HILINK_SAL_SPRINTF_ERR; + } + ret = mbedtls_net_connect(&context->serverFd, context->hostName, portStr, + MBEDTLS_NET_PROTO_TCP); + if (ret != 0) { + HILINK_SAL_ERROR("ret=[-0x%04x],errno=[%d]\r\n", -ret, errno); + return ret; + } + } else { + HILINK_SAL_ERROR("no hostname\r\n"); + return HILINK_SAL_NOK; + } + } + mbedtls_ssl_conf_read_timeout(&context->conf, TLS_READ_TIMEOUT_MS); + mbedtls_ssl_set_bio(&context->ssl, &context->serverFd, + mbedtls_net_send, NULL, mbedtls_net_recv_timeout); + + return HILINK_SAL_OK; +} + +static int TlsHandshake(HiLinkTlsClient *context) +{ + int ret; + unsigned long curTime; + unsigned long startTime = 0; + + if (GetOsTime(&startTime) != HILINK_SAL_OK) { + HILINK_SAL_ERROR("GetOsTime\r\n"); + return HILINK_SAL_NOK; + } + do { + ret = mbedtls_ssl_handshake(&context->ssl); + if (GetOsTime(&curTime) != HILINK_SAL_OK) { + HILINK_SAL_ERROR("GetOsTime\r\n"); + return HILINK_SAL_NOK; + } + } while (((ret == MBEDTLS_ERR_SSL_WANT_READ) || (ret == MBEDTLS_ERR_SSL_WANT_WRITE) || + (ret == MBEDTLS_ERR_SSL_TIMEOUT)) && (DeltaTime(curTime, startTime) < TLS_HANDSHAKE_TIMEOUT)); + if (ret != 0) { + HILINK_SAL_ERROR("ret=[-0x%04x],errno=[%d]\r\n", -ret, errno); + return ret; + } + + return HILINK_SAL_OK; +} + +HiLinkTlsClient *HILINK_TlsClientCreate(const char *custom) +{ + if ((custom == NULL) || (HILINK_Strlen(custom) > MAX_CUSTOM_STR_LEN)) { + HILINK_SAL_ERROR("param invaild\r\n"); + return NULL; + } + HILINK_SAL_NOTICE("custom=[%s] start tls create\r\n", custom); + HiLinkTlsClient *ctx = (HiLinkTlsClient *)HILINK_Malloc(sizeof(HiLinkTlsClient)); + if (ctx == NULL) { + HILINK_SAL_ERROR("malloc error\r\n"); + return NULL; + } + (void)memset_s(ctx, sizeof(HiLinkTlsClient), 0, sizeof(HiLinkTlsClient)); + + int ret; + do { + int mallocSize = HILINK_Strlen(custom) + 1; + ctx->custom = (char *)HILINK_Malloc(mallocSize); + if (ctx->custom == NULL) { + HILINK_SAL_ERROR("malloc error\r\n"); + break; + } + (void)memset_s(ctx->custom, mallocSize, 0, mallocSize); + + ret = strcpy_s(ctx->custom, mallocSize, custom); + if (ret != EOK) { + HILINK_SAL_ERROR("strcpy error %d\r\n", ret); + break; + } + + InitMbedtls(); + ret = InitTlsContext(ctx); + if (ret != HILINK_SAL_OK) { + HILINK_SAL_ERROR("init error %d\r\n", ret); + break; + } + + ret = SetTlsRandomMember(ctx, custom); + if (ret != HILINK_SAL_OK) { + HILINK_SAL_ERROR("set random error %d\r\n", ret); + break; + } + + ret = SetTlsConfigBase(ctx); + if (ret != HILINK_SAL_OK) { + HILINK_SAL_ERROR("set config base error %d\r\n", ret); + break; + } + + return ctx; + } while (0); + (void)HILINK_TlsClientFreeResource(ctx); + return NULL; +} + +static int SetTlsClientOptionHost(HiLinkTlsClient *ctx, const void *value, unsigned int len) +{ + if ((len != sizeof(HiLinkTlsHost) || (value == NULL))) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + const HiLinkTlsHost *host = (const HiLinkTlsHost *)value; + ctx->port = host->port; + if (host->hostname == NULL) { + HILINK_SAL_INFO("no host name for [%s]\r\n", ctx->custom); + return HILINK_SAL_OK; + } + + unsigned int hostNameLen = HILINK_Strlen(host->hostname); + if (hostNameLen > MAX_HOSTNAME_STR_LEN) { + HILINK_SAL_WARN("host name too long [%u]\r\n", hostNameLen); + return HILINK_SAL_PARAM_INVALID; + } + int ret = mbedtls_ssl_set_hostname(&ctx->ssl, host->hostname); + if (ret != 0) { + HILINK_SAL_ERROR("set host name error, ret=[-0x%04x]\r\n", -ret); + return HILINK_SAL_NOK; + } + if (ctx->hostName != NULL) { + HILINK_Free(ctx->hostName); + ctx->hostName = NULL; + } + ctx->hostName = (char *)HILINK_Malloc(hostNameLen + 1); + if (ctx->hostName == NULL) { + HILINK_SAL_ERROR("malloc error\r\n"); + return HILINK_SAL_NOK; + } + (void)memset_s(ctx->hostName, hostNameLen + 1, 0, hostNameLen + 1); + ret = strcpy_s(ctx->hostName, hostNameLen + 1, host->hostname); + if (ret != EOK) { + HILINK_SAL_ERROR("strcpy error %d\r\n", ret); + HILINK_Free(ctx->hostName); + ctx->hostName = NULL; + return HILINK_SAL_NOK; + } + + return HILINK_SAL_OK; +} + +static int SetTlsClientOptionFd(HiLinkTlsClient *ctx, const void *value, unsigned int len) +{ + if ((len != sizeof(int) || (value == NULL))) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + + int fd = *(const int *)value; + if (fd < 0) { + HILINK_SAL_WARN("invalid fd"); + return HILINK_SAL_PARAM_INVALID; + } + ctx->serverFd.fd = fd; + + return HILINK_SAL_OK; +} + +static int SetTlsClientOptiontTimeCallback(HiLinkTlsClient *ctx, const void *value, unsigned int len) +{ + (void)ctx; + if ((len != sizeof(HiLinkMbedtlsGetTimeCb)) || (value == NULL)) { + HILINK_SAL_WARN("invalid param"); + return HILINK_SAL_PARAM_INVALID; + } + + g_mbedtlsGetTimeCb = (HiLinkMbedtlsGetTimeCb)value; + return HILINK_SAL_OK; +} + +static int SetTlsClientOptiontCiphersuite(HiLinkTlsClient *ctx, const void *value, unsigned int len) +{ + if ((len != sizeof(HiLinkTlsCiphersuites)) || (value == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + const HiLinkTlsCiphersuites *suites = (const HiLinkTlsCiphersuites *)value; + if ((suites->ciphersuites == NULL) || (suites->num == 0)) { + HILINK_SAL_WARN("invalid suites\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + return SetTlsConfigCiphersuites(ctx, suites->ciphersuites, suites->num); +} + +static int SetTlsClientOptiontCert(HiLinkTlsClient *ctx, const void *value, unsigned int len) +{ + if ((len != sizeof(HiLlinkTlsCerts)) || (value == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + const HiLlinkTlsCerts *certs = (const HiLlinkTlsCerts *)value; + if ((certs->certs == NULL) || (certs->num == 0)) { + HILINK_SAL_WARN("invalid certs\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + return SetTlsConfigCert(ctx, certs->certs, certs->num, certs->num); +} + +static int SetTlsClientOptiontPsk(HiLinkTlsClient *ctx, const void *value, unsigned int len) +{ + if ((len != sizeof(HiLlinkTlsPsk)) || (value == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + const HiLlinkTlsPsk *psk = (const HiLlinkTlsPsk *)value; + if ((psk->psk == NULL) || (psk->pskLen == 0) || (psk->pskIdentity == NULL) || + (psk->pskIdentityLen == 0)) { + HILINK_SAL_WARN("invalid psk\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + return SetTlsConfigPsk(ctx, psk->psk, psk->pskLen, psk->pskIdentity, psk->pskIdentityLen); +} + +static int SetTlsClientOptiontMaxFragLen(HiLinkTlsClient *ctx, const void *value, unsigned int len) +{ + if ((len != sizeof(unsigned char)) || (value == NULL)) { + HILINK_SAL_WARN("invalid param\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + unsigned char fragLenType = *(const unsigned char *)value; + + return SetTlsConfigMaxFragLen(ctx, fragLenType); +} + +int HILINK_SetTlsClientOption(HiLinkTlsClient *ctx, HiLinkTlsOption option, const void *value, unsigned int len) +{ + if (ctx == NULL) { + HILINK_SAL_ERROR("param invaild\r\n"); + return HILINK_SAL_NOK; + } + + static const OptionItem optionList[] = { + {HILINK_TLS_OPTION_FD, SetTlsClientOptionFd}, + {HILINK_TLS_OPTION_REG_TIME_CB, SetTlsClientOptiontTimeCallback}, + {HILINK_TLS_OPTION_HOST, SetTlsClientOptionHost}, + {HILINK_TLS_OPTION_CIPHERSUITE, SetTlsClientOptiontCiphersuite}, + {HILINK_TLS_OPTION_CERT, SetTlsClientOptiontCert}, + {HILINK_TLS_OPTION_PSK, SetTlsClientOptiontPsk}, + {HILINK_TLS_OPTION_MAX_FRAG_LEN, SetTlsClientOptiontMaxFragLen}, + }; + for (unsigned int i = 0; i < (sizeof(optionList) / sizeof(OptionItem)); ++i) { + if (option == optionList[i].option) { + return optionList[i].setOptionFunc(ctx, value, len); + } + } + HILINK_SAL_WARN("unsupport option %d\r\n", option); + return HILINK_SAL_NOT_SUPPORT; +} + +int HILINK_TlsClientConnect(HiLinkTlsClient *ctx) +{ + if (ctx == NULL) { + HILINK_SAL_ERROR("param invaild\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + int ret = InitTlsSocket(ctx); + if (ret != HILINK_SAL_OK) { + HILINK_SAL_ERROR("init socket error\r\n"); + return ret; + } + + ret = mbedtls_ssl_setup(&ctx->ssl, &ctx->conf); + if (ret != 0) { + HILINK_SAL_ERROR("ret=[-0x%04x]\r\n", -ret); + return ret; + } + + ret = TlsHandshake(ctx); + if (ret != HILINK_SAL_OK) { + HILINK_SAL_ERROR("handshake\r\n"); + return ret; + } + + return HILINK_SAL_OK; +} + +int HILINK_TlsClientGetContextFd(HiLinkTlsClient *ctx) +{ + if (ctx == NULL) { + HILINK_SAL_DEBUG("param invaild\r\n"); + return -1; + } + + return ctx->serverFd.fd; +} + +int HILINK_TlsClientRead(HiLinkTlsClient *ctx, unsigned char *buf, size_t len) +{ + if ((ctx == NULL) || (buf == NULL) || (len == 0)) { + HILINK_SAL_ERROR("param invaild\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + if (ctx->serverFd.fd < 0) { + HILINK_SAL_ERROR("context invaild\r\n"); + return HILINK_SAL_FD_INVALID; + } + + int ret = mbedtls_ssl_read(&ctx->ssl, buf, len); + if (ret > 0) { + HILINK_SAL_DEBUG("read exit,custom=[%s],len=[%d]\r\n", ctx->custom, ret); + return ret; + } else if (ret == 0) { + HILINK_SAL_ERROR("custom=[%s],ret=[%d],errno=[%d]\r\n", ctx->custom, ret, errno); + return HILINK_SAL_NOK; + } else if ((ret == MBEDTLS_ERR_SSL_TIMEOUT) || + (ret == MBEDTLS_ERR_SSL_WANT_WRITE) || (ret == MBEDTLS_ERR_SSL_WANT_READ)) { + return HILINK_SAL_OK; + } + + HILINK_SAL_ERROR("custom=[%s],ret=[-0x%04x],errno=[%d]\r\n", ctx->custom, -ret, errno); + return ret; +} + +int HILINK_TlsClientWrite(HiLinkTlsClient *ctx, const unsigned char *buf, size_t len) +{ + if ((ctx == NULL) || (buf == NULL) || (len == 0)) { + HILINK_SAL_ERROR("param invaild\r\n"); + return HILINK_SAL_PARAM_INVALID; + } + + if (ctx->serverFd.fd < 0) { + HILINK_SAL_ERROR("context invaild\r\n"); + return HILINK_SAL_FD_INVALID; + } + + unsigned long curTime = 0; + unsigned long startTime = 0; + if (GetOsTime(&startTime) != HILINK_SAL_OK) { + return HILINK_SAL_TIME_ERR; + } + + int writeLen = 0; + while ((size_t)writeLen < len) { + if (GetOsTime(&curTime) != HILINK_SAL_OK) { + return HILINK_SAL_TIME_ERR; + } + + if (DeltaTime(curTime, startTime) > GetTlsTimeoutTime(len)) { + HILINK_SAL_ERROR("tls write timeout,writeLen=[%d],len=[%u]\r\n", writeLen, len); + return HILINK_SAL_TIMEOUT; + } + + int ret = mbedtls_ssl_write(&ctx->ssl, buf + writeLen, len - writeLen); + if (ret > 0) { + writeLen += ret; + HILINK_SAL_DEBUG("custom=[%s],writeLen=[%d]\r\n", ctx->custom, writeLen); + continue; + } else if (ret == 0) { + HILINK_SAL_ERROR("custom=[%s],ret=[%d],errno=[%d]\r\n", ctx->custom, ret, errno); + return HILINK_SAL_NOK; + } else if ((ret == MBEDTLS_ERR_SSL_TIMEOUT) || + (ret == MBEDTLS_ERR_SSL_WANT_WRITE) || (ret == MBEDTLS_ERR_SSL_WANT_READ)) { + HILINK_MilliSleep(1); + continue; + } else { + HILINK_SAL_ERROR("custom=[%s],ret=[-0x%04x],errno=[%d]\r\n", ctx->custom, -ret, errno); + return ret; + } + } + + return writeLen; +} + +bool HILINK_TlsClientIsValidCert(HiLinkTlsClient *ctx) +{ + if (ctx == NULL) { + HILINK_SAL_NOTICE("param invaild\r\n"); + return false; + } + + int ret; + ret = mbedtls_x509_time_is_future(&ctx->validFrom); + if (ret != 0) { + HILINK_SAL_ERROR("ret=[%d]\r\n", ret); + return false; + } + ret = mbedtls_x509_time_is_past(&ctx->validTo); + if (ret != 0) { + HILINK_SAL_ERROR("ret=[%d]\r\n", ret); + return false; + } + + return true; +} + +int HILINK_TlsClientFreeResource(HiLinkTlsClient *ctx) +{ + if (ctx == NULL) { + HILINK_SAL_NOTICE("param invaild\r\n"); + return HILINK_SAL_NOK; + } + + mbedtls_ssl_free(&ctx->ssl); + mbedtls_net_free(&ctx->serverFd); + mbedtls_ssl_config_free(&ctx->conf); + mbedtls_x509_crt_free(&ctx->caCert); + HILINK_SAL_DrbgDeinit(ctx->drbg); + ctx->drbg = NULL; + HILINK_Free(ctx->supportedCiphersuites); + ctx->supportedCiphersuites = NULL; + if (ctx->custom != NULL) { + HILINK_SAL_NOTICE("custom=[%s] free resource success\r\n", ctx->custom); + HILINK_Free(ctx->custom); + ctx->custom = NULL; + } + if (ctx->hostName != NULL) { + HILINK_Free(ctx->hostName); + ctx->hostName = NULL; + } + HILINK_Free(ctx); + return HILINK_SAL_OK; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/entry/Makefile b/application/samples/wifi/ohos_connect/hilink_adapt/entry/Makefile new file mode 100755 index 0000000..10f1e8b --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/entry/Makefile @@ -0,0 +1,45 @@ +#ǰ· +PWD := . +BASE_PATH := $(PWD)/. + +CC :=/usr/bin/gcc +AR :=/usr/bin/ar + +#CC := /opt/toolchains/yocto-32bit-toolchain/sysroots/x86_64-oesdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc +#AR := /opt/toolchains/yocto-32bit-toolchain/sysroots/x86_64-oesdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-ar + +#ͷļ· +INCLUDE_PATH := -I$(BASE_PATH)/include + +#Դļ +SOURCE_FILES := $(wildcard $(BASE_PATH)/*.c) + +#ļ· +LIB_FILE_PATH := $(BASE_PATH)/../lib + +#ļ +LIB_FILES := -lhilinkbtsdk -lpthread + +#.oļ +OBJECTS_PATH := objs +OBJECTS := $(patsubst %.c, %.o, $(SOURCE_FILES)) + +#ѡ +COMPILE_FLAGS := -g -O $(INCLUDE_PATH) +LINK_FLAGS := -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack --data-sections -L$(LIB_FILE_PATH) $(LIB_FILES) + +#뿪ʼ +.PHONY: all +all: clean demo + +# +clean: + rm -f $(OBJECTS) + +# +demo: $(OBJECTS) + $(CC) -o $@ $(OBJECTS) $(LINK_FLAGS) + +#.o +$(OBJECTS):%.o : %.c + $(CC) $(COMPILE_FLAGS) -c $< -o $@ diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_ble_main.c b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_ble_main.c new file mode 100755 index 0000000..19e678d --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_ble_main.c @@ -0,0 +1,531 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved. + * Description: 蓝牙SDK提供demo示例代码(此文件为DEMO,需集成方适配修改) + */ +#include +#include +#include +#include +#include +#include "cJSON.h" +#include "hilink_bt_api.h" +#include "hilink_sle_api.h" +#include "hilink_bt_function.h" +#include "ble_cfg_net_api.h" +#include "hilink_device.h" +#include "hilink_sal_defines.h" +#include "ohos_bt_gatt.h" +#include "ohos_bt_gatt_server.h" +#include "cmsis_os2.h" +#include "hal_reboot.h" +#include "device_profile.h" +#include "hilink_custom.h" +#include "hilink_mem_adapter.h" +#include "hilink_network_adapter.h" +#include "hilink_socket_adapter.h" +#include "hilink_network_adapter.h" +#include "hilink_device.h" +#include "wifi_device.h" +#include "securec.h" +#include "hsf.h" +#include "hilink_entry.h" + +#define min_len(a, b) (((a) < (b)) ? (a) : (b)) + +#define SWITCH_REPORT "{\"data\":{\"on\":%d},\"sid\":\"switch\"}" +#define UPDATE_REPORT "{\"data\":{\"autoUpdate\":%d},\"sid\":\"update\"}" +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE +#define CHECKSUM_SID "checkSum" +#define CHECKSUM_REPORT "{\"data\":{\"checkSum\":\"%s\"},\"sid\":\"checkSum\"}" +#endif + +//static bool g_switch = 0; +int sid_switch; +static bool g_autoUpdate = 0; + +static HILINK_BT_DevInfo g_btDevInfo = {0}; +extern int set_get_ble_mac(void); +extern int HILINK_Printf(const char *format, ...); +#define HILINK_BLE_MAIN "HILINK_BLE_MAIN" +#define HILINK_BLE_MAIN_PRINT(fmt, args...) \ + HILINK_Printf("[%s][%s:%d] " fmt "\n", HILINK_BLE_MAIN, __FUNCTION__, __LINE__, ##args) +const char *GetMacSn(void) +{ + static char macSn[3 * WIFI_MAC_LEN + 1] = {0}; + unsigned char mac[WIFI_MAC_LEN] = {0}; + (void)HILINK_GetMacAddr(mac, WIFI_MAC_LEN); + (void)sprintf_s(macSn, sizeof(macSn), "%02X%02X%02X%02X%02X%02X", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return macSn; +} +/* + * 功能: 获取设备sn号 + * 参数[in]: len sn的最大长度, 39字节 + * 参数[out]: sn 设备sn + * 注意: sn指针的字符串长度为0时将使用设备mac地址作为sn + */ +void HILINK_GetDeviceSn(unsigned int len, char *sn) +{ + if (sn == NULL) + { + return; + } + + (void)strcpy_s(sn, len, hfget_hilink_sn()); +} + +/* + * 获取设备的子型号,长度固定两个字节 + * subProdId为保存子型号的缓冲区,len为缓冲区的长度 + * 如果产品定义有子型号,则填入两字节子型号,并以'\0'结束, 返回0 + * 没有定义子型号,则返回-1 + * 该接口需设备开发者实现 + */ +int HILINK_GetSubProdId(char *subProdId, int len) +{ + if (subProdId == NULL || len <= 0) { + return -1; + } + if (strcpy_s(subProdId, len, SUB_PRODUCT_ID) != EOK) { + return -1; + } + return 0; +} + +/* + * 获取设备表面的最强点信号发射功率强度,最强点位置的确定以及功率测试方 + * 法,参照hilink认证蓝牙靠近发现功率设置及测试方法指导文档,power为出参, + * 单位dbm,下一次发送广播时生效 + */ +int HILINK_BT_GetDevSurfacePower(char *power) +{ + if (power == NULL) { + return -1; + } + *power = ADV_TX_POWER; + return 0; +} + +const char *GetMacStr(void) +{ + static char macStr[3 * WIFI_MAC_LEN + 1] = {0}; + unsigned char mac[WIFI_MAC_LEN] = {0}; + (void)HILINK_GetMacAddr(mac, WIFI_MAC_LEN); + (void)sprintf_s(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return macStr; +} +/* 获取蓝牙SDK设备相关信息 */ +//char hf_mac_string[16]={0}; +HILINK_BT_DevInfo *HILINK_BT_GetDevInfo(void) +{ + HILINK_SAL_NOTICE("HILINK_BT_GetDevInfo\n"); + + g_btDevInfo.manuName = configName; + g_btDevInfo.devName = configType; + g_btDevInfo.productId = ProductId; + g_btDevInfo.mac = (char *)GetMacStr(); + g_btDevInfo.model = deviceModel; + g_btDevInfo.devType = deviceTypeId; + g_btDevInfo.hiv = DEVICE_HIVERSION; + if(hfget_hilink_mode() == SMTLK_BLE_NARMAL || hfget_hilink_mode() == SMTLK_SOFTAP) + { + g_btDevInfo.protType = 1; + } + else if(hfget_hilink_mode() == SMTLK_BLE_ADD_LOCAL_CONTROL) + { + g_btDevInfo.protType = 12; + } + else if(hfget_hilink_mode() == SMTLK_BLE_FAST_CONNECT) + { + g_btDevInfo.protType = 17; + } + g_btDevInfo.sn = hfget_hilink_sn(); + return &g_btDevInfo; +} +/* + * 若厂商发送广播类型为BLE_ADV_CUSTOM时才需适配此接口 + * 获取厂商定制信息,由厂家实现 + * 返回0表示获取成功,返回其他表示获取失败 + */ +int HILINK_GetCustomInfo(char *customInfo, unsigned int len) +{ + if (customInfo == NULL || len == 0) { + return -1; + } + if (strcpy_s(customInfo, len, BT_CUSTOM_INFO) != EOK) { + return -1; + } + + return 0; +} + +/* + * 若厂商发送广播类型为BLE_ADV_CUSTOM时才需适配此接口 + * 获取厂家ID,由厂家实现 + * 返回0表示获取成功,返回其他表示获取失败 + */ +int HILINK_GetManuId(char *manuId, unsigned int len) +{ + if (manuId == NULL || len == 0) { + return -1; + } + if (strcpy_s(manuId, len, DEVICE_MANU_ID) != EOK) { + return -1; + } + + return 0; +} + +/* + * 获取蓝牙mac地址,由厂家实现 + * 返回0表示获取成功,返回其他表示获取失败 + */ +int HILINK_BT_GetMacAddr(unsigned char *mac, unsigned int len) +{ + (void)mac; + (void)len; + return 0; +} + +/* 填写固件、软件和硬件版本号,APP显示版本号以及OTA版本检查与此相关 */ +int getDeviceVersion(char* *firmwareVer, char* *softwareVer, char* *hardwareVer) +{ + if (firmwareVer == NULL || softwareVer == NULL || hardwareVer == NULL) { + return -1; + } +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE + static char fwvWithSwv[64] = ""; + if (sprintf_s(fwvWithSwv, sizeof(fwvWithSwv), "%s_%s", FIRMWARE_VER, SOFTWARE_VER) <= 0) { + return -1; + } + *firmwareVer = fwvWithSwv; +#else + *firmwareVer = FIRMWARE_VER; +#endif + *softwareVer = (char *)SOFTWARE_VER; + *hardwareVer = HARDWARE_VER; + return 0; +} + +//#if (HILINK_NETCFG_MODE != SOFTAP_MODE) + +static void ReporSwitchStatus(void) +{ + char buff[128] = { 0 }; + int ret = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, SWITCH_REPORT, sid_switch); + if (ret <= 0) { + HILINK_SAL_NOTICE("ReporSwitchStatus snprintf_s ret:%d\r\n", ret); + return; + } + unsigned int buffLen = strlen(buff); + ret = BLE_SendCustomData(CUSTOM_SEC_DATA, (const unsigned char *)buff, buffLen); + HILINK_SAL_NOTICE("BLE_SendCustomData:%s len:%u,ret:%d\r\n", buff, buffLen, ret); +} + +static void ReporAutoUpdateStatus(void) +{ + char buff[128] = { 0 }; + int ret = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, UPDATE_REPORT, g_autoUpdate); + if (ret <= 0) { + HILINK_SAL_NOTICE("ReporAutoUpdateStatus snprintf_s ret:%d\r\n", ret); + return; + } + unsigned int buffLen = strlen(buff); + ret = BLE_SendCustomData(CUSTOM_SEC_DATA, (const unsigned char *)buff, buffLen); + HILINK_SAL_NOTICE("BLE_SendCustomData:%s len:%u,ret:%d\r\n", buff, buffLen, ret); +} + +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE +static void ReporFwvCheckSum(void) +{ + char fwvCheckSum[65] = { 0 }; + unsigned int size = sizeof(fwvCheckSum); + int ret = read_app_bin_hash(fwvCheckSum, &size); + if (ret < 0) { + HILINK_SAL_NOTICE("ReporFwvCheckSum get fwv checksum ret:%d\r\n", ret); + return; + } + char buff[128] = { 0 }; + ret = snprintf_s(buff, sizeof(buff), sizeof(buff) - 1, CHECKSUM_REPORT, fwvCheckSum); + if (ret <= 0) { + HILINK_SAL_NOTICE("ReporFwvCheckSum snprintf_s ret:%d\r\n", ret); + return; + } + unsigned int buffLen = strlen(buff); + ret = BLE_SendCustomData(CUSTOM_SEC_DATA, (const unsigned char *)buff, buffLen); + HILINK_SAL_NOTICE("BLE_SendCustomData:%s len:%u,ret:%d\r\n", buff, buffLen, ret); +} +#endif + +static void HILINK_BT_StateChangeHandler(HILINK_BT_SdkStatus event, const void *param) +{ + (void)param; + /* ble sdk初始化完成后,发送广播让设备被手机发现 */ + if (event == HILINK_BT_SDK_STATUS_SVC_RUNNING) { + /* + * 由于 sle 与 ble 协议栈中的 mac 会在使能协议栈之后恢复默认, + * 当前海思未释放星闪 hilink 适配层代码,所以放在此处设置 mac, + * 保证能在使能之后起广播前能设置正确的 mac 到协议栈 + */ + if (SetBleAndSleAddrToStackFromNv() != 0) { + HILINK_SAL_ERROR("set addr err\n"); + } + /* 设置蓝牙广播格式,包括靠近发现、碰一碰等,下一次发送广播生效 */ + BLE_SetAdvType(BLE_ADV_LOCAL_NAME); + + /* BLE配网广播控制:参数代表广播时间,0:停止;0xFFFFFFFF:一直广播,其他:广播指定时间后停止,单位秒 */ + (void)BLE_CfgNetAdvCtrl(BLE_ADV_TIME); + } +} + +static BLE_ConfPara g_isBlePair = { + .isBlePair = 0, +}; + +static BLE_InitPara g_bleInitParam = { + .confPara = &g_isBlePair, + /* advInfo为空表示使用ble sdk默认广播参数及数据 */ + .advInfo = NULL, + .gattList = NULL, +}; + +static int BleHandleCustomDataGet(const char *sid) +{ + HILINK_SAL_NOTICE("get %s svc\r\n", sid); + if (strcmp(sid, "switch") == 0) { + ReporSwitchStatus(); + return 0; + } else if (strcmp(sid, "update") == 0) { + ReporAutoUpdateStatus(); + return 0; +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE + } else if (strcmp(sid, CHECKSUM_SID) == 0) { + ReporFwvCheckSum(); + return 0; +#endif + } + return -1; +} + +// 参考链接 https://device.harmonyos.com/cn/docs/devicepartner/DevicePartner-Guides/device-development-ble-specifications-control-0000001482432154 +static int BleHandleCustomData(const char *buff, unsigned int len) +{ + if (strcmp((char *)buff, "{}") == 0) { + /* 上报全量数据 */ + ReporSwitchStatus(); +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE + ReporFwvCheckSum(); +#endif + return 0; + } + int ret = -1; + + cJSON *json = cJSON_Parse(buff); + if (json == NULL) { + return ret; + } + + do { + cJSON *sidItem = cJSON_GetObjectItem(json, "sid"); + cJSON *dataItem = cJSON_GetObjectItem(json, "data"); + if (sidItem == NULL || !cJSON_IsString(sidItem) || (sidItem->valuestring == NULL)) { + break; + } + + if (dataItem == NULL) { + ret = BleHandleCustomDataGet(sidItem->valuestring); + break; + } + + if (strcmp(sidItem->valuestring, "allservices") == 0) { + /* H5 连接上时会给设备发送allservices, 设备需要给H5同步全量状态 */ + HILINK_SAL_NOTICE("sync dev status\r\n"); + ReporSwitchStatus(); +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE + ReporFwvCheckSum(); +#endif + ret = 0; + break; + } else if (strcmp(sidItem->valuestring, "currentTime") == 0) { + // 参考格式 {"sid":"currentTime", "data":{"currentTime":"1730692041"}} + cJSON *item = cJSON_GetObjectItem(dataItem, "currentTime"); + if (item != NULL) { + HILINK_SAL_NOTICE("sync time %d\r\n", item->valueint); + } + ret = 0; + break; + } else if (strcmp(sidItem->valuestring, "switch") == 0) { + cJSON *item = cJSON_GetObjectItem(dataItem, "on"); + if (item == NULL) { + HILINK_SAL_NOTICE("on json null\r\n"); + break; + } + sid_switch = item->valueint; + HILINK_Printf("DEMO: Hilink receive a switch cmd, on = %d\r\n", sid_switch); + ReporSwitchStatus(); // 连上手机蓝牙时,发的第一个cjson数据。同步一次设备状态 + ret = 0; + break; + } else if (strcmp(sidItem->valuestring, "update") == 0) { + cJSON *item = cJSON_GetObjectItem(dataItem, "autoUpdateOn"); + if (item == NULL) { + HILINK_SAL_NOTICE("autoUpdateOn json null\r\n"); + ret = -1; + break; + } + g_autoUpdate = item->valueint != 0 ? true : false; + + HILINK_SAL_NOTICE("DEMO: Hilink receive a update cmd, on = %d\r\n", g_autoUpdate); + ReporAutoUpdateStatus(); // 连上手机蓝牙时,发的第一个cjson数据。同步一次设备状态 + ret = 0; + break; + } + } while(0); + + cJSON_Delete(json); + return ret; +} + +/* APP下发自定义指令时调用此函数,需处理自定义数据,返回0表示处理成功 */ +static int BleRcvCustomData(unsigned char *buff, unsigned int len) +{ + if (buff == NULL || len == 0) { + HILINK_SAL_NOTICE("buff is NULL\r\n"); + return -1; + } + HILINK_SAL_NOTICE("custom data, len: %u, data: %s", len, buff); + + /* 处理自定义数据 */ + if (BleHandleCustomData((const char *)buff, len) != 0) { + HILINK_SAL_NOTICE("BleHandleCustomData fail"); + return -1; + } + + return 0; +} + +int CfgNetProcess(BLE_CfgNetStatus status) +{ + HILINK_SAL_NOTICE("status: %d", status); + if (status == CFG_NET_BLE_DIS_CONNECT) { + BLE_CfgNetAdvUpdate(NULL); + } + return 0; +} + +static BLE_CfgNetCb g_bleCfgNetCb = { + .rcvCustomDataCb = BleRcvCustomData, + .cfgNetProcessCb = CfgNetProcess, +}; + +static int HardReboot(void) +{ + extern int HILINK_MilliSleep(unsigned int ms); + HILINK_MilliSleep(100); + hal_reboot_chip(); + return 0; +} + +unsigned int GetWifiRecoveryType(void) +{ + return (0x01 | 0x02); +} + +int hilink_ble_main(void) +{ + int ret = 0; + int hilink_entry_mode=hfget_hilink_mode(); + printf("hilink_entry_mode:%d\r\n",hilink_entry_mode); + if(hilink_entry_mode != SMTLK_SOFTAP) + { + if(hfget_hilink_mode() == SMTLK_BLE_NARMAL) + { + HILINK_SetProtType(1); + } + else if(hfget_hilink_mode() == SMTLK_BLE_ADD_LOCAL_CONTROL) + { + HILINK_SetProtType(12); + } + else if(hfget_hilink_mode() == SMTLK_BLE_FAST_CONNECT) + { + /* 打开星闪总开关 */ + HILINK_EnableSle(); + HILINK_EnablePrescan(); + HILINK_SetProtType(17); + } + + ret = HILINK_SetNetConfigMode(HILINK_NETCONFIG_OTHER); + + /* 设备按需设置,例如接入蓝牙网关时,设置广播类型标志及心跳间隔 */ + unsigned char mpp[] = {0x02, 0x3c, 0x00}; + ret = BLE_SetAdvNameMpp(mpp, sizeof(mpp)); + if (ret != 0) { + HILINK_SAL_NOTICE("set adv name mpp failed\r\n"); + return -1; + } + + /* 注册SDK状态接收函数,可在初始化完成后发送广播 */ + ret = HILINK_BT_SetSdkEventCallback(HILINK_BT_StateChangeHandler); + if (ret != 0) { + HILINK_SAL_NOTICE("set event callback failed\r\n"); + return -1; + } + + /* 设置广播方式为靠近发现 */ + BLE_SetAdvType(BLE_ADV_LOCAL_NAME); + + /* 初始化ble sdk */ + ret = BLE_CfgNetInit(&g_bleInitParam, &g_bleCfgNetCb); + if (ret != 0) { + HILINK_SAL_NOTICE("ble sdk init fail\r\n"); + return -1; + } + //set_get_ble_mac(); + } + else if(hilink_entry_mode == SMTLK_SOFTAP) + { + HILINK_SetProtType(1); + ret = HILINK_SetNetConfigMode(HILINK_NETCONFIG_WIFI); + } + + + /* 修改任务属性 */ + HILINK_SdkAttr *sdkAttr = HILINK_GetSdkAttr(); + if (sdkAttr == NULL) { + HILINK_SAL_NOTICE("sdkAttr is null"); + return -1; + } + sdkAttr->monitorTaskStackSize = 0x600; /* 示例代码 推荐栈大小为0x400 */ + sdkAttr->rebootHardware = HardReboot; + sdkAttr->rebootSoftware = HardReboot; + HILINK_SetSdkAttr(*sdkAttr); + + /* 注册极简配网WIFI相关函数 */ + WiFiRecoveryApi wifiCb; + wifiCb.getWifiRecoveryType = GetWifiRecoveryType; + wifiCb.scanAP = HILINK_ScanAP; + wifiCb.getAPScanResult = HILINK_GetAPScanResult; + wifiCb.restartWiFi = HILINK_RestartWiFi; + wifiCb.connectWiFiByBssid = HILINK_ConnectWiFiByBssid; + wifiCb.lastConnResult = HILINK_GetLastConnectResult; + if (HILINK_RegWiFiRecoveryCallback((const WiFiRecoveryApi *)&wifiCb, sizeof(wifiCb)) != 0) { + HILINK_SAL_NOTICE("reg wifi recovery failed!\r\n"); + return -1; + } + HILINK_SAL_NOTICE("RegWiFiRecoveryCallback finish!\n"); + +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE + if (HILINK_RegisterErrnoCallback(get_os_errno) != 0) { + HILINK_SAL_NOTICE("reg errno cb err\r\n"); + return -1; + } +#endif + + /* 启动Hilink SDK */ + if (HILINK_Main() != 0) { + HILINK_SAL_NOTICE("HILINK_Main start error"); + return -1; + } + hf_set_hilink_main_runing(); + return 0; +} \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_entry.c b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_entry.c new file mode 100755 index 0000000..d4dfb49 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_entry.c @@ -0,0 +1,6 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: HiLink SDK 配网的入口函数 + */ + + diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_indie_upgrade_main.c b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_indie_upgrade_main.c new file mode 100755 index 0000000..fb0a342 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_indie_upgrade_main.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: HiLink独立升级入口 + */ +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE +#include +#include +#include "hilink.h" +#include "app_call_entry.h" +#include "memory_config_common.h" +#include "sfc.h" +#include "securec.h" + +#define ONE_BYTE_HEXIFY_LEN 2 +#define HEXIFY_LEN(len) ((len) * ONE_BYTE_HEXIFY_LEN) +#define BIN_HASH_LEN 32 +/* 需减去固件包头长度0x300 */ +#define APP_BIN_ADDR (APP_PROGRAM_ORIGIN - FLASH_START - 0x300) +#define CODE_AREA_HASH_OFFSET 0x128 + +bool hexify(const unsigned char *inBuf, unsigned int inBufLen, char *outBuf, unsigned int outBufLen) +{ + if (outBufLen < HEXIFY_LEN(inBufLen)) { + return false; + } + + unsigned char high; + unsigned char low; + while (inBufLen > 0) { + /* 对16取模得到高位 */ + high = *inBuf / 16; + /* 对16取余得到低位 */ + low = *inBuf % 16; + /* 数字10表示16进制字符a与其代表10进制数字的值 */ + if (high < 10) { + *outBuf++ = '0' + high; + } else { + /* 数字10表示16进制字符a与其代表10进制数字的值 */ + *outBuf++ = 'A' + high - 10; + } + /* 数字10表示16进制字符a与其代表10进制数字的值 */ + if (low < 10) { + *outBuf++ = '0' + low; + } else { + /* 数字10表示16进制字符a与其代表10进制数字的值 */ + *outBuf++ = 'A' + low - 10; + } + + ++inBuf; + inBufLen--; + } + + return true; +} + +int read_app_bin_hash(char *hash_str, unsigned int *size) +{ + if (hash_str == NULL || size == NULL || *size <= HEXIFY_LEN(BIN_HASH_LEN)) { + printf("param err\n"); + return -1; + } + unsigned char bin_hash[BIN_HASH_LEN] = { 0 }; + errcode_t err = uapi_sfc_reg_read(APP_BIN_ADDR + CODE_AREA_HASH_OFFSET, bin_hash, BIN_HASH_LEN); + if (err != ERRCODE_SUCC) { + printf("read bin hash fail:%u\n", err); + return -1; + } + (void)memset_s(hash_str, HEXIFY_LEN(BIN_HASH_LEN) + 1, 0, HEXIFY_LEN(BIN_HASH_LEN) + 1); + if (!hexify(bin_hash, BIN_HASH_LEN, hash_str, *size)) { + printf("hexify bin hash fail\n"); + return -1; + } + *size = HEXIFY_LEN(BIN_HASH_LEN); + return 0; +} + +int hilink_indie_upgrade_main(void) +{ + hilink_func_map_init(); + + /* 修改任务属性 */ + HILINK_SdkAttr *sdkAttr = HILINK_GetSdkAttr(); + if (sdkAttr == NULL) { + printf("sdkAttr is null"); + return -1; + } + sdkAttr->deviceMainTaskStackSize = 0x4000; + sdkAttr->otaCheckTaskStackSize = 0x3250; + sdkAttr->otaUpdateTaskStackSize = 0x3250; + HILINK_SetSdkAttr(*sdkAttr); + + return 0; +} +#endif \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_wifi_main.c b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_wifi_main.c new file mode 100755 index 0000000..afb207f --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/entry/hilink_wifi_main.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: HiLink SDK提供的demo示例代码(此文件为DEMO,需集成方适配修改) + */ +#include +#include +#include "hilink.h" +#include "hilink_device.h" +#include "cmsis_os2.h" +#include "hilink_socket_adapter.h" +#include "hilink_sal_defines.h" +#include "hal_reboot.h" +#include "hilink_device.h" +#include "hilink_network_adapter.h" + +#ifdef SUPPORT_QUICK_NETCFG +#include "hilink_quick_netcfg_demo.h" +#include "hilink_quick_netcfg_api.h" +#endif + +static int GetAcV2Func(unsigned char *acKey, unsigned int acLen) +{ + /* key文件在开发者平台获取 */ + return -1; +} + +static unsigned int GetWifiRecType(void) +{ + return (0x01 | 0x02); +} + +static int HardReboot(void) +{ + hal_reboot_chip(); + return 0; +} + +int hilink_wifi_main(void) +{ + /* 注册ACKey函数 */ + HILINK_RegisterGetAcV2Func(GetAcV2Func); + + /* 设置配网方式 */ + HILINK_SetNetConfigMode(HILINK_NETCONFIG_WIFI); + +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE + if (HILINK_RegisterErrnoCallback(get_os_errno) != 0) { + HILINK_SAL_NOTICE("reg errno cb err\r\n"); + return -1; + } +#endif + + /* 修改任务属性 */ + HILINK_SdkAttr *sdkAttr = HILINK_GetSdkAttr(); + if (sdkAttr == NULL) { + HILINK_SAL_NOTICE("sdkAttr is null"); + return -1; + } + sdkAttr->monitorTaskStackSize = 0x600; + sdkAttr->rebootHardware = HardReboot; + sdkAttr->rebootSoftware = HardReboot; + HILINK_SetSdkAttr(*sdkAttr); + +#ifdef SUPPORT_QUICK_NETCFG + HILINK_EnableQuickNetCfg(); +#endif + + /* 注册极简配网WIFI相关函数 */ + WiFiRecoveryApi wifiCb; + wifiCb.getWifiRecoveryType = GetWifiRecType; + wifiCb.scanAP = HILINK_ScanAP; + wifiCb.getAPScanResult = HILINK_GetAPScanResult; + wifiCb.restartWiFi = HILINK_RestartWiFi; + wifiCb.connectWiFiByBssid = HILINK_ConnectWiFiByBssid; + wifiCb.lastConnResult = HILINK_GetLastConnectResult; + if (HILINK_RegWiFiRecoveryCallback((const WiFiRecoveryApi *)&wifiCb, sizeof(wifiCb)) != 0) { + HILINK_SAL_NOTICE("reg wifi recovery failed!\r\n"); + return -1; + } + HILINK_SAL_NOTICE("RegWiFiRecoveryCallback finish!\n"); + + /* 启动Hilink SDK */ + if (HILINK_Main() != 0) { + HILINK_SAL_NOTICE("HILINK_Main start error"); + return -1; + } + +#ifdef SUPPORT_QUICK_NETCFG + StartQuickNetCfg(); +#endif + + return 0; +} diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/product/device_profile.h b/application/samples/wifi/ohos_connect/hilink_adapt/product/device_profile.h new file mode 100755 index 0000000..497c47a --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/product/device_profile.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: HiLink产品基本信息 + */ +#ifndef DEVICE_PROFILE_H +#define DEVICE_PROFILE_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* + * 设备基本信息根据设备实际情况填写 + * 与hilink sdk相同定义,双模组模式只需一份,已提供给第三方厂家,暂不按编程规范整改 + */ + + +#define ProductId "2PQP" +#define deviceTypeId "112" +#define manufacturerID "i0s" +#define deviceModel "SamSLE001" +#define configName "HuaweiSm" +#define configType "art Home" +#define enterpriseEnglishName "yuanxun" +#define brandEn "YX" +#define deviceName "SamSLETest" +#define productSeries "" + +#define DEVICE_HIVERSION "1.0.0" +/* 设备固件版本号 */ +#define FIRMWARE_VER "1.0.0" +/* 设备硬件版本号 */ +#define HARDWARE_VER "1.0.0" +/* 设备软件版本号 */ +#define SOFTWARE_VER HILINK_GetSdkVersion() + +/* 蓝牙sdk单独使用的定义 */ +#define SUB_PRODUCT_ID "00" +#define ADV_TX_POWER 0xF8 +#define BLE_ADV_TIME 10*60 + +/* 厂商自定义蓝牙广播,设备型号信息 */ +#define BT_CUSTOM_INFO "12345678" +#define DEVICE_MANU_ID "017" + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* DEVICE_PROFILE_H */ \ No newline at end of file diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.c b/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.c new file mode 100755 index 0000000..350fa32 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.c @@ -0,0 +1,479 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: HiLink产品适配实现源文件(此文件为DEMO,需集成方适配修改) + */ +#include "hilink_device.h" +#include +#include "hilink.h" +#include "securec.h" +#include "hilink_sal_defines.h" +#include "cJSON.h" +#include +#include "ble_cfg_net_api.h" +#include "cmsis_os2.h" +#include "device_profile.h" +#include "hsf.h" +#include "hilink_entry.h" + +/* + * + * 服务信息定义 + * 注意:(1)适配格式{svcType, svcId} + * (2)与devicepartner平台物模型定义必须保持一致 + */ +static const HILINK_SvcInfo SVC_INFO[] = { + { "switch", "switch" }, +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE + { "checkSum", "checkSum" }, +#endif +}; +int HILINK_GetDevInfo(HILINK_DevInfo *devinfo) +{ + if (devinfo == NULL) { + return -1; + } + int err = EOK; + err = strcpy_s(devinfo->sn, sizeof(devinfo->sn), hfget_hilink_sn()); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo sn: [%s]\r\n", hfget_hilink_sn()); + err = strcpy_s(devinfo->prodId, sizeof(devinfo->prodId), ProductId); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo prodId: [%s]\r\n", devinfo->prodId); + err = strcpy_s(devinfo->subProdId, sizeof(devinfo->subProdId), ""); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo subProdId: [%s]\r\n", devinfo->subProdId); + err = strcpy_s(devinfo->model, sizeof(devinfo->model), deviceModel); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo model: [%s]\r\n", devinfo->model); + err = strcpy_s(devinfo->devTypeId, sizeof(devinfo->devTypeId), deviceTypeId); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo devTypeId: [%s]\r\n", devinfo->devTypeId); + err = strcpy_s(devinfo->devTypeName, sizeof(devinfo->devTypeName), configName); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo devTypeName: [%s]\r\n", devinfo->devTypeName); + err = strcpy_s(devinfo->manuId, sizeof(devinfo->manuId), manufacturerID); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo manuId: [%s]\r\n", devinfo->manuId); + err = strcpy_s(devinfo->manuName, sizeof(devinfo->manuName), configType); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo manuName: [%s]\r\n", devinfo->manuName); +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE + err = sprintf_s(devinfo->fwv, sizeof(devinfo->fwv), "%s_%s", FIRMWARE_VER, SOFTWARE_VER); + if (err <= 0) { + HILINK_SAL_ERROR("sprintf_s err:%d\r\n", err); + return -1; + } +#else + err = strcpy_s(devinfo->fwv, sizeof(devinfo->fwv), FIRMWARE_VER); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } +#endif + HILINK_SAL_DEBUG("HILINK_GetDevInfo fwv: [%s]\r\n", devinfo->fwv); + err = strcpy_s(devinfo->hwv, sizeof(devinfo->hwv), HARDWARE_VER); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo hwv: [%s]\r\n", devinfo->hwv); + err = strcpy_s(devinfo->swv, sizeof(devinfo->swv), SOFTWARE_VER); + if (err != EOK) { + HILINK_SAL_ERROR("strcpy_s err:%d\r\n", err); + return -1; + } + HILINK_SAL_DEBUG("HILINK_GetDevInfo swv: [%s]\r\n", devinfo->swv); + return 0; +} + +int HILINK_GetSvcInfo(HILINK_SvcInfo *svcInfo[], unsigned int size) +{ + unsigned int svcNum = sizeof(SVC_INFO) / sizeof(HILINK_SvcInfo); + if ((svcInfo == NULL) || (size == 0) || (size < svcNum)) { + return -1; + } + + for (unsigned int i = 0; i < svcNum; ++i) { + if (memcpy_s(svcInfo[i], sizeof(HILINK_SvcInfo), &SVC_INFO[i], sizeof(HILINK_SvcInfo)) != EOK) { + return -1; + } + } + return svcNum; +} + +/* AC参数 */ +unsigned char A_C[48] = { + 0x66, 0x3F, 0x64, 0x78, 0x4B, 0x78, 0x3B, 0x26, 0x76, 0x78, 0x24, 0x56, 0x25, 0x2C, 0x57, 0x47, 0x6F, \ + 0xC8, 0xE7, 0xD6, 0xC6, 0xF2, 0x7F, 0x03, 0x3A, 0x1C, 0x78, 0x05, 0x66, 0x24, 0x5F, 0x09, 0xCD, 0xAD, \ + 0x30, 0x55, 0x2C, 0x19, 0x28, 0x34, 0x1A, 0xC3, 0x31, 0x49, 0x16, 0xC7, 0x45, 0x1B}; + +/* 获取加密 AC 参数 */ +unsigned char *HILINK_GetAutoAc(void) +{ + return A_C; +} + + +extern int HILINK_HILINK_Printf(const char *format, ...); + + +// 设备状态定义 +typedef struct{ + int switch_on; +}t_device_info; +// 分配一个对象记录设备状态 +static t_device_info g_device_info = {0}; + +// 服务处理函数定义 +typedef int (*handle_put_func)(const char* svc_id, const char* payload, unsigned int len); +typedef int (*handle_get_func)(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len); +// 服务注册信息定义 +typedef struct{ + // service id + char* sid; + // HILINK_PutCharState cmd function + handle_put_func putFunc; + // handle HILINK_GetCharState cmd function + handle_get_func getFunc; +} HANDLE_SVC_INFO; +//不支持 HILINK_PutCharState 时,默认实现 +int not_support_put(const char* svc_id, const char* payload, unsigned int len) +{ + HILINK_Printf("sid:%s NOT SUPPORT PUT function \r\n", svc_id); + return 0; +} +// 处理从 HILINK_PutCharState 传递过来的信息 +int handle_put_switch(const char* svc_id, const char* payload, unsigned int len) +{ + cJSON* pJson = cJSON_Parse(payload); + if (pJson == NULL){ + HILINK_Printf("JSON parse failed in PUT cmd: ID-%s \r\n", svc_id); + return -1; + } + cJSON* item = cJSON_GetObjectItem(pJson, "on"); + if (item != NULL) + g_device_info.switch_on = item->valueint; + if (pJson != NULL) + cJSON_Delete(pJson); + HILINK_Printf("handle func:%s, sid:%s \r\n", __FUNCTION__, svc_id); + return 0; +} +// 处理从 HILINK_GetCharState 传递过来的信息 +int handle_get_switch(const char* svc_id, const char* in, unsigned int in_len,char** out, unsigned int* out_len) +{ + *out_len = 20; + *out = (char*)malloc(*out_len); + if (NULL == *out) + return -1; + *out_len = sprintf_s(*out, *out_len, "{\"on\":%d}", g_device_info.switch_on); + HILINK_Printf("%s:%d svcId:%s, *out:%s\r\n",__FUNCTION__ , __LINE__,svc_id, *out); + return 0; +} +// 服务处理信息注册 +HANDLE_SVC_INFO g_device_profile[] = { + {"switch", handle_put_switch, handle_get_switch}, + // 故障不支持 HILINK_PutCharState,配置 not_support_put +}; +// 服务总数量 +int g_device_profile_count = sizeof(g_device_profile) / sizeof(HANDLE_SVC_INFO); + +// 辅助函数,用于查找服务注册信息 +static HANDLE_SVC_INFO* find_handle(const char* svc_id) +{ + for(int i = 0; i < g_device_profile_count; i++) { + HANDLE_SVC_INFO handle = g_device_profile[i]; + if(strcmp(handle.sid, svc_id) == 0) { + return &g_device_profile[i]; + } + } + return NULL; +} + +// 分发设备控制指令 +int handle_put_cmd(const char* svc_id, const char* payload, unsigned intlen) +{ + HANDLE_SVC_INFO* handle = find_handle(svc_id); + if(handle == NULL) { + HILINK_Printf("no service to handle put cmd : %s \r\n", svc_id); + return -1; + } + handle_put_func function = handle->putFunc; + if(function == NULL) { + HILINK_Printf("put function is null for %s \r\n", svc_id); + return -1; + } + return function(svc_id, payload, intlen); +} +// 分发服务查询直连 +int handle_get_cmd(const char* svc_id, const char* in, unsigned int in_len, char** out, unsigned int* out_len) +{ + HANDLE_SVC_INFO* handle = find_handle(svc_id); + if(handle == NULL) { + HILINK_Printf("no service to handle get cmd : %s \r\n", svc_id); + return -1; + } + handle_get_func function = handle->getFunc; + if(function == NULL) { + HILINK_Printf("get function is null for %s \r\n", svc_id); + return -1; + } + return function(svc_id, in, in_len, out,out_len); +} +// 快速上报函数,用于上报服务状态信息 +int fast_report(const char* svc_id) +{ + char* payload = NULL; + int len; + int err = handle_get_cmd(svc_id, NULL, 0, &payload, (unsigned int *)&len); + if(err != 0) { + HILINK_Printf("get msg from %s failed \r\n", svc_id); + return err; + } + err = HILINK_ReportCharState(svc_id, payload, len); + HILINK_Printf("report %s result is %d \r\n", svc_id, err); + return err; +} +/* + * 修改服务当前字段值 + * svcId为服务的ID,payload为接收到需要修改的Json格式的字段与其值,len为payload的长度 + * 返回0表示服务状态值修改成功,不需要底层设备主动上报,由Hilink Device SDK上报; + * 返回-101表示获得报文不符合要求; + * 返回-111表示服务状态值正在修改中,修改成功后底层设备必须主动上报; + */ +int HILINK_PutCharState(const char *svcId, const char *payload, unsigned int len) +{ + if ((svcId == NULL) || (payload == NULL)) { + return -1; + } + + cJSON *json = cJSON_Parse(payload); + if (json == NULL) { + return -1; + } + int err = handle_put_cmd(svcId, payload, len); + return err; +} +#ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE +static int GetFwvCheckSum(char **out, unsigned int *outLen) +{ + char fwvCheckSum[65] = { 0 }; + unsigned int size = sizeof(fwvCheckSum); + int ret = read_app_bin_hash(fwvCheckSum, &size); + if (ret < 0) { + HILINK_SAL_NOTICE("GetFwvCheckSum get fwv checksum ret:%d\r\n", ret); + return -1; + } + unsigned int mallocLen = 128; + char *newData = (char *)malloc(mallocLen); + if (newData == NULL) { + HILINK_SAL_NOTICE("GetFwvCheckSum malloc fail\r\n"); + return -1; + } + ret = sprintf_s(newData, mallocLen, "{\"checkSum\": \"%s\"}", fwvCheckSum); + if (ret <= 0) { + free(newData); + HILINK_SAL_NOTICE("GetFwvCheckSum snHILINK_Printf_s ret:%d\r\n", ret); + return -1; + } + *out = newData; + *outLen = ret; + return 0; +} +#endif +/* + * 添加单设备多服务批控服务接口 + * 1.使用场景:单产品需要在一个报文包中包含多个服务同时处理 + * 2.使用方法: + * (1)厂商需要编写支持批控的H5页面,增加type = 4以及在action中可以包含一个或者以上的服务。 + * (2)厂商需要通过HILINK_EnableBatchControl(bool flag)接口打开或关闭批量功能,当前默认关闭。 + * 3.使用约束: + * (1)payload为接收到报文的actions内容,为数组格式,len为actions内容的长度;详情请参考《指南》 + * (2)返回值判断: + * 返回0表示服务状态值修改成功,不需要底层设备主动上报,由HiLink SDK上报; + * 返回-101表示获得报文不符合要求; + * 返回-111表示服务状态值正在修改中; + */ +int HILINK_ControlCharState(const char *payload, unsigned int len) +{ + return 0; +} + +/* + * 获取服务字段值 + * svcId表示服务ID。厂商实现该函数时,需要对svcId进行判断; + * in表示接收到的Json格式的字段与其值; + * inLen表示接收到的in的长度; + * out表示保存服务字段值内容的指针,内存由厂商开辟,使用完成后,由Hilink Device SDK释放; + * outLen表示读取到的payload的长度; + * 返回0表示服务状态字段值获取成功,返回非0表示获取服务状态字段值不成功。 + */ +int HILINK_GetCharState(const char *svcId, const char *in, unsigned int inLen, char **out, unsigned int *outLen) +{ + if ((svcId == NULL) || (out == NULL) || (outLen == NULL)) + { + return -1; + } + #ifdef CONFIG_SUPPORT_HILINK_INDIE_UPGRADE + if (strcmp(svcId, "checkSum") == 0) { + return GetFwvCheckSum(out, outLen); + } + #endif + int err = handle_get_cmd(svcId, in, inLen, out, outLen); + return err; +} + +/* + * 功能: 获取SoftAp配网PIN码 + * 返回: 返回10000000到99999999之间的8位数字PIN码, 返回-1表示使用HiLink SDK的默认PIN码 + * 注意: (1)安全认证要求,PIN码不能由sn、mac等设备固定信息生成 + * (2)该接口实现需要与devicepartner平台匹配 + */ +int HILINK_GetPinCode(void) +{ + return -1; +} + +/* + * 通知设备的状态 + * status表示设备当前的状态 + * 注意,此函数由设备厂商根据产品业务选择性实现 + * 注意: (1) 此函数由设备厂商根据产品业务选择性实现 + * (2) 禁止在HILINK_NotifyDevStatus接口内回调HiLink SDK的对外接口 + */ +void HILINK_NotifyDevStatus(int status) +{ + HILINK_SAL_DEBUG("HILINK_NotifyDevStatus status: %d\r\n", status); + switch (status) { + case HILINK_M2M_CLOUD_OFFLINE: + /* 设备与云端连接断开,请在此处添加实现 */ +#if defined(SUPPORT_MINIMALIST_NETCFG) || defined(SUPPORT_BLE_ANCILLAY_NETCFG) + BLE_CfgNetAdvUpdate(NULL); + BLE_CfgNetAdvCtrl(0); + (void)BLE_CfgNetAdvCtrl(0xFFFFFFFF); +#endif + break; + case HILINK_M2M_CLOUD_ONLINE: + /* 设备连接云端成功,请在此处添加实现 */ +#if defined(SUPPORT_MINIMALIST_NETCFG) || defined(SUPPORT_BLE_ANCILLAY_NETCFG) + BLE_CfgNetAdvUpdate(NULL); + BLE_CfgNetAdvCtrl(0); + (void)BLE_CfgNetAdvCtrl(0xFFFFFFFF); +#endif + break; + case HILINK_M2M_LONG_OFFLINE: + /* 设备与云端连接长时间断开,请在此处添加实现 */ + break; + case HILINK_M2M_LONG_OFFLINE_REBOOT: + /* 设备与云端连接长时间断开后进行重启,请在此处添加实现 */ + HILINK_SAL_DEBUG("device offline long time reboot\r\n"); + break; + case HILINK_UNINITIALIZED: + /* HiLink线程未启动,请在此处添加实现 */ + break; + case HILINK_LINK_UNDER_AUTO_CONFIG: + /* 设备处于配网模式,请在此处添加实现 */ + break; + case HILINK_LINK_CONFIG_TIMEOUT: + /* 设备处于10分钟超时状态,请在此处添加实现 */ + break; + case HILINK_LINK_CONNECTTING_WIFI: + /* 设备正在连接路由器,请在此处添加实现 */ + break; + case HILINK_LINK_CONNECTED_WIFI: + /* 设备已经连上路由器,请在此处添加实现 */ + hf_set_wifi_state(1); + break; + case HILINK_M2M_CONNECTTING_CLOUD: + /* 设备正在连接云端,请在此处添加实现 */ + break; + case HILINK_LINK_DISCONNECT: + /* 设备与路由器的连接断开,请在此处添加实现 */ + hf_set_wifi_state(0); + break; + case HILINK_DEVICE_REGISTERED: + /* 设备被注册,请在此处添加实现 */ + break; + case HILINK_DEVICE_UNREGISTER: + /* 设备被解绑,请在此处添加实现 */ + break; + case HILINK_REVOKE_FLAG_SET: + /* 设备被复位标记置位,请在此处添加实现 */ + break; + case HILINK_NEGO_REG_INFO_FAIL: + /* 设备协商配网信息失败 */ + break; + case HILINK_LINK_CONNECTED_FAIL: + /* 设备与路由器的连接失败 */ + break; + case HILINK_CLOUD_TO_CENTRAL: + /* 直连云模式切成中枢模式 */ + break; + case HILINK_DEVICE_CLEAN: + /* 设备完全清除,包括前装跟后装信息 */ + break; + default: + break; + } + + return; +} + + /* + * 功能:实现模组重启前的设备操作 + * 参数:flag 入参,触发重启的类型 + * 0表示HiLink SDK 线程看门狗触发模组重启; + * 1表示APP删除设备触发模组重启; + * 2表示设备长时间离线无法恢复而重启; + * 返回值:0表示处理成功, 系统可以重启,使用硬重启; + * 1表示处理成功, 系统可以重启,如果通过HILINK_SetSdkAttr()注册了软重启(sdkAttr.rebootSoftware),使用软重启; + * 负值表示处理失败,系统不能重启 + * 注意:(1) 此函数由设备厂商实现; + * (2) 若APP删除设备触发模组重启时,设备操作完务必返回0,否则会导致删除设备异常; + * (3) 设备长时间离线无法恢复而重启,应对用户无感,不可影响用户体验,否则不可以重启; + */ +int HILINK_ProcessBeforeRestart(int flag) +{ + /* HiLink SDK线程看门狗超时触发模组重启 */ + if (flag == 0) { + /* 实现模组重启前的操作(如:保存系统状态等) */ + return 1; + } + + /* APP删除设备触发模组重启 */ + if (flag == 1) { + /* 实现模组重启前的操作(如:保存系统状态等) */ + return 1; + } + + /* 设备长时间离线触发模组重启,尝试恢复网络 */ + if (flag == 2) { + /* 实现模组重启前的操作(如:保存系统状态等) */ + return 1; + } + + return -1; +} diff --git a/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.h b/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.h new file mode 100755 index 0000000..cbfcd84 --- /dev/null +++ b/application/samples/wifi/ohos_connect/hilink_adapt/product/hilink_device.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. + * Description: HiLink产品适配头文件(此文件为DEMO,需集成方适配修改) + */ +#ifndef HILINK_DEVICE_H +#define HILINK_DEVICE_H + +#include "hilink.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef struct { + char sn[40]; /* 设备唯一标识,比如sn号,有效字符长度范围[0,40),为空时使用MAC地址作为SN */ + char prodId[5]; /* 设备产品ID,有效字符长度为4 */ + char subProdId[3]; /* 设备子型号,有效字符长度为0或2 */ + char model[32]; /* 设备型号,长度范围[0,32) */ + char devTypeId[4]; /* 设备类型ID,有效字符长度为3 */ + char devTypeName[32]; /* 设备类型英文名称,长度范围[0,32) */ + char manuId[4]; /* 设备制造商ID,有效字符长度为3 */ + char manuName[32]; /* 设备制造商英文名称,长度范围[0,32) */ + char fwv[64]; /* 设备固件版本,长度范围[0,64) */ + char hwv[64]; /* 设备硬件版本,长度范围[0,64) */ + char swv[64]; /* 设备软件版本,长度范围[0,64) */ +} HILINK_DevInfo; + +typedef struct { + char svcType[32]; /* 服务类型,字符长度范围(0, 32) */ + char svcId[64]; /* 服务ID,字符长度范围(0, 64) */ +} HILINK_SvcInfo; + +enum HILINK_StateMachine { + /* 设备与云端连接断开(版本向前兼容) */ + HILINK_M2M_CLOUD_OFFLINE = 0, + /* 设备连接云端成功,处于正常工作态(版本向前兼容) */ + HILINK_M2M_CLOUD_ONLINE, + /* 设备与云端连接长时间断开(版本向前兼容) */ + HILINK_M2M_LONG_OFFLINE, + /* 设备与云端连接长时间断开后进行重启(版本向前兼容) */ + HILINK_M2M_LONG_OFFLINE_REBOOT, + /* HiLink线程未启动 */ + HILINK_UNINITIALIZED, + /* 设备处于配网模式 */ + HILINK_LINK_UNDER_AUTO_CONFIG, + /* 设备处于10分钟超时状态 */ + HILINK_LINK_CONFIG_TIMEOUT, + /* 设备正在连接路由器 */ + HILINK_LINK_CONNECTTING_WIFI, + /* 设备已经连上路由器 */ + HILINK_LINK_CONNECTED_WIFI, + /* 设备正在连接云端 */ + HILINK_M2M_CONNECTTING_CLOUD, + /* 设备与路由器的连接断开 */ + HILINK_LINK_DISCONNECT, + /* 设备被注册 */ + HILINK_DEVICE_REGISTERED, + /* 设备被解绑 */ + HILINK_DEVICE_UNREGISTER, + /* 设备复位标记置位 */ + HILINK_REVOKE_FLAG_SET, + /* 设备协商注册信息失败 */ + HILINK_NEGO_REG_INFO_FAIL, + /* 设备与路由器的连接失败 */ + HILINK_LINK_CONNECTED_FAIL, + /* 打开中枢模式成功 */ + HILINK_OPEN_CENTRAL_MODE_OK, + /* 打开中枢模式失败 */ + HILINK_OPEN_CENTRAL_MODE_FAILE, + /* 本地端口创建成功 */ + HILINK_CREATE_CENTRAL_PORT_OK, + /* 设备恢复交房标记 */ + HILINK_RECOVER_HANDOVER, + /* 设备交房标记 */ + HILINK_HANDOVER, + /* 设备已初始化 */ + HILINK_INITIALIZED, + /* 直连云模式切成中枢模式 */ + HILINK_CLOUD_TO_CENTRAL, + /* 设备信息完全清除,包括前装跟后装信息 */ + HILINK_DEVICE_CLEAN, + /* 共部署设备被设置为单品模式 */ + HILINK_DEVICE_MODE, + /* 设备TLS链路重连事件 */ + HILINK_TLS_LINK_RECONNECTED, +}; + +typedef int (*HILINK_GetAcKeyFunc)(unsigned char *acKey, unsigned int acLen); + +/* + * 功能:注册获取ACkeyV2函数,key文件在开发者平台获取 + * 参数:HILINK_GetAcKeyFun 入参 + * 备注,SDK优先使用ACkeyV2,HILINK_GetAutoAc逐渐日落。 + */ +void HILINK_RegisterGetAcV2Func(HILINK_GetAcKeyFunc func); + +/* + * 功能:获取设备信息 + * 参数:devinfo 出入参,待填充的设备信息 + * 返回:获取成功返回 0,否则返-1 + * 注意:(1) sn不填充时将使用设备mac地址作为sn。 + * (2) 如果产品定义有子型号则需要填充subProdId。 + * (3) 所有需要填充的字段都需要以'\0'结束。 + * (4) softap配网时devTypeName与manuName用来拼接ssid,两个字段长度和尽量不超过10字节,否则会截断。 + */ +int HILINK_GetDevInfo(HILINK_DevInfo *devinfo); + +/* + * 功能:获取设备服务信息 + * 参数:(1) svcInfo 出入参,待填充的设备服务信息结构体指针数组。 + * (2) size 入参,svcInfo结构体指针数组大小。 + * 返回:获取成功返回服务数量,否则返-1。 + * 注意:所有需要填充的字段都需要以'\0'结束。 + */ +int HILINK_GetSvcInfo(HILINK_SvcInfo *svcInfo[], unsigned int size); + +/* 获取AC 参数接口函数 */ +unsigned char *HILINK_GetAutoAc(void); + +/* + * 修改服务当前字段值 + * svcId为服务的ID,payload为接收到需要修改的Json格式的字段与其值,len为payload的长度。 + * 返回0表示该次控制为同步上报,由HILINK SDK上报。 + * 返回-111表示该次控制为异步上报,修改成功后设备必须调用HILINK_ReportCharState主动上报。 + * 其余返回值均为错误值,HILINK SDK不会上报任何信息。 + */ +int HILINK_PutCharState(const char *svcId, const char *payload, unsigned int len); + +/* + * 功能:单设备多服务批控接口 + * 参数:payload为Json格式的报文内容(数组格式),len为payload的长度,例如: + * [ + * {"sid": "switch", "data":{"on": 1}}, + * {"sid": "brightness","data": {"brightness": 20}} + * ] + * 返回值:0表示服务状态值修改成功,不需要底层设备主动上报,由HiLink SDK上报。 + * -101表示获得报文不符合要求。 + * -111表示服务状态值正在修改中。 + * 注意:(1) 此函数由设备厂商实现。 + * (2) 厂商需通过HILINK_EnableBatchControl(bool flag)接口打开或关闭批量控制功能,默认关闭。 + */ +int HILINK_ControlCharState(const char *payload, unsigned int len); + +/* + * 获取服务字段值 + * svcId表示服务ID。厂商实现该函数时,需要对svcId进行判断。 + * in表示接收到的Json格式的字段与其值。 + * inLen表示接收到的in的长度。 + * out表示保存服务字段值内容的指针,内存由厂商开辟,使用完成后,由Hilink Device SDK释放,需要以'\0'结尾,并保证内容符合json格式。 + * outLen表示读取到的payload的长度。 + * 返回0表示服务状态字段值获取成功,返回非0表示获取服务状态字段值不成功。 + */ +int HILINK_GetCharState(const char *svcId, const char *in, unsigned int inLen, char **out, unsigned int *outLen); + +/* + * 获取SoftAp配网PIN码 + * 返回值为8位数字PIN码, 返回-1表示使用HiLink SDK的默认PIN码。 + * 该接口需设备开发者实现。 + * 安全认证要求,PIN码不能由sn、mac等设备固定信息生成。 + */ +int HILINK_GetPinCode(void); + +/* + * 通知设备的状态 + * status表示设备当前的状态 + * 注意: (1) 此函数由设备厂商根据产品业务选择性实现。 + * (2) 禁止在HILINK_NotifyDevStatus接口内回调HiLink SDK的对外接口。 + */ +void HILINK_NotifyDevStatus(int status); + + /* + * 功能:实现模组重启前的设备操作 + * 参数:flag 入参,触发重启的类型 + * 0表示HiLink SDK 线程看门狗触发模组重启。 + * 1表示APP删除设备触发模组重启。 + * 2表示设备长时间离线无法恢复而重启。 + 3表示网关定时重启。 + * 返回值:0表示处理成功, 系统可以重启,使用硬重启。 + * 1表示处理成功, 系统可以重启,如果通过HILINK_SetSdkAttr()注册了软重启(sdkAttr.rebootSoftware),使用软重启。 + * 负值表示处理失败,系统不能重启。 + * 注意:(1) 此函数由设备厂商实现。 + * (2) 若APP删除设备触发模组重启时,设备操作完务必返回0,否则会导致删除设备异常。 + * (3) 设备长时间离线无法恢复而重启,应对用户无感,不可影响用户体验,否则不可以重启。 + */ +int HILINK_ProcessBeforeRestart(int flag); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* HILINK_DEVICE_H */ \ No newline at end of file diff --git a/application/samples/wifi/softap_sample/CMakeLists.txt b/application/samples/wifi/softap_sample/CMakeLists.txt new file mode 100755 index 0000000..9e4b647 --- /dev/null +++ b/application/samples/wifi/softap_sample/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/softap_sample.c" PARENT_SCOPE) diff --git a/application/samples/wifi/softap_sample/softap_sample.c b/application/samples/wifi/softap_sample/softap_sample.c new file mode 100755 index 0000000..53c9329 --- /dev/null +++ b/application/samples/wifi/softap_sample/softap_sample.c @@ -0,0 +1,121 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * + * Description: Application core main function for standard \n + * + * History: \n + * 2022-07-27, Create file. \n + */ + +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "td_base.h" +#include "td_type.h" +#include "stdlib.h" +#include "uart.h" +#include "cmsis_os2.h" +#include "app_init.h" +#include "soc_osal.h" + +#define WIFI_IFNAME_MAX_SIZE 16 +#define WIFI_MAX_KEY_LEN 65 +#define WIFI_MAX_SSID_LEN 33 +#define WIFI_SOFTAP_SAMPLE_LOG "[WIFI_SOFTAP_SAMPLE]" + +#define WIFI_TASK_PRIO (osPriority_t)(13) +#define WIFI_TASK_DURATION_MS 2000 +#define WIFI_TASK_STACK_SIZE 0x1000 +/***************************************************************************** + SoftAP sample用例 +*****************************************************************************/ +td_s32 example_softap_function(td_void) +{ + /* SoftAp接口的信息 */ + td_char ssid[WIFI_MAX_SSID_LEN] = "my_softAP"; + td_char pre_shared_key[WIFI_MAX_KEY_LEN] = "my_password"; + softap_config_stru hapd_conf = {0}; + softap_config_advance_stru config = {0}; + td_char ifname[WIFI_IFNAME_MAX_SIZE + 1] = "ap0"; /* 创建的SoftAp接口名 */ + struct netif *netif_p = TD_NULL; + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + IP4_ADDR(&st_ipaddr, 192, 168, 43, 1); /* IP地址设置:192.168.43.1 */ + IP4_ADDR(&st_netmask, 255, 255, 255, 0); /* 子网掩码设置:255.255.255.0 */ + IP4_ADDR(&st_gw, 192, 168, 43, 2); /* 网关地址设置:192.168.43.2 */ + + /* 配置SoftAp基本参数 */ + (td_void)memcpy_s(hapd_conf.ssid, sizeof(hapd_conf.ssid), ssid, sizeof(ssid)); + (td_void)memcpy_s(hapd_conf.pre_shared_key, WIFI_MAX_KEY_LEN, pre_shared_key, WIFI_MAX_KEY_LEN); + hapd_conf.security_type = 3; /* 3: 加密方式设置为WPA_WPA2_PSK */ + hapd_conf.channel_num = 13; /* 13:工作信道设置为13信道 */ + hapd_conf.wifi_psk_type = 0; + + /* 配置SoftAp网络参数 */ + config.beacon_interval = 100; /* 100:Beacon周期设置为100ms */ + config.dtim_period = 2; /* 2:DTIM周期设置为2 */ + config.gi = 0; /* 0:short GI默认关闭 */ + config.group_rekey = 86400; /* 86400:组播秘钥更新时间设置为1天 */ + config.protocol_mode = 4; /* 4:协议类型设置为802.11b + 802.11g + 802.11n + 802.11ax */ + config.hidden_ssid_flag = 1; /* 1:不隐藏SSID */ + if (wifi_set_softap_config_advance(&config) != 0) { + return -1; + } + /* 启动SoftAp接口 */ + if (wifi_softap_enable(&hapd_conf) != 0) { + return -1; + } + /* 配置DHCP服务器 */ + netif_p = netif_find(ifname); + if (netif_p == TD_NULL) { + (td_void)wifi_softap_disable(); + return -1; + } + if (netifapi_netif_set_addr(netif_p, &st_ipaddr, &st_netmask, &st_gw) != 0) { + (td_void)wifi_softap_disable(); + return -1; + } + if (netifapi_dhcps_start(netif_p, NULL, 0) != 0) { + (td_void)wifi_softap_disable(); + return -1; + } + PRINT("%s::SoftAp start success.\r\n", WIFI_SOFTAP_SAMPLE_LOG); + return 0; +} + +int softap_sample_init(void *param) +{ + param = param; + + /* 等待wifi初始化完成 */ + while (wifi_is_wifi_inited() == 0) { + (void)osDelay(10); /* 1: 等待100ms后判断状态 */ + } + PRINT("%s::wifi init succ.\r\n", WIFI_SOFTAP_SAMPLE_LOG); + + if (example_softap_function() != 0) { + PRINT("%s::example_softap_function fail.\r\n", WIFI_SOFTAP_SAMPLE_LOG); + return -1; + } + return 0; +} + +static void softap_sample_entry(void) +{ + osThreadAttr_t attr; + attr.name = "softap_sample_task"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = WIFI_TASK_STACK_SIZE; + attr.priority = WIFI_TASK_PRIO; + if (osThreadNew((osThreadFunc_t)softap_sample_init, NULL, &attr) == NULL) { + PRINT("%s::Create softap_sample_task fail.\r\n", WIFI_SOFTAP_SAMPLE_LOG); + } + PRINT("%s::Create softap_sample_task succ.\r\n", WIFI_SOFTAP_SAMPLE_LOG); +} + +/* Run the sta_sample_task. */ +app_run(softap_sample_entry); \ No newline at end of file diff --git a/application/samples/wifi/sta_sample/CMakeLists.txt b/application/samples/wifi/sta_sample/CMakeLists.txt new file mode 100755 index 0000000..1e414ef --- /dev/null +++ b/application/samples/wifi/sta_sample/CMakeLists.txt @@ -0,0 +1,5 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== +set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/sta_sample.c" PARENT_SCOPE) diff --git a/application/samples/wifi/sta_sample/sta_sample.c b/application/samples/wifi/sta_sample/sta_sample.c new file mode 100755 index 0000000..a8249ed --- /dev/null +++ b/application/samples/wifi/sta_sample/sta_sample.c @@ -0,0 +1,279 @@ +/** + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * + * Description: Application core main function for standard \n + * + * History: \n + * 2022-07-27, Create file. \n + */ + +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "td_base.h" +#include "td_type.h" +#include "stdlib.h" +#include "uart.h" +#include "cmsis_os2.h" +#include "app_init.h" +#include "soc_osal.h" + +#define WIFI_IFNAME_MAX_SIZE 16 +#define WIFI_MAX_SSID_LEN 33 +#define WIFI_SCAN_AP_LIMIT 64 +#define WIFI_MAC_LEN 6 +#define WIFI_STA_SAMPLE_LOG "[WIFI_STA_SAMPLE]" +#define WIFI_NOT_AVALLIABLE 0 +#define WIFI_AVALIABE 1 +#define WIFI_GET_IP_MAX_COUNT 300 + +#define WIFI_TASK_PRIO (osPriority_t)(13) +#define WIFI_TASK_DURATION_MS 2000 +#define WIFI_TASK_STACK_SIZE 0x1000 + +static td_void wifi_scan_state_changed(td_s32 state, td_s32 size); +static td_void wifi_connection_changed(td_s32 state, const wifi_linked_info_stru *info, td_s32 reason_code); + +wifi_event_stru wifi_event_cb = { + .wifi_event_connection_changed = wifi_connection_changed, + .wifi_event_scan_state_changed = wifi_scan_state_changed, +}; + +enum { + WIFI_STA_SAMPLE_INIT = 0, /* 0:初始态 */ + WIFI_STA_SAMPLE_SCANING, /* 1:扫描中 */ + WIFI_STA_SAMPLE_SCAN_DONE, /* 2:扫描完成 */ + WIFI_STA_SAMPLE_FOUND_TARGET, /* 3:匹配到目标AP */ + WIFI_STA_SAMPLE_CONNECTING, /* 4:连接中 */ + WIFI_STA_SAMPLE_CONNECT_DONE, /* 5:关联成功 */ + WIFI_STA_SAMPLE_GET_IP, /* 6:获取IP */ +} wifi_state_enum; + +static td_u8 g_wifi_state = WIFI_STA_SAMPLE_INIT; + +/***************************************************************************** + STA 扫描事件回调函数 +*****************************************************************************/ +static td_void wifi_scan_state_changed(td_s32 state, td_s32 size) +{ + UNUSED(state); + UNUSED(size); + PRINT("%s::Scan done!.\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_SCAN_DONE; + return; +} + +/***************************************************************************** + STA 关联事件回调函数 +*****************************************************************************/ +static td_void wifi_connection_changed(td_s32 state, const wifi_linked_info_stru *info, td_s32 reason_code) +{ + UNUSED(info); + UNUSED(reason_code); + + if (state == WIFI_NOT_AVALLIABLE) { + PRINT("%s::Connect fail!. try agin !\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_INIT; + } else { + PRINT("%s::Connect succ!.\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_CONNECT_DONE; + } +} + +/***************************************************************************** + STA 匹配目标AP +*****************************************************************************/ +td_s32 example_get_match_network(wifi_sta_config_stru *expected_bss) +{ + td_s32 ret; + td_u32 num = 64; /* 64:扫描到的Wi-Fi网络数量 */ + td_char expected_ssid[] = "my_softAP"; + td_char key[] = "my_password"; /* 待连接的网络接入密码 */ + td_bool find_ap = TD_FALSE; + td_u8 bss_index; + /* 获取扫描结果 */ + td_u32 scan_len = sizeof(wifi_scan_info_stru) * WIFI_SCAN_AP_LIMIT; + wifi_scan_info_stru *result = osal_kmalloc(scan_len, OSAL_GFP_ATOMIC); + if (result == TD_NULL) { + return -1; + } + memset_s(result, scan_len, 0, scan_len); + ret = wifi_sta_get_scan_info(result, &num); + if (ret != 0) { + osal_kfree(result); + return -1; + } + /* 筛选扫描到的Wi-Fi网络,选择待连接的网络 */ + for (bss_index = 0; bss_index < num; bss_index ++) { + if (strlen(expected_ssid) == strlen(result[bss_index].ssid)) { + if (memcmp(expected_ssid, result[bss_index].ssid, strlen(expected_ssid)) == 0) { + find_ap = TD_TRUE; + break; + } + } + } + /* 未找到待连接AP,可以继续尝试扫描或者退出 */ + if (find_ap == TD_FALSE) { + osal_kfree(result); + return -1; + } + /* 找到网络后复制网络信息和接入密码 */ + if (memcpy_s(expected_bss->ssid, WIFI_MAX_SSID_LEN, expected_ssid, strlen(expected_ssid)) != 0) { + osal_kfree(result); + return -1; + } + if (memcpy_s(expected_bss->bssid, WIFI_MAC_LEN, result[bss_index].bssid, WIFI_MAC_LEN) != 0) { + osal_kfree(result); + return -1; + } + expected_bss->security_type = result[bss_index].security_type; + if (memcpy_s(expected_bss->pre_shared_key, WIFI_MAX_SSID_LEN, key, strlen(key)) != 0) { + osal_kfree(result); + return -1; + } + expected_bss->ip_type = 1; /* 1:IP类型为动态DHCP获取 */ + osal_kfree(result); + return 0; +} + +/***************************************************************************** + STA 关联状态查询 +*****************************************************************************/ +td_bool example_check_connect_status(td_void) +{ + td_u8 index; + wifi_linked_info_stru wifi_status; + /* 获取网络连接状态,共查询5次,每次间隔500ms */ + for (index = 0; index < 5; index ++) { + (void)osDelay(50); /* 50: 延时500ms */ + memset_s(&wifi_status, sizeof(wifi_linked_info_stru), 0, sizeof(wifi_linked_info_stru)); + if (wifi_sta_get_ap_info(&wifi_status) != 0) { + continue; + } + if (wifi_status.conn_state == 1) { + return 0; /* 连接成功退出循环 */ + } + } + return -1; +} + +/***************************************************************************** + STA DHCP状态查询 +*****************************************************************************/ +td_bool example_check_dhcp_status(struct netif *netif_p, td_u32 *wait_count) +{ + if ((ip_addr_isany(&(netif_p->ip_addr)) == 0) && (*wait_count <= WIFI_GET_IP_MAX_COUNT)) { + /* DHCP成功 */ + PRINT("%s::STA DHCP success.\r\n", WIFI_STA_SAMPLE_LOG); + return 0; + } + + if (*wait_count > WIFI_GET_IP_MAX_COUNT) { + PRINT("%s::STA DHCP timeout, try again !.\r\n", WIFI_STA_SAMPLE_LOG); + *wait_count = 0; + g_wifi_state = WIFI_STA_SAMPLE_INIT; + } + return -1; +} + +td_s32 example_sta_function(td_void) +{ + td_char ifname[WIFI_IFNAME_MAX_SIZE + 1] = "wlan0"; /* 创建的STA接口名 */ + wifi_sta_config_stru expected_bss = {0}; /* 连接请求信息 */ + struct netif *netif_p = TD_NULL; + td_u32 wait_count = 0; + + /* 创建STA接口 */ + if (wifi_sta_enable() != 0) { + return -1; + } + PRINT("%s::STA enable succ.\r\n", WIFI_STA_SAMPLE_LOG); + + do { + (void)osDelay(1); /* 1: 等待10ms后判断状态 */ + if (g_wifi_state == WIFI_STA_SAMPLE_INIT) { + PRINT("%s::Scan start!\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_SCANING; + /* 启动STA扫描 */ + if (wifi_sta_scan() != 0) { + g_wifi_state = WIFI_STA_SAMPLE_INIT; + continue; + } + } else if (g_wifi_state == WIFI_STA_SAMPLE_SCAN_DONE) { + /* 获取待连接的网络 */ + if (example_get_match_network(&expected_bss) != 0) { + PRINT("%s::Do not find AP, try again !\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_INIT; + continue; + } + g_wifi_state = WIFI_STA_SAMPLE_FOUND_TARGET; + } else if (g_wifi_state == WIFI_STA_SAMPLE_FOUND_TARGET) { + PRINT("%s::Connect start.\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_CONNECTING; + /* 启动连接 */ + if (wifi_sta_connect(&expected_bss) != 0) { + g_wifi_state = WIFI_STA_SAMPLE_INIT; + continue; + } + } else if (g_wifi_state == WIFI_STA_SAMPLE_CONNECT_DONE) { + PRINT("%s::DHCP start.\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_GET_IP; + netif_p = netifapi_netif_find(ifname); + if (netif_p == TD_NULL || netifapi_dhcp_start(netif_p) != 0) { + PRINT("%s::find netif or start DHCP fail, try again !\r\n", WIFI_STA_SAMPLE_LOG); + g_wifi_state = WIFI_STA_SAMPLE_INIT; + continue; + } + } else if (g_wifi_state == WIFI_STA_SAMPLE_GET_IP) { + if (example_check_dhcp_status(netif_p, &wait_count) == 0) { + break; + } + wait_count++; + } + } while (1); + + return 0; +} + +int sta_sample_init(void *param) +{ + param = param; + + /* 注册事件回调 */ + if (wifi_register_event_cb(&wifi_event_cb) != 0) { + PRINT("%s::wifi_event_cb register fail.\r\n", WIFI_STA_SAMPLE_LOG); + return -1; + } + PRINT("%s::wifi_event_cb register succ.\r\n", WIFI_STA_SAMPLE_LOG); + + /* 等待wifi初始化完成 */ + while (wifi_is_wifi_inited() == 0) { + (void)osDelay(10); /* 1: 等待100ms后判断状态 */ + } + PRINT("%s::wifi init succ.\r\n", WIFI_STA_SAMPLE_LOG); + + if (example_sta_function() != 0) { + PRINT("%s::example_sta_function fail.\r\n", WIFI_STA_SAMPLE_LOG); + return -1; + } + return 0; +} + +static void sta_sample_entry(void) +{ + osThreadAttr_t attr; + attr.name = "sta_sample_task"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = WIFI_TASK_STACK_SIZE; + attr.priority = WIFI_TASK_PRIO; + if (osThreadNew((osThreadFunc_t)sta_sample_init, NULL, &attr) == NULL) { + PRINT("%s::Create sta_sample_task fail.\r\n", WIFI_STA_SAMPLE_LOG); + } + PRINT("%s::Create sta_sample_task succ.\r\n", WIFI_STA_SAMPLE_LOG); +} + +/* Run the sta_sample_task. */ +app_run(sta_sample_entry); \ No newline at end of file diff --git a/application/ws63/CMakeLists.txt b/application/ws63/CMakeLists.txt new file mode 100755 index 0000000..0109faf --- /dev/null +++ b/application/ws63/CMakeLists.txt @@ -0,0 +1,14 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== +add_subdirectory_if_exist(ws63_liteos_application) +add_subdirectory_if_exist(hsf) +add_subdirectory_if_exist(user_main) +add_subdirectory_if_exist(ws63_liteos_testsuite) +add_subdirectory_if_exist(ws63_freertos_application) +add_subdirectory_if_exist(ws63_freertos_testsuite) +add_subdirectory_if_exist(ws63_alios_application) +add_subdirectory_if_exist(ws63_alios_testsuite) +add_subdirectory_if_exist(ws63_ate) +add_subdirectory_if_exist(ws63_liteos_mfg) \ No newline at end of file diff --git a/application/ws63/hsf/CMakeLists.txt b/application/ws63/hsf/CMakeLists.txt new file mode 100755 index 0000000..ecba4a9 --- /dev/null +++ b/application/ws63/hsf/CMakeLists.txt @@ -0,0 +1,145 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) ShangHai High-flying Electronics Technology Co.,Ltd 2022-2022. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "hsf") + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/hfsys.c +) + +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR} +) + +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES + CONFIG_SUPPORT_WIFI_APSTA +) + +set(PUBLIC_DEFINES +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS #当前组件需要对外提供的编译选项 + #-Wno-error=maybe-uninitialized #变量未初始化 + #-Wno-error=pointer-sign #传递参数类型不匹配 + #-Wno-error=char-subscripts #使用char类作为数组下标,char有符号 + #-Wno-error=unused-label #未使用的标签,比如用goto + #-Wno-error=strict-prototypes #函数的声明或定义没有参数 + #-Wno-unused-parameter #未使用的函数参数 + #-Wno-unused-variable #未使用的变量 + #-Wno-unused-function #声明但未使用函数 + #-Wno-unused-but-set-variable #设置了但未使用的变量 + #-Wsign-compare #有符号与无符号比较 + #-Wno-error=pointer-arith + #-Wno-error=sign-compare + #-Wno-error=jump-misses-init + #-Wno-error=incompatible-pointer-types + #-Wno-error=logical-op + #-Wno-error=empty-body +) + +set(COMPONENT_CCFLAGS #当前组件内部生效的编译选项 + -Wno-error=maybe-uninitialized #变量未初始化 + -Wno-error=pointer-sign #传递参数类型不匹配 + -Wno-error=char-subscripts #使用char类作为数组下标,char有符号 + -Wno-error=unused-label #未使用的标签,比如用goto + -Wno-error=strict-prototypes #函数的声明或定义没有参数 + -Wno-unused-parameter #未使用的函数参数 + -Wno-unused-variable #未使用的变量 + -Wno-unused-function #声明但未使用函数 + -Wno-unused-but-set-variable #设置了但未使用的变量 + -Wsign-compare #有符号与无符号比较 + -Wno-error=pointer-arith + -Wno-error=sign-compare + -Wno-error=jump-misses-init + -Wno-error=incompatible-pointer-types + -Wno-error=logical-op + -Wno-error=empty-body +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + true +) + +build_component() + + + + + + +set(COMPONENT_NAME "app_main") + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/app_main.c +) + +set(PUBLIC_HEADER +) + +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES + CONFIG_SUPPORT_WIFI_APSTA +) + +set(PUBLIC_DEFINES +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS #当前组件需要对外提供的编译选项 + #-Wno-error=maybe-uninitialized #变量未初始化 + #-Wno-error=pointer-sign #传递参数类型不匹配 + #-Wno-error=char-subscripts #使用char类作为数组下标,char有符号 + #-Wno-error=unused-label #未使用的标签,比如用goto + #-Wno-error=strict-prototypes #函数的声明或定义没有参数 + #-Wno-unused-parameter #未使用的函数参数 + #-Wno-unused-variable #未使用的变量 + #-Wno-unused-function #声明但未使用函数 + #-Wno-unused-but-set-variable #设置了但未使用的变量 + #-Wsign-compare #有符号与无符号比较 + #-Wno-error=pointer-arith + #-Wno-error=sign-compare + #-Wno-error=jump-misses-init + #-Wno-error=incompatible-pointer-types + #-Wno-error=logical-op + #-Wno-error=empty-body +) + +set(COMPONENT_CCFLAGS #当前组件内部生效的编译选项 + -Wno-error=maybe-uninitialized #变量未初始化 + -Wno-error=pointer-sign #传递参数类型不匹配 + -Wno-error=char-subscripts #使用char类作为数组下标,char有符号 + -Wno-error=unused-label #未使用的标签,比如用goto + -Wno-error=strict-prototypes #函数的声明或定义没有参数 + -Wno-unused-parameter #未使用的函数参数 + -Wno-unused-variable #未使用的变量 + -Wno-unused-function #声明但未使用函数 + -Wno-unused-but-set-variable #设置了但未使用的变量 + -Wsign-compare #有符号与无符号比较 + -Wno-error=pointer-arith + -Wno-error=sign-compare + -Wno-error=jump-misses-init + -Wno-error=incompatible-pointer-types + -Wno-error=logical-op + -Wno-error=empty-body +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + true +) + +build_component() diff --git a/application/ws63/hsf/assis_thread.h b/application/ws63/hsf/assis_thread.h new file mode 100755 index 0000000..d32daf3 --- /dev/null +++ b/application/ws63/hsf/assis_thread.h @@ -0,0 +1,66 @@ +/* assis_thread.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _ASSIS_THREAD_H_ +#define _ASSIS_THREAD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ASSIS_PORT 48899 +#define ASSIS_PBUF_SIZE 200 + + +/** + * @brief start assis thread. + * + * @param[in] port: assis thread listen udp port + * @return[out] HF_SUCCESS-successfully, other value is failed + */ +int HSF_IAPI start_assis(uint16_t port); + +/** + * @brief check whether or not in assis AT cmd mode. + * + * @param[in] None + * @return[out] 0-not in, 1-in assis AT cmd mode + * @see None. + * @note None. + */ +int HSF_IAPI assis_is_in_cmd(void); + +/** + * @brief get assis AT cmd source IP address. + * + * @param[in] None + * @return[out] IP address in number format + * @see None. + * @note None. + */ +uint32_t HSF_IAPI assis_get_peer_ip(void); + +/** + * @brief send response to AT commands from assis thread. + * + * @param[in] rsp: the response + * len: the length of response + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_IAPI assis_cmd_response(char *rsp, int len); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/application/ws63/hsf/hfat.h b/application/ws63/hsf/hfat.h new file mode 100755 index 0000000..b38aac8 --- /dev/null +++ b/application/ws63/hsf/hfat.h @@ -0,0 +1,162 @@ + /* hfat.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_AT_H_ +#define _HF_AT_H_ + +#include "hsf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HFAT_MAX_CMD_DATA_LEN (1024) +#define HFAT_REPLY_FLAG_NOSEND_TAIL (0x00000001) +#define HFUART_TEST_WAIT_TIME 400 +//#define HFAT_DELETE_PARTIAL_CMD + +typedef int (*at_cmd_reply_func)(const char*,int len,int timeouts,int flags); +typedef int (*at_cmd_read_func)(char*buf,int len,int timeouts,int flags); + +typedef struct _at_session +{ + at_cmd_reply_func pfreply; + at_cmd_read_func pfread; + int sid; + char *rsp; + int rsp_len; + int cmd_id; +}at_session_t,*pat_session_t; + +typedef pat_session_t at_session_handle; + +typedef struct _at_cmd +{ + const char * name; + int (*func)(pat_session_t,int, char** ,char *,int); // the main func , or init + const char * doc; + int (*callhook)(pat_session_t,int, char** ,char *,int); +} hfat_cmd_t,*phfat_cmd_t; + +typedef struct _at_cmd_category +{ + const char *name; + phfat_cmd_t item; +}hfat_cmd_category,*phfat_cmd_category; + + +enum session_id_e +{ + AT_SESSION_UART0=0, + AT_SESSION_UART1=1, + AT_SESSION_ASSIST_SOCKET, + AT_SESSION_API, +}; + +enum ENCMDOPCODE +{ + OPCODE_NONE, + OPCODE_EQUA, + OPCODE_WFLASH, + OPCODE_QUERY +}; + +enum ENCMDCODE +{ + CMD_ERR =-1, + CMD_NONE = 0, +}; +enum +{ + UART0_TEST_NONE=0, + UART0_TEST_START, + UART0_TEST_SUCCESS +}; + +#define HFAT_TABLE_INDEX_USER 0 +#define HFAT_TABLE_INDEX_UTILS 1 +#define HFAT_TABLE_INDEX_SOCKA 2 +#define HFAT_TABLE_INDEX_SOCKB 3 +#define HFAT_TABLE_INDEX_WIFI 4 +#define HFAT_TABLE_INDEX_NETWORK 5 +#define HFAT_TABLE_INDEX_WIFITEST 6 + +extern hfat_cmd_category hf_at_cmd_tables[]; +extern const hfat_cmd_t user_define_at_cmds_table[]; +int setbaudrate(int baud,int uart_no); +int setparity(int parity,int uart_no); + +int HSF_IAPI hfat_init(void); + +int HSF_IAPI hfat_assis_send_cmd(char *cmd_line,int cmd_len); + +int HSF_IAPI hfat_pars_uart_cmd(hfuart_handle_t uart, char *cmd_line, int len); + +int HSF_IAPI hfat_uart_recv(char *data, uint32_t bytes, uint32_t timeouts); + +int HSF_IAPI hfat_uart_send(char *data, uint32_t bytes); + +void HSF_IAPI print_hex(char *rep, unsigned char h); + +void HSF_IAPI cmd_reply(char *reply); + +int HSF_IAPI strtowords(char *str,char *words[],int size,char *separators); + + +/** + * @brief enable/disable uart at command. + * + * @param[in] enable: 1-enable, 0-disable + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfat_enable_uart_session(char enable); + +/** + * @brief set at command buffer size. + * + * @param[in] size: range is [1-4096], in bytes, default is 100 + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfat_set_atcmd_buf_size(int size); + + /** + * @brief parse at command. + * + * @param[in] cmd_line: a pointer to a buffer containing the AT command + * cmd_len: the length, in bytes, of the data pointed to by the cmd_line parameter + * rsp: a pointer to a buffer to receive AT command response data + * len: the size of the rsp parameter + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note cannot be called in ISR. + */ +int HSF_API hfat_send_cmd(char *cmd_line,int cmd_len,char *rsp,int len); + +/** + * @brief parse at command response. + * + * @param[in] str: a pointer to a buffer containing the AT command response data + * words: a pointer to a pointer buffer + * size: the count of words parameter + * @return[out] the count of words + * @see None. + * @note None. + */ +int HSF_API hfat_get_words(char *str,char *words[],int size); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/application/ws63/hsf/hfconfig.h b/application/ws63/hsf/hfconfig.h new file mode 100755 index 0000000..21de214 --- /dev/null +++ b/application/ws63/hsf/hfconfig.h @@ -0,0 +1,704 @@ +/* hfconfig.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_CONFIG_H_ +#define _HF_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hsf.h" + +#define CONFIG_HAVE_SETTIMEOFDAY 1 +#define CONFIG_HAVE_GETTIMEOFDAY 1 +//#define CONFIG_NO_STRUCT_TIMEZONE +#define SECRET_BUF_SIZE 3500 +#define DEFAULT_NTP_SERVER "cn.ntp.org.cn" + + +#define UPDATEFLAG 2 +#define BLE_CONKEYLEN 16 +#define HILINK_SN_MAX_SIZE 36 + +#pragma pack(push) +#pragma pack(1) + +typedef struct +{ + int8_t updateflag; //update flag + int8_t validflag; //valid flag + int8_t tmode_mode; + int8_t wmode_mode; + + //STA, 140 bytes + uint8_t sta_ssid[33]; + uint8_t sta_key[65]; + int8_t wsauth; + int8_t wsencry; + uint8_t wslko; + uint8_t pmk_av; + uint8_t sta_padding[6]; + uint8_t pmk[32]; + + //AP, 144 bytes + int8_t wap_mode; + int8_t wap_channel; + int8_t waauth; + int8_t waencry; + uint8_t walk_led; + uint8_t max_sta_num; + uint8_t ap_enable_hide; + uint8_t ap_ssid[33]; + uint8_t ap_key[65]; + uint8_t ap_pmk_av; + uint8_t ap_pmk[32]; + uint8_t ap_padding[6]; + + //UART, 20 bytes + int8_t baudrate; + int8_t data_bits; + int8_t stop_bits; + int8_t parity; + int8_t ctsrts; + + int8_t uart1_baudrate; + int8_t uart1_data_bits; + int8_t uart1_stop_bits; + int8_t uart1_parity; + int8_t uart1_debug; + int8_t uartfable; + int8_t fuartte_mode; + uint16_t uarttm; + uint16_t uartbuf; + uint8_t uart_padding[4]; + + //NETP, 108 bytes + int8_t protocol; + int8_t app_mode; + uint8_t maxsocket; + char cipadd[101]; + uint16_t pro_port; + uint16_t tcpto; + + //SOCKB, 112 bytes + uint16_t sockb_port; + uint16_t sockb_tcpto; + int8_t sockb_pro; + char sockb_cipadd[101]; + int8_t tcpdis; + int8_t tcpdisb; + + uint16_t udp_localporta; + uint16_t udp_localportb; + + //NETWORK, 108 bytes + char wann_ipaddr[16]; + char wann_mask[16]; + char wann_gateway[16]; + char lann_ipaddr[16]; + char lann_mask[16]; + uint8_t wann_mode; + uint8_t network_padding[2]; + uint8_t domain_name[21]; + uint32_t dns_addr; + + //UTILS, 124 bytes + int8_t echo; + int8_t rlden; + uint8_t debug_level; + char wel_msg[11]; + uint8_t event_onoff; + uint8_t noise_filter; + uint8_t wifi_switch; + uint8_t sta_dtim; + uint8_t utils_padding[40]; + uint8_t dis_power_saving; + int8_t modechange; + uint8_t ps_interval; + uint8_t mid[21]; + uint8_t aswd[21]; + uint8_t cmdpw[21]; + + //HTTPD, 36 bytes + char user_name[16]; + char user_password[16]; + int8_t web_switch; + uint8_t web_language; + uint8_t web_encode_format; + uint8_t httpd_padding; + + //DHCPD, 4 bytes + int8_t dhcpsw; + uint8_t dhcpd_addr_start; + uint8_t dhcpd_addr_end; + uint8_t dhcpd_padding; + + //UPDATE, 124 bytes + char update_url[101]; + char update_file[21]; + uint8_t update_padding[2]; + + //NTP, 8 bytes + uint8_t ntp_time; + uint8_t ntp_enable; + uint8_t ntp_padding; + int8_t time_zone; + uint32_t ntpserver; + + //SMTLK, 16 bytes + uint32_t smtlk_sign; + uint8_t smtlk_mode; + uint8_t smtlk_protocol; + uint8_t smtlk_rtype; + uint8_t smtlk_ak_random; + uint8_t connect_flag; + uint8_t sta_channel; + uint8_t sta_bssid[6]; + + //SMARTAPLINK, 44 bytes + uint8_t smartaplink_enable; + uint8_t smartaplink_padding; + uint8_t smartaplink_prefix[21]; + uint8_t smartaplink_key[21]; + + //NETPID, 24 bytes + uint8_t netpa_iden; + char netpa_id[11]; + uint8_t netpb_iden; + char netpb_id[11]; + + //NETPREG, 264 bytes + uint8_t netpa_regen; + uint8_t netpa_regtype; + uint8_t netpa_reg_padding; + char netpa_regdata[129]; + uint8_t netpb_regen; + uint8_t netpb_regtype; + uint8_t netpb_reg_padding; + char netpb_regdata[129]; + + //HEART, 124 bytes + uint16_t heart_netp_time; + uint16_t heart_sockb_time; + uint16_t heart_uart_time; + char heart_netp_data[39]; + char heart_sockb_data[39]; + char heart_uart_data[39]; + uint8_t heart_padding; + + //HTTP, 236 bytes + uint8_t http_type; + uint8_t http_version; + uint8_t http_connect_type; + uint8_t http_recv_time; + char http_url[51]; + char http_header[181]; + + //MQTT, 224 bytes + char mqtt_username[33]; + char mqtt_password[33]; + char mqtt_clientid[33]; + char mqtt_pub_topic[61]; + char mqtt_sub_topic[61]; + uint8_t mqtt_qos; + uint16_t mqtt_heart_time; + + //BLE, 188 bytes + uint16_t conn_min; + uint16_t conn_max; + uint16_t conn_latency; + uint16_t supervisionTO; + + uint16_t adver_min; + uint16_t adver_max; + + uint8_t ble_name[27]; //BLE广播名 + uint8_t ble_dms_name[27]; //BLE配网名 + uint8_t ble_adver_data[27]; + + uint8_t ble_adver_data_len; + uint8_t ble_switch; + uint8_t ble_uuid_server; + uint8_t dms_type; + uint8_t ble_padding; + + uint8_t uuid_ntf_server[17]; + uint8_t uuid_ntf_read[17]; + uint8_t uuid_ntf_write[17]; + uint8_t uuid_ind_server[17]; + uint8_t uuid_ind_read[17]; + uint8_t uuid_ind_write[17]; + + uint8_t adver_type; + uint8_t adver_channel; + uint8_t ble_ind; + uint8_t smartconfiglink; + + uint8_t ble_conenable; + uint8_t ble_conkey[BLE_CONKEYLEN]; + uint8_t ble_contimeout; + uint8_t netpc_iden; + char netpc_id[11]; + uint8_t netpc_idflag; + + uint8_t ble_padding2[17]; + + uint8_t mqtt_tls; + uint8_t mqtt_padding[3]; + + char iot_productkey[12]; + char iot_devicename[48]; + char iot_devicesecret[48]; + char iot_pubtopic[96]; + char iot_subtopic[96]; + char iot_mode; + char iot_padding[3]; + + uint8_t product_mode; + + int8_t ctsrts_pin; + + char instance_flag; + char instance_id[32]; + + char ntp_domain_server[33]; + int8_t smk_find; + + uint32_t mcu_ota_size; + uint8_t scan_ch14; + + uint32_t module_reset_reason; + + uint8_t radar_type; //雷达工作类型(0 is disable) + uint8_t radar_led; //雷达灯工作类型(0 is off) + + uint8_t smtlk_type; + char hilink_sn[HILINK_SN_MAX_SIZE]; + uint8_t prot_type; + uint8_t product; + uint8_t uart1_debug_rx_invalid; + uint8_t reserved1[51+512-HILINK_SN_MAX_SIZE-1]; + + uint8_t validflag_magic; + int8_t validflag_end; //valid flag +}HF_CONFIG_FILE; //sizeof Must have 16 byte alignment + +typedef struct +{ + uint32_t magic_code; + uint32_t crc32; + uint32_t ver; + uint32_t ota_flag; + uint32_t run_mode; + uint32_t upgrade_fw_addr; + uint8_t flash_test; + uint8_t reserved2; + uint8_t xmodem_upgrade_fw_flag; + uint8_t debug; + uint8_t rf_init; + uint8_t run_default_sw; + uint8_t run_rf_test_app; + uint8_t boot_wait_flag; + int8_t rf_table[48]; + uint8_t reserved[48]; +}HF_BOOT_CONFIG; + +#pragma pack(pop) + +extern int g_module_id; +extern HF_CONFIG_FILE g_hf_config_file; + +enum ENWAUTH +{ + WAUTH_OPEN = 0x00, + WAUTH_SHARED, + WAUTH_WPAPSK, + WAUTH_WPA2PSK, + WAUTH_WPAPSKWPA2PSK +}; + +enum ENWENCRY +{ + WENCRY_NONE = 0x00, + WENCRY_WEP_A, + WENCRY_WEP_H, + WENCRY_TKIP, + WENCRY_AES, + WENCRY_TKIPAES, + WENCRY_WEP +}; + +enum ENNETSETAPP +{ + NETSETAPP_SERVER = 0x00, + NETSETAPP_CLIENT +}; + +enum ENNETSETPRO +{ + NETSETPRO_TCP = 0x00, + NETSETPRO_UDP, + NETSETPRO_HTTPC, + NETSETPRO_MQTT, + NETSETPRO_ALIIOT, + NETSETPRO_IGMP, + NETSETPRO_TCP_TLS, + NETSETPRO_HTTPSC +}; + +enum ENSOCKBPRO +{ + SOCKBPRO_NONE = 0x00, + SOCKBPRO_TCP, + SOCKBPRO_UDP, + SOCKBPRO_UDPS, + SOCKBPRO_IGMP +}; + +typedef enum ENBAUDRATE +{ + BAUDRATE_50 = 0x00, + BAUDRATE_75, + BAUDRATE_110, + BAUDRATE_134, + BAUDRATE_150, + BAUDRATE_200, + BAUDRATE_300, + BAUDRATE_600, + BAUDRATE_1200, + BAUDRATE_1800, + BAUDRATE_2400, + BAUDRATE_4800, + BAUDRATE_9600, + BAUDRATE_19200, + BAUDRATE_38400, + BAUDRATE_57600, + BAUDRATE_115200, + BAUDRATE_230400, + BAUDRATE_380400, + BAUDRATE_460800, + BAUDRATE_921600, + BAUDRATE_56000, + BAUDRATE_1000000, + BAUDRATE_1500000, + BAUDRATE_2000000, + BAUDRATE_2500000, + BAUDRATE_3000000, + BAUDRATE_3500000, + BAUDRATE_4000000 +}ENBAUDRATE_E; + +typedef enum ENCOMBITS +{ + COMBITS_5 = 0x00, + COMBITS_6, + COMBITS_7, + COMBITS_8 +}ENCOMBITS_E; + +typedef enum ENCOMPARITY +{ + COMPARITY_NONE = 0x00, + COMPARITY_ODD, + COMPARITY_EVEN, + COMPARITY_MARK, + COMPARITY_SPACE +}ENCOMPARITY_E; + +typedef enum ENCOMSTOPBITS +{ + + COMSTOPBITS_1 = 0x01, + COMSTOPBITS_1P5, + COMSTOPBITS_2 +}ENCOMSTOPBITS_E; + +typedef enum ENCOMUARTCTL +{ + COMUARTFC = 0x00, + COMUARTNFC +}ENCOMUARTCTL_E; + +typedef enum ENCOMUARTCTLPIN +{ + COMUARTFCPIN_DEF = 0x00, + COMUARTFCPIN_REV +}ENCOMUARTCTLPIN_E; + +enum ENCOMWANNMODE +{ + COMWANNDHCP = 0x00, + COMWANNSTATIC +}; + +enum ENUARTFABLE +{ + HFUARTFDISABLE = 0x00, + HFUARTFENABLE, + HFUARTHFFORMAT, +}; + +enum ENUARTFMODE +{ + M2M_UARTTE_FAST = 0x00, + M2M_UARTTE_NORMAL +}; + +enum CONFIG_WAMOD +{ + CONFIG_WAMOD_11B = 0x00, + CONFIG_WAMOD_11BG, + CONFIG_WAMOD_11BGN +}; + +enum CONFIG_WMODE +{ + CONFIG_WMODE_AP = 0x00, + CONFIG_WMODE_STA, + CONFIG_WMODE_APSTA +}; + +enum ENWORKTMODE +{ + M2M_STATE_RUN_THROUGH = 0x00, + M2M_STATE_RUN_CMD, + M2M_STATE_RUN_GPIO, + M2M_STATE_RUN_PWM +}; + +enum CONFIG_PSLP +{ + CONFIG_PSLP_NORMAL = 0x00, + CONFIG_PSLP_STANDBY, + CONFIG_PSLP_DEEPSLEEP +}; + +enum CONFIG_PRLDEN +{ + CONFIG_PRLDEN_DISABLE = 0x00, + CONFIG_PRLDEN_ENABLE +}; + +enum CONFIG_WADHCP +{ + CONFIG_WADHCP_DISABLE = 0x00, + CONFIG_WADHCP_ENABLE +}; + +enum CONFIG_WEBLANGUAGE +{ + CONFIG_WEBLAN_EN = 0x00, + CONFIG_WEBLAN_CN +}; + +enum CONFIG_DISPS +{ + CONFIG_EN_PS = 0x00, + CONFIG_DIS_PS +}; + +enum CONFIG_BLE +{ + CONFIG_BLE_ON = 0x00, + CONFIG_BLE_OFF +}; + +enum CONFIG_BLE_IND //ble link light +{ + CONFIG_BLE_IND_OFF = 0x00, + CONFIG_BLE_IND_ON +}; + +enum CONFIG_REG_TYPE +{ + CONFIG_REG_TYPE_LINK = 0x00, + CONFIG_REG_TYPE_DATA, + CONFIG_REG_TYPE_BOTH +}; + +typedef enum +{ + SMTLK_BLE_NARMAL =0, + SMTLK_BLE_ADD_LOCAL_CONTROL =1, + SMTLK_BLE_FAST_CONNECT =2, + SMTLK_SOFTAP =3 +}config_type_t; + +enum +{ + SMTLK_BLE_NOMAL =1, + SMTLK_BLE_DOUBLE_CONTROL=12, + SMTLK_BLE_FAST=17 +}; + +enum CONFIG_FACTORYTEST +{ + CONFIG_FACTORYTEST_OFF = 0x00, + CONFIG_FACTORYTEST_ON = 0x01 +}; + +void HSF_IAPI hfconfig_init(void); + +int HSF_IAPI hfconfig_is_valid(void); + +void HSF_IAPI hfconfig_dump(unsigned char *data, int len); + +int HSF_IAPI hfconfig_protect_check(void); + +int HSF_IAPI hfconfig_fseting_save_ex(HF_CONFIG_FILE *file); + +int HSF_IAPI hfconfig_fseting_save(void); + +void HSF_IAPI hfconfig_file_reload(void); + +void HSF_IAPI hfconfig_enable_save(int enable); + +void HSF_IAPI hfconfig_file_save(void); + + + + +int HSF_IAPI hfboot_config_set_ota_ready(uint32_t ota_file_addr); + +int HSF_IAPI hfboot_config_set_ota_flags(uint32_t flags); + +int HSF_IAPI hfboot_config_set_ota_xmodem(uint8_t flag); + +int HSF_IAPI hfboot_config_set_run_default_sw(uint8_t flag); + +uint8_t HSF_IAPI hfboot_config_get_run_default_sw(void); + +int HSF_IAPI hfboot_config_set_flash_test(uint8_t flag); + +int HSF_IAPI hfboot_config_get_flash_test(void); + +void HSF_IAPI hfboot_update_run_mode(uint32_t mode); + +void HSF_IAPI hfboot_set_rf_test_mode(uint8_t mode); + +uint8_t HSF_IAPI hfboot_get_rf_test_mode(void); + +void HSF_IAPI hfboot_set_boot_wait_flag(uint8_t flag); + +uint8_t HSF_IAPI hfboot_get_boot_wait_flag(void); + +int HSF_IAPI hfboot_config_set_rf_table(int8_t table[48]); + +int HSF_IAPI hfboot_config_get_rf_table(int8_t table[48]); + +void HSF_IAPI hfboot_update_run_mode(uint32_t mode); + +void HSF_IAPI hfboot_set_debug(uint8_t on); + + + + + +int HSF_IAPI hfconfig_uart_baud_en2num(int *num,int baudrate); + +int HSF_IAPI hfconfig_uart_baud_num2en(int num, int *en); +uint8_t HSF_API hfproduct_is_run(void); +void HSF_API hfproduct_run_set(uint8_t mode); +int HSF_API hf_get_customer_run_mode(void); +int HSF_API hf_set_customer_run_mode(int mode); +uint8_t hf_hilink_main_is_runing(void); +void hf_set_hilink_main_runing(void); + + +/** + * @brief check High-flying config data is valid. + * + * @param[in] None + * @return[out] 0-invalid, 1-valid + * @see None. + * @note None. + */ +int HSF_API hfconfig_file_check_is_valid(void); + + + +/** + * @brief read High-flying config data. + * + * @param[in] offset: the offset of config data + * data: a pointer to data + * len: the length, in bytes, of the data pointed to store data + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfconfig_file_data_read(int offset, unsigned char *data, int len); + + /** + * @brief write High-flying config data. + * + * @param[in] offset: the offset of config data + * data: a pointer to data + * len: the length, in bytes, of the data pointed to write + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfconfig_file_data_write(int offset, unsigned char *data, int len); + +/** + * @brief read hilink sn. + * + * @param[in] NULL + * @return[out] return hilink sn string + * @see None. + * @note None. + */ +char *hfget_hilink_sn(void); + +/** + * @brief write hilink sn. + * + * @param[in] set hilink sn to flash + * @return[out] 0 set success other fail + * @see None. + * @note None. + */ +int hfset_hilink_sn(char *sn); + +/** + * @brief set hilink smtlk mode. + * + * @param[in] set hilink smtlk mode to flash + * SMTLK_BLE_NARMAL ble常规配网 + * SMTLK_BLE_ADD_LOCAL_CONTROL ble双联双控 + * SMTLK_BLE_FAST_CONNECT ble极简配网 + * SMTLK_SOFTAP softap配网 + * @return[out] NULL + * @see None. + * @note None. + */ +void hfset_hilink_mode(int type); + +/** + * @brief get hilink smtlk mode. + * @param[in] NULL + * @return[out] hilink mode + * SMTLK_BLE_NARMAL ble常规配网 + * SMTLK_BLE_ADD_LOCAL_CONTROL ble双联双控 + * SMTLK_BLE_FAST_CONNECT ble极简配网 + * SMTLK_SOFTAP softap配网 + * @see None. + * @note None. + */ +int hfget_hilink_mode(void); + + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/application/ws63/hsf/hfcrypto.h b/application/ws63/hsf/hfcrypto.h new file mode 100755 index 0000000..8f60455 --- /dev/null +++ b/application/ws63/hsf/hfcrypto.h @@ -0,0 +1,230 @@ +/* hfcrypto.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_CRYPTO_H_ +#define _HF_CRYPTO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief encrypt data with aes (ecb mode/128bit key). + * + * @param[in] key: the key of AES + * data: the data want to encrypt + * data_len: the length of data + * @return[out] the length of encrypted data + * @see None. + * @note None. + */ +int HSF_API hfcrypto_aes_ecb_encrypt(const unsigned char *key, unsigned char *data, int data_len); + +/** + * @brief decrypt data with aes (ecb mode/128bit key). + * + * @param[in] key: the key of AES + * data: the data want to decrypt + * data_len: the length of data + * @return[out] the length of decrypted data + * @see None. + * @note None. + */ +int HSF_API hfcrypto_aes_ecb_decrypt(const unsigned char *key, unsigned char *data, int data_len); + +/** + * @brief encrypt data with aes (cbc mode/128bit key). + * + * @param[in] key: the key of AES + * iv: the initialization vector of AES + * data: the data want to encrypt + * data_len: the length of data + * @return[out] the length of encrypted data + * @see None. + * @note None. + */ +int HSF_API hfcrypto_aes_cbc_encrypt(const unsigned char *key, const unsigned char *iv, unsigned char *data, int data_len); + +/** + * @brief decrypt data with aes (cbc mode/128bit key). + * + * @param[in] key: the key of AES + * iv: the initialization vector of AES + * data: the data want to decrypt + * data_len: the length of data + * @return[out] the length of decrypted data + * @see None. + * @note None. + */ +int HSF_API hfcrypto_aes_cbc_decrypt(const unsigned char *key, const unsigned char *iv, unsigned char *data, int data_len); + +/** + * @brief calculate the MD5 of the data. + * + * @param[in] data: the data want to calculate MD5 + * len: the length of data, in bytes + * digest: store MD5, must > 16 bytes + * @return[out] the length of MD5, in bytes + * @see None. + * @note None. + */ +int HSF_API hfcrypto_md5(const unsigned char *data, int len, unsigned char *digest); + +/** + * @brief encode data as base64. + * + * @param[in] src: input byte array + * srclength: size of input byte array + * target: output byte array + * targsize: size of output byte array + * @return[out] returns the number of data bytes stored at the target, or -1 on error. + * @see None. + * @note encode data as base64, converts characters, three at a time, + * starting at src into four base64 characters in the target area + * until the entire input buffer is encoded. + */ +int HSF_API hfcrypto_base64_encode(char *src, uint32_t srclength, char *target, uint32_t targsize); + +/** + * @brief decode Base64 data. + * + * @param[in] src: input byte array + * target: output byte array + * targsize: size of output byte array + * @return[out] returns the number of data bytes stored at the target, or -1 on error. + * @see None. + * @note decode Base64 data, skips all whitespace anywhere. converts + * characters, four at a time, starting at (or after) src from Base64 + * numbers into three 8 bit bytes in the target area.. + */ +int HSF_API hfcrypto_base64_decode(char *src, char *target, uint32_t targsize); + +/** + * @brief rsa public key operation (1024bit key). + * + * @param[in] key: the key of RSA + * data: the data want to decrypt + * data_len: the length of data + * @return[out] the length of encrypted data + * @see None. + * @note None. + */ +// int HSF_API hfcrypto_rsa_public(const unsigned char *key, unsigned char *data, int data_len); + +/** + * @brief HMAC-SHA1 algorithm. + * + * @param[in] key: the key of HMAC-SHA1 + * key_len: the length of key + * data: the data want to calculate HMAC-SHA1 + * data_len: the length of data + * mac: the hash (20 bytes) + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfcrypto_hmac_sha1(const unsigned char *key, int key_len, const unsigned char *data, int data_len, unsigned char *mac); + + + +/** + * @brief AES CBC模式解密 + * + * @param input 文本输入 + * @param input_len 输入文本长度 + * @param output 文本输出 + * @param output_len 文本输出最大长度 + * @param key 秘钥 + * @param key_len 秘钥长度 + * @param iv 初始化向量 + * @param iv_len 初始化向量长度 + * @return uint8_t 返回是否解密成功,0:不成功,1:成功 + */ +uint8_t aes_cbc_decipher(uint8_t *input, uint32_t input_len, + uint8_t *output, uint32_t output_len, + uint8_t *key, uint32_t key_len, + uint8_t *iv, uint32_t iv_len); + + + +#if 1 + +#define Nb 4 //加解密数据块大小,固定为4 +// GF(2^8) 多项式 +#define BPOLY 0x1B //x^4 + x^3 + x^1 + x^0= 从右边开始算,bit0、bit1、bit3、bit4、为1,bit2、bit5、bit6、bit7为0,即00011011=0x1B + +//加密类型对应的密匙长度,单位bit +typedef enum { + AES128 = 128, + AES192 = 192, + AES256 = 256, +} AESType_t; + +//加解密模式 +typedef enum { + AES_MODE_ECB = 0, // 电子密码本模式 + AES_MODE_CBC = 1, // 密码分组链接模式 +} AESMode_t; + +typedef struct { + int Nk; //用户不需要填充,密钥长度,单位字节, AES128:Nk=16、AES192:Nk=24、AES256:Nr=32 + int Nr; //用户不需要填充,加密的轮数 AES128:Nr=10、AES192:Nr=12、AES256:Nr=14 + AESType_t type;//用户需填充,关联AESType_t + AESMode_t mode;//用户需填充,关联AESMode_t + const void *key;//用户需填充,密匙 + const void *pIV;//用户需填充,初始化向量, 当mode=AES_MODE_CBC时需要设置,指向unsigned char IV[4*Nb]; + //AES拓展密匙, 空间大小 AES128:4*Nb*(10+1):4*Nb*(12+1)、AES256:4*Nb*(14+1) + unsigned char expandKey[4*Nb*(14+1)];//用户不需要填充,[4*Nb*(Nr+1)]、这里按最大的AES256进行初始化 +} AESInfo_t; + + +/***************************************************************************** +* 函数名: AESInit +* 功能描述: 初始化 +* 输入参数: aesInfoP -- 用户需要填充 +* 输出参数: 无。 +* 返回值: 无。 +*****************************************************************************/ +void AESInit(AESInfo_t *aesInfoP); + + + +/***************************************************************************** +* 函数名: AESEncrypt +* 功能描述: 加密数据 +* 输入参数: aesInfoP -- 包含key、加密方式等初始化信息 +* pPlainText -- 要加密的明文数据,其长度为dataLen字节。 +* dataLen -- 明文数据长度,以字节为单位 +* 输出参数: pCipherText -- 加密后的数据 +* 返回值: 解密后的数据长度。 +*****************************************************************************/ +unsigned int AESEncrypt(AESInfo_t *aesInfoP, const unsigned char *pPlainText, unsigned char *pCipherText, unsigned int dataLen); + + + +/***************************************************************************** +* 函数名: AESDecrypt +* 功能描述: 解密数据 +* 输入参数: aesInfoP -- 包含key、加密方式等初始化信息 +* pCipherText -- 要解密的密文 +* dataLen -- 密文数据长度,以字节为单位,必须是整倍数,AES128:16倍数、AES192:24倍数、AES256:32倍数。 +* 输出参数: pPlainText -- 解密出来的明文 +* 返回值: 返回解密后的数据长度。 +*****************************************************************************/ +unsigned int AESDecrypt(AESInfo_t *aesInfoP, unsigned char *pPlainText, const unsigned char *pCipherText, unsigned int dataLen); + +#endif + + +#ifdef __cplusplus +} + +#endif +#endif + diff --git a/application/ws63/hsf/hfflash.h b/application/ws63/hsf/hfflash.h new file mode 100755 index 0000000..ec5cdf2 --- /dev/null +++ b/application/ws63/hsf/hfflash.h @@ -0,0 +1,103 @@ +/* hfflash.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_FLASH_H_ +#define _HF_FLASH_H_ + +#include "hsf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +int HSF_IAPI hfflash_init(void); + +unsigned int HSF_IAPI hfflash_size(void); + +int HSF_IAPI flash_write(unsigned int addr, unsigned char *data, int len, int no_used); + +int HSF_IAPI flash_erase_page(unsigned int addr, int pages); + +int HSF_IAPI flash_erase_write(unsigned int addr, unsigned char *data, int len, int no_used); + +int HSF_IAPI flash_read(unsigned int addr, unsigned char *data, int len, int no_used); + +int HSF_IAPI flash_copy(unsigned int dstaddr, unsigned int srcaddr, int len); + +int HSF_IAPI flash_valid_addr(unsigned int addr); + +int HSF_IAPI flash_enable(int enable); + +uint32_t HSF_IAPI hfget_flash_jedec_id(void); + +void HSF_IAPI hfset_flash_jedec_id(uint32_t JedecId); + + +#define hfflash_write flash_write +#define hfflash_erase_page flash_erase_page +#define hfflash_erase_write flash_erase_write +#define hfflash_read flash_read +#define hfflash_copy flash_copy +#define hfflash_enable flash_enable + + +#define HFFLASH_PAGE_SIZE (4*1024) + +/** + * @brief get the size of uflash, in bytes. + * + * @param[in] None + * @return[out] the size of uflash, in bytes + * @see None. + * @note None. + */ +int HSF_API hfuflash_size(void); + +/** + * @brief erase uflash. + * + * @param[in] addr: the address of flash, start from 0 + * pages: the number of pages to be erased, must <= 8, one page is 4096 bytes + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfuflash_erase_page(uint32_t addr, int pages); + +/** + * @brief write data to uflash. + * + * @param[in] addr: the address of flash, start from 0 + * data: a pointer to data + * len: the len of data + * @return[out] the length of write success + * @see None. + * @note None. + */ +int HSF_API hfuflash_write(uint32_t addr, char *data, int len); + +/** + * @brief read data from uflash. + * + * @param[in] addr: the address of flash, start from 0 + * data: a pointer to data + * len: the len of data + * @return[out] the length of read success + * @see None. + * @note None. + */ +int HSF_API hfuflash_read(uint32_t addr, char *data, int len); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/application/ws63/hsf/hfflashlayout.h b/application/ws63/hsf/hfflashlayout.h new file mode 100755 index 0000000..ff3dd76 --- /dev/null +++ b/application/ws63/hsf/hfflashlayout.h @@ -0,0 +1,64 @@ +/* hfflashlayout.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_FLASH_LAYOUT_H_ +#define _HF_FLASH_LAYOUT_H_ + + +#define CONFIG_FLASH_SIZE_4MB +#define CONFIG_FLASH_SIZE (1024*1024*4) + +#define BOOT_ADDRESS 0x00002000 //BOOT +#define BOOT_SIZE (64*1024) + + + + + +#define SOFTWARE_CODE_ADDRESS 0x00030000 //CODE区 +#define MAX_SOFTWARE_CODE_SIZE (1720*1024) + +#define SOFTWARE_HILINK_CODE_ADDRESS 0x001DE000 //HILINK CODE区 +#define MAX_SOFTWARE_HILINK_CODE_SIZE (512*1024) + +#define UPGRADE_ADDRESS 0x0025E000 //OTA区 +#define MAX_UPGRADE_FILE_SIZE (1536*1024) + +#define HILINK_FILE_SYS 0x003F3000 //HILINK文件系统区 +#define HILINK_FILE_SYS_SIZE 0x00008000 + + + +#define UFLASH_ADDRESS 0x003DE000 //UFLASH区 +#define HFUFLASH_SIZE (56*1024) + +#define BOOT_CONFIG 0x003EC000 //HF_BOOT配置区 +#define PRODUCT_PARA_ADDR 0x003ED000 //JSON配置MAC区 + + +#define USERPAGE 0x003EE000 //AT参数存储区 +#define USERPAGE_BACKUP 0x003F2000 //AT参数备份区 +#define F_SETTING_ADDRESS 0x003F0000 //AT参数出厂值区 + +#define SECU_FLASH_ADDR 0x003F1000 //MAC存储区 +#define SECU_FLASH_BACKUP_ADDR 0x003EF000 //MAC备份区 + + + +#define UFLASH1_ADDRESS 0 +#define HFUFLASH1_SIZE (0) + + +#define HILINK_CRASH_INFO 0x003FB000 //程序崩溃信息区 +#define HILINK_CRASH_INFO_SIZE 0x00001000 + +#define HILINK_NV_DATA 0x003FC000 //HILINK NV区 +#define HILINK_NV_DATA_SIZE 0x00004000 + +#endif + diff --git a/application/ws63/hsf/hfgpio.h b/application/ws63/hsf/hfgpio.h new file mode 100755 index 0000000..2096d32 --- /dev/null +++ b/application/ws63/hsf/hfgpio.h @@ -0,0 +1,434 @@ + /* hfgpio.h + * + * Copyright (C) 2023 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_GPIO_H_ +#define _HF_GPIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef void (*hfgpio_interrupt_func)(uint32_t irq, uint32_t fid); + +#define HFM_PIN_NUMBER (32+1) + +#define HFM_TYPE_LPT262 0 +#define HFM_TYPE_LPT263 1 +#define HFM_TYPE_LPT162 2 + + +#define HFM_MAX_FUNC_CODE (HFM_PIN_NUMBER*3) + +enum HF_GPIO_FUNC_E +{ + //////fix///////////////////// + HFGPIO_F_JTAG_TCK=0, + HFGPIO_F_JTAG_TDO=1, + HFGPIO_F_JTAG_TDI, + HFGPIO_F_JTAG_TMS, + HFGPIO_F_USBDP, + HFGPIO_F_USBDM, + HFGPIO_F_UART0_TX, + HFGPIO_F_UART0_RTS, + HFGPIO_F_UART0_RX, + HFGPIO_F_UART0_CTS, + HFGPIO_F_SPI_MISO, + HFGPIO_F_SPI_CLK, + HFGPIO_F_SPI_CS, + HFGPIO_F_SPI_MOSI, + HFGPIO_F_UART1_TX, + HFGPIO_F_UART1_RTS, + HFGPIO_F_UART1_RX, + HFGPIO_F_UART1_CTS, + //////////////////////////////// + HFGPIO_F_NLINK, + HFGPIO_F_NREADY, + HFGPIO_F_NRELOAD, + HFGPIO_F_SLEEP_RQ, + HFGPIO_F_SLEEP_ON, + HFGPIO_F_WPS, + + HFGPIO_F_RESERVE1, + HFGPIO_F_RESERVE2, + HFGPIO_F_RESERVE3, + HFGPIO_F_RESERVE4, + HFGPIO_F_RESERVE5, + HFGPIO_F_USER_DEFINE +}; + +#define F_GPI (0x00010000) +#define F_GPO (0x00020000) +//GND +#define F_GND (0x00040000) +//vcc +#define F_VCC (0x00100000) +#define F_NC (0x00200000) +//use to system reset +#define F_RST (0x00400000) +//use to interrupt input pin +#define F_IT (0x00800000|F_GPI) + +#define F_GPIO (F_GPI|F_GPO) + +#define F_PWM (0x01000000) +#define F_PWM0 F_PWM +#define F_PWM1 F_PWM +#define F_PWM2 F_PWM +#define F_PWM3 F_PWM +#define F_PWM4 F_PWM + +#define F_ADC (0x02000000) + +#define HFM_NOPIN (0) +#define HFM_PIN1 (F_NC|1) +#define HFM_PIN2 (F_VCC|2) +#define HFM_PIN3 (F_VCC|3) +#define HFM_PIN4 (F_GPIO|F_IT|4) +#define HFM_PIN5 (F_GPIO|F_IT|5) +#define HFM_PIN6 (F_GPIO|F_IT|6) +#define HFM_PIN7 (F_GPIO|F_IT|7) +#define HFM_PIN8 (F_GPIO|F_IT|8) +#define HFM_PIN9 (F_GPIO|F_IT|9) +#define HFM_PIN10 (F_GPIO|F_IT|10) +#define HFM_PIN11 (F_GPIO|F_IT|11) +#define HFM_PIN12 (F_GPIO|F_IT|12) +#define HFM_PIN13 (F_GPIO|F_IT|13) +#define HFM_PIN14 (F_GPIO|F_IT|14) +#define HFM_PIN15 (F_GPIO|F_IT|15) +#define HFM_PIN16 (F_GPIO|F_IT|16) +#define HFM_PIN17 (F_VCC|17) +#define HFM_PIN18 (F_NC|18) +#define HFM_PIN19 (F_NC|19) +#define HFM_PIN20 (F_NC|20) +#define HFM_PIN21 (F_GND|21) +#define HFM_PIN22 (F_NC|22) +#define HFM_PIN23 (F_NC|23) +#define HFM_PIN24 (F_GPIO|F_IT|24) +#define HFM_PIN25 (F_GPIO|F_IT|25) +#define HFM_PIN26 (F_GPIO|F_IT|26) +#define HFM_PIN27 (F_GPIO|F_IT|27) +#define HFM_PIN28 (F_GPIO|F_IT|28) +#define HFM_PIN29 (F_GPIO|F_IT|29) +#define HFM_PIN30 (F_NC|30) +#define HFM_PIN31 (F_NC|31) +#define HFM_PIN32 (F_NC|32) + + +#define LPT26x_GPIO0 HFM_PIN4 +#define LPT26x_GPIO1 HFM_PIN5 +#define LPT26x_GPIO2 HFM_PIN6 +#define LPT26x_GPIO3 HFM_PIN7 +#define LPT26x_GPIO4 HFM_PIN8 +#define LPT26x_GPIO5 HFM_PIN9 +#define LPT26x_GPIO6 HFM_PIN10 +#define LPT26x_GPIO7 HFM_PIN11 +#define LPT26x_GPIO8 HFM_PIN12 +#define LPT26x_GPIO9 HFM_PIN13 +#define LPT26x_GPIO10 HFM_PIN14 +#define LPT26x_GPIO11 HFM_PIN15 +#define LPT26x_GPIO12 HFM_PIN16 +#define LPT26x_GPIO13 HFM_PIN24 +#define LPT26x_GPIO14 HFM_PIN25 +#define LPT26x_GPIO15 HFM_PIN26 +#define LPT26x_GPIO16 HFM_PIN27 +#define LPT26x_GPIO17 HFM_PIN28 +#define LPT26x_GPIO18 HFM_PIN29 + + + + + +#define HF_M_PINNO(_pin) ((_pin)&0xFF) + +#define HFM_VALID_PINNO(_pinno) ((_pinno)>0&&(_pinno)<=HFM_PIN_NUMBER) + +#define HF_M_PIN(_no) HFM_PIN##_no + +/* Default pin configuration (no attribute). */ +#define HFPIO_DEFAULT (0u << 0) +#define HFPIO_PULLUP (1u << 2) +#define HFPIO_PULLDOWN (1u << 3) + +/* Low level interrupt is active */ +#define HFPIO_IT_LOW_LEVEL (1u<<4) +/* High level interrupt is active */ +#define HFPIO_IT_HIGH_LEVEL (1u<<5) +/* Falling edge interrupt is active */ +#define HFPIO_IT_FALL_EDGE (1u<<6) +/* Rising edge interrupt is active */ +#define HFPIO_IT_RISE_EDGE (1u<<7) +/*Interrupt Edge detection is active.*/ +#define HFPIO_IT_EDGE (1u<<8) + +#define HFPIO_TYPE_Pos 27 +/* PIO Type Mask */ +#define HFPIO_TYPE_Msk (0x7u << HFPIO_TYPE_Pos) + +/* The pin is an input. */ +#define HFM_IO_TYPE_INPUT (0x01 << HFPIO_TYPE_Pos) +/* The pin is an output and has a default level of 0.*/ +#define HFM_IO_OUTPUT_0 (0x02 << HFPIO_TYPE_Pos) +/* The pin is an output and has a default level of 1.*/ +#define HFM_IO_OUTPUT_1 (0x04 << HFPIO_TYPE_Pos) +#define HFPIO_DS (0x8u << HFPIO_TYPE_Pos) + + +void HSF_IAPI hfgpio_init(void); + +int HSF_IAPI hfgpio_get_pid(int gpio); + +int HSF_IAPI hfgpio_get_chip_pin(int fid); + +int HSF_IAPI hfgpio_configure_pin(int pid,int flags); + +int HSF_IAPI hfgpio_pin_is_high(int pid); + +int HSF_IAPI hfgpio_fpin_add_feature(int fid,int flags); + +int HSF_IAPI hfgpio_fpin_clear_feature(int fid,int flags); + +void HSF_IAPI hfgpio_gpio_test_enable(int enable); + +void HSF_IAPI hfgpio_set_nlink_pin(int val); + +void HSF_IAPI hfgpio_set_nready_pin(int val); + +int HSF_IAPI hfgpio_reload_pin_is_low(void); + +#define hfgpio_set_out_high(pid) hfgpio_configure_pin(pid,HFPIO_DEFAULT|HFM_IO_OUTPUT_1) + +#define hfgpio_set_out_low(pid) hfgpio_configure_pin(pid,HFPIO_DEFAULT|HFM_IO_OUTPUT_0) + + +/** + * @brief check the validity of hf_gpio_fid_to_pid_map_table. + * + * @param[in] type: the module type, as follows + * ========================================== + * | HFM_TYPE_LPT262 | + * |----------------------------------------| + * | HFM_TYPE_LPT263 | + * |----------------------------------------| + * | HFM_TYPE_LPT162 | + * ========================================== + * @return[out] HF_SUCCESS-successfully, other value is have multiple functions in the same pin + * @see None. + * @note None. + */ +int HSF_API hfgpio_fmap_check(int type); + +/** + * @brief set the configure parameters of pin by the function id. + * + * @param[in] fid: the function id define by table 'hf_gpio_fid_to_pid_map_table' + * flags: the flag of pin, as follows, can be used together, such as: HFPIO_DEFAULT|HFM_IO_TYPE_INPUT + * ========================================== + * | HFPIO_DEFAULT | + * |----------------------------------------| + * | HFM_IO_TYPE_INPUT | + * |----------------------------------------| + * | HFM_IO_OUTPUT_0 | + * |----------------------------------------| + * | HFM_IO_OUTPUT_1 | + * ========================================== + * @return[out] HF_SUCCESS-successfully, HF_FAIL-failed, HF_E_INVAL-illegal, HF_E_ACCES-not allowed + * @see None. + * @note None. + */ +int HSF_API hfgpio_configure_fpin(int fid, int flags); + +/** + * @brief get the configure parameters of pin by the function id. + * + * @param[in] fid: the function id define by table 'hf_gpio_fid_to_pid_map_table' + * @return[out] the configure parameters of pin + * @see None. + * @note None. + */ +int HSF_API hfgpio_fconfigure_get(int fid); + +/** + * @brief set the pin to high level by the function id. + * + * @param[in] fid: the function id define by table 'hf_gpio_fid_to_pid_map_table' + * @return[out] HF_SUCCESS-successfully, HF_FAIL-failed, HF_E_INVAL-illegal + * @see None. + * @note None. + */ +#define hfgpio_fset_out_high(fid) hfgpio_configure_fpin(fid,HFPIO_DEFAULT|HFM_IO_OUTPUT_1) + +/** + * @brief set the pin to low level by the function id. + * + * @param[in] fid: the function id define by table 'hf_gpio_fid_to_pid_map_table' + * @return[out] HF_SUCCESS-successfully, HF_FAIL-failed, HF_E_INVAL-illegal + * @see None. + * @note None. + */ +#define hfgpio_fset_out_low(fid) hfgpio_configure_fpin(fid,HFPIO_DEFAULT|HFM_IO_OUTPUT_0) + +/** + * @brief configure the interrupt of pin by the function id. + * +* @param[in] fid: the function id define by table 'hf_gpio_fid_to_pid_map_table' + * flags: the interrupt type, as follows + * ========================================== + * | HFPIO_IT_LOW_LEVEL | + * |----------------------------------------| + * | HFPIO_IT_HIGH_LEVEL | + * |----------------------------------------| + * | HFPIO_IT_FALL_EDGE | + * |----------------------------------------| + * | HFPIO_IT_RISE_EDGE | + * ========================================== + * handle: a function pointer, called back when trigger + * enable: enable or disable to trigger + * @return[out] HF_SUCCESS-successfully, HF_FAIL-failed, HF_E_INVAL-illegal, HF_E_ACCES-not allowed + * @see None. + * @note None. Timers cannot be used during interrupts + */ +int HSF_API hfgpio_configure_fpin_interrupt(int fid, uint32_t flags, hfgpio_interrupt_func handle, int enable); + +/** + * @brief enable interrupt of pin by the function id. + * +* @param[in] fid: the function id define by table 'hf_gpio_fid_to_pid_map_table' + * @return[out] HF_SUCCESS-successfully, HF_FAIL-failed, HF_E_INVAL-illegal + * @see None. + * @note None. Timers cannot be used during interrupts + */ +int HSF_API hfgpio_fenable_interrupt(int fid); + +/** + * @brief disable interrupt of pin by the function id. + * +* @param[in] fid: the function id define by table 'hf_gpio_fid_to_pid_map_table' + * @return[out] HF_SUCCESS-successfully, HF_FAIL-failed, HF_E_INVAL-illegal + * @see None. + * @note None. Timers cannot be used during interrupts + */ +int HSF_API hfgpio_fdisable_interrupt(int fid); + +/** + * @brief disable interrupt of all pins by the function id. + * +* @param[in] fid:None + * @return[out] HF_SUCCESS-successfully, HF_FAIL-failed + * @see None. + * @note None. Timers cannot be used during interrupts + */ +int HSF_API hfgpio_disabel_all_interrupt(void); + +/** + * @brief check the level of the pin to be high by the function id. + * +* @param[in] fid: the function id define by table 'hf_gpio_fid_to_pid_map_table' + * @return[out] >=1 high level, <=0 low level or illegal + * @see None. + * @note effective in output mode and input mode. + */ +int HSF_API hfgpio_fpin_is_high(int fid); + +/** + * @brief check whether or not in GPIO test mode . + * + * @param[in] None + * @return[out] 0-not in test mode, 1-in test mode + * @see None. + * @note None. + */ +int HSF_API hfgpio_gpio_test_is_running(void); + +/** + * @brief stop PWM. + * + * @param[in] fid: the function id of gpio + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfgpio_pwm_disable(int fid); + +/** + * @brief start PWM. + * + * @param[in] fid: the function id of gpio + * freq: the frequency of PWM, the range is [100-800000] + * hrate: the duty cycle of PWM, the range is [0-100], 0 means low, 100 means high + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note the same PWM channel cannot be used at the same time. + */ +int HSF_API hfgpio_pwm_enable(int fid, int freq, int hrate); + +/** + * @brief start PWM. + * + * @param[in] fid: the function id of gpio + * freq: the frequency of PWM, max is 20000000 + * percent: high level ratio, accurate 0.0001 + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note the same PWM channel cannot be used at the same time. + */ +int HSF_API hfgpio_pwm_enable_ex(int fid, int freq, float percent); + +/** + * @brief start ADC. + * + * @param[in] fid: the function id of gpio + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfgpio_adc_enable(int fid); + +/** + * @brief get ADC value. + * + * @param[in] fid: the function id of gpio + * @return[out] + <0-failed + >=0-the value of ADC, [0-3200] indicate [0V-3.2V] + * @see None. + * @note None. + */ +int HSF_API hfgpio_adc_get_value(int fid); + +/** + * @brief init infrared function. + * + * @param[in] fid: the function id of gpio + * @see None. + * @note None. + */ +void HSF_API hf_ir_init(int fid); +/** + * @brief infrared enable. + * + * @param[in] fid: the function id of gpio + * @see None. + * @note None. + */ +void HSF_API hf_ir_enable(void); +/** + * @brief infrared disable. + * + * @param[in] fid: the function id of gpio + * @see None. + * @note None. + */ +void HSF_API hf_ir_disable(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/application/ws63/hsf/hfmd5.h b/application/ws63/hsf/hfmd5.h new file mode 100755 index 0000000..c62130e --- /dev/null +++ b/application/ws63/hsf/hfmd5.h @@ -0,0 +1,48 @@ +#ifndef __MD5_H__ +#define __MD5_H__ + +typedef struct +{ + unsigned int count[2]; + unsigned int state[4]; + unsigned char buffer[64]; +}IOT_MD5_CTX; + + +#define F(x,y,z) ((x & y) | (~x & z)) +#define G(x,y,z) ((x & z) | (y & ~z)) +#define H(x,y,z) (x^y^z) +#define I(x,y,z) (y ^ (x | ~z)) +#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n))) +#define FF(a,b,c,d,x,s,ac) \ +{ \ + a += F(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +#define GG(a,b,c,d,x,s,ac) \ +{ \ + a += G(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +#define HH(a,b,c,d,x,s,ac) \ +{ \ + a += H(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +#define II(a,b,c,d,x,s,ac) \ +{ \ + a += I(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +void IOT_MD5Init(IOT_MD5_CTX *context); +void IOT_MD5Update(IOT_MD5_CTX *context,unsigned char *input,unsigned int inputlen); +void IOT_MD5Final(IOT_MD5_CTX *context,unsigned char digest[16]); +void IOT_MD5Transform(unsigned int state[4],unsigned char block[64]); +void IOT_MD5Encode(unsigned char *output,unsigned int *input,unsigned int len); +void IOT_MD5Decode(unsigned int *output,unsigned char *input,unsigned int len); +void IOT_MD5_format2str(unsigned char *encrypt, unsigned char *buffer); +#endif diff --git a/application/ws63/hsf/hfnet.h b/application/ws63/hsf/hfnet.h new file mode 100755 index 0000000..4d435f3 --- /dev/null +++ b/application/ws63/hsf/hfnet.h @@ -0,0 +1,99 @@ + +#ifndef _HF_NET_H_ +#define _HF_NET_H_ + +#include "lwip/sockets.h" + + +#define HFUART0 (hfuart_handle_t)(1) +#define HFUART1 (hfuart_handle_t)(2) + + +#define ASSIS_PORT 48899 + + +typedef enum +{ + HFNET_SOCKETA_DATA_READY=0, + HFNET_SOCKETA_CONNECTED=1, + HFNET_SOCKETA_DISCONNECTED, + HFNET_SOCKETB_DATA_READY, + HFNET_SOCKETB_CONNECTED, + HFNET_SOCKETB_DISCONNECTED, + HFNET_UART0_DATA_READY, + HFNET_UART1_DATA_READY, + HFNET_ASSIS_DATA_READY +}hfnet_event_id_t; + + +typedef struct _hfnet_stat +{ + int hfnet_init_down; + + int socketa_send_bytes; + int socketa_recv_bytes; + int socketa_connect_times; + + int uart_send_bytes; + int uart_recv_bytes; + + int socketb_send_bytes; + int socketb_recv_bytes; + int socketb_connect_times; + + int uart_buffer_full_times; + int uart_irq_num; + int uart_thread_run; + + int uart1_buffer_full_times; + int uart1_irq_num; + int uart1_thread_run; + + int socketa_buffer_full_times; + int drop_arp_packet; + int drop_udp_broadcast_packet; +}hfnet_stat; + +extern hfnet_stat g_hfnet_stat; + + +typedef int (*hfnet_callback_t)( uint32_t event,void *data,uint32_t len,uint32_t buf_len); + +int hfnet_start_uart(uint32_t uxpriority, hfnet_callback_t p_callback); + + +int HSF_API hfnet_start_assis(uint16_t port); + +int HSF_API hfnet_get_mac_address(char *mac_str); + +int HSF_API hfnet_get_wan_ip(uint32_t * ip, uint32_t *mask, uint32_t *gw); +struct netif *hf_get_sta_netif(void); +int hfwifi_sta_is_connected(void); + +int HSF_API hfnet_wifi_is_active(void); + +int HSF_IAPI hfnet_send_assis_event(uint32_t event,void *data,uint32_t len,uint32_t buf_len); + +/** + * @brief get ip address by domain name. + * + * @param[in] name: domain name + * addr: a pointer for using to store addr + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfnet_gethostbyname(const char *name, ip_addr_t *addr); + +/** + * @brief check string is ip address. + * + * @param[in] ipaddr: ip string + * @return[out] 1-ip address, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfnet_is_ipaddress(const char * ipaddr); + +#endif + diff --git a/application/ws63/hsf/hfntp.h b/application/ws63/hsf/hfntp.h new file mode 100755 index 0000000..97cb99c --- /dev/null +++ b/application/ws63/hsf/hfntp.h @@ -0,0 +1,38 @@ + /* hfntp.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_NTP_H_ +#define _HF_NTP_H_ + +#ifdef __cplusplus +extern "C"{ +#endif + + +#define DEFAULT_NTP_SERVER "cn.ntp.org.cn" + + +/** + * @brief get UTC time from NTP server. + * + * @param[in] addr: NTP server address, support domain name + * port: NTP server port, such as "123" + * timeout: recv response timeout, in milliseconds + * @return[out] >0 UTC time from 1970-01-01 00:00, <0 is failed + * @see None. + * @note None. + */ +int HSF_API hfntp_get_time(const char *addr, unsigned short port, int timeout); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/application/ws63/hsf/hfproduct.h b/application/ws63/hsf/hfproduct.h new file mode 100755 index 0000000..aac3984 --- /dev/null +++ b/application/ws63/hsf/hfproduct.h @@ -0,0 +1,34 @@ +/* hfproduct.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_PRODUCT_H_ +#define _HF_PRODUCT_H_ + +#include "hsf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _product_cmd +{ + const char * name; + void (*callhook)(int, char *); +} hfproduct_cmd_t,*phfproduct_cmd_t; + + +void HSF_IAPI hfproduct_init(void); +void HSF_IAPI hfproduct_read_mac(void); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/application/ws63/hsf/hfsecret.h b/application/ws63/hsf/hfsecret.h new file mode 100755 index 0000000..756a9c6 --- /dev/null +++ b/application/ws63/hsf/hfsecret.h @@ -0,0 +1,12 @@ +#ifndef _HF_SECRET_H__ +#define _HF_SECRET_H__ + +#include "hsf.h" +#define KEY_LEN 8 +#define MAC_LEN 6 + +void HSF_IAPI hfwifi_init(void); + +#define SECRET_MASSAGE_SIZE 256 + +#endif diff --git a/application/ws63/hsf/hfsys.h b/application/ws63/hsf/hfsys.h new file mode 100755 index 0000000..53ec983 --- /dev/null +++ b/application/ws63/hsf/hfsys.h @@ -0,0 +1,120 @@ + +#ifndef _HF_SYS_H_ +#define _HF_SYS_H_ + + + +#define MOD_ERROR_START(x) ((x << 16) | 0) + +/* Create Module index */ +#define MOD_GENERIC 0 +/** HTTPD module index */ +#define MOD_HTTPDE 1 +/** HTTP-CLIENT module index */ +#define MOD_HTTPC 2 +/** WPS module index */ +#define MOD_WPS 3 +/** WLAN module index */ +#define MOD_WLAN 4 +/** USB module index */ +#define MOD_USB 5 + +#define MOD_USER_DEFINE (0x80) + + +/* Globally unique success code */ +#define HF_SUCCESS 0 + + + +#define HFSYS_RESET_REASON_NORMAL (0) + +#define HFSYS_RESET_REASON_OTA (0x00000100) + + +enum hf_errno { + /* First Generic Error codes */ + HF_GEN_E_BASE = MOD_ERROR_START(MOD_GENERIC), + HF_FAIL, + HF_E_PERM, /* Operation not permitted */ + HF_E_NOENT, /* No such file or directory */ + HF_E_SRCH, /* No such process */ + HF_E_INTR, /* Interrupted system call */ + HF_E_IO, /* I/O error */ + HF_E_NXIO, /* No such device or address */ + HF_E_2BIG, /* Argument list too long */ + HF_E_NOEXEC, /* Exec format error */ + HF_E_BADF, /* Bad file number */ + HF_E_CHILD, /* No child processes */ + HF_E_AGAIN, /* Try again */ + HF_E_NOMEM, /* Out of memory */ + HF_E_ACCES, /* Permission denied */ + HF_E_FAULT, /* Bad address */ + HF_E_NOTBLK, /* Block device required */ + HF_E_BUSY, /* Device or resource busy */ + HF_E_EXIST, /* File exists */ + HF_E_XDEV, /* Cross-device link */ + HF_E_NODEV, /* No such device */ + HF_E_NOTDIR, /* Not a directory */ + HF_E_ISDIR, /* Is a directory */ + HF_E_INVAL, /* Invalid argument */ + HF_E_NFILE, /* File table overflow */ + HF_E_MFILE, /* Too many open files */ + HF_E_NOTTY, /* Not a typewriter */ + HF_E_TXTBSY, /* Text file busy */ + HF_E_FBIG, /* File too large */ + HF_E_NOSPC, /* No space left on device */ + HF_E_SPIPE, /* Illegal seek */ + HF_E_ROFS, /* Read-only file system */ + HF_E_MLINK, /* Too many links */ + HF_E_PIPE, /* Broken pipe */ + HF_E_DOM, /* Math argument out of domain of func */ + HF_E_RANGE, /* Math result not representable */ + HF_E_DEADLK, /*Resource deadlock would occur*/ +}; + + + + +enum HFSYS_RUN_MODE_E +{ + HFSYS_STATE_RUN_THROUGH=0, + HFSYS_STATE_RUN_CMD=1, + HFSYS_STATE_RUN_GPIO, + HFSYS_STATE_RUN_PWM, + HFSYS_STATE_MAX_VALUE +}; + + + + +void HSF_API hfsys_reset(void); + +uint32_t HSF_API hfsys_get_time(void); + +int HSF_API hfsys_switch_run_mode(int mode); + +int HSF_API hfsys_get_run_mode(void); + +void HSF_API *hfmem_malloc(int size); +void HSF_API hfmem_free(void *pv); +uint32_t HSF_API hfsys_get_memory(void); + + +int HSF_API hfwifi_read_sta_mac_address(uint8_t *mac); +int HSF_IAPI hfwifi_write_sta_mac_address(uint8_t *mac, char *key); + +uint32_t HSF_API hfsys_get_reset_reason(void); + +void HSF_API hfsys_set_reset_reason(uint32_t reason); + +int HSF_API hfwifi_read_sle_mac_address(uint8_t *mac); + +int HSF_API hfwifi_write_sle_mac_address(uint8_t *mac); + +int HSF_API hfwifi_read_ap_mac_address(uint8_t *mac); + +unsigned int HSF_API hfsys_random(void); + +void HSF_API hfsys_set_time(uint32_t t); +#endif diff --git a/application/ws63/hsf/hfthread.h b/application/ws63/hsf/hfthread.h new file mode 100755 index 0000000..91e4035 --- /dev/null +++ b/application/ws63/hsf/hfthread.h @@ -0,0 +1,125 @@ + +#include "hsf.h" + +#define HFTHREAD_PRIORITIES_LOW (15) +#define HFTHREAD_PRIORITIES_MID (13) +#define HFTHREAD_PRIORITIES_NORMAL (10) +#define HFTHREAD_PRIORITIES_HIGH (8) +#define HFTHREAD_MAX_PRIORITIES (1) + + +typedef void (*PHFTHREAD_START_ROUTINE)( void * arg); + +typedef void* hfthread_sem_t; + +int hfthread_create(PHFTHREAD_START_ROUTINE routine, char * name, uint16_t stack_depth, void *parameters, uint32_t uxpriority, uint32_t *created_thread, uint32_t *stack_buffer); + +int hfsys_init(void); + +void HSF_API hfthread_delay(uint32_t ms); +void HSF_API hfthread_destroy(uint32_t task_id); + + +#define msleep(ms) hfthread_delay(ms) + + +typedef void* hfthread_mutex_t; + +#define NULL_MUTEX (hfthread_mutex_t)0 + +/** + * @brief create a mutex, not allow in ISR. + * + * @param[in] mutex: a pointer to mutex handle + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfthread_mutext_new(hfthread_mutex_t *pmutex); + +/** + * @brief free a mutex, not allow in ISR. + * + * @param[in] pmutex: the specified mutex handle + * @return[out] None + * @see None. + * @note None. + */ +void HSF_API hfthread_mutext_free(hfthread_mutex_t mutex); + +/** + * @brief releases ownership of the specified mutex object, not allow in ISR. + * + * @param[in] mutex: the specified mutex handle + * @return[out] None + * @see None. + * @note None. + */ +void HSF_API hfthread_mutext_unlock(hfthread_mutex_t mutex); + +/** + * @brief waits until the specified mutex is in the signaled state, not allow in ISR. + * + * @param[in] mutex: the specified mutex handle + * timeout: timeout interval in millisecond, value >= 10, 0xFFFFFFFF mean the function will return only when the mutex is signaled + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfthread_mutext_wait(hfthread_mutex_t mutex, uint32_t timeout); + +/** + * @brief try to wait a mutex, not allow in ISR. + * + * @param[in] mutex: the specified mutex handle + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfthread_mutext_trylock(hfthread_mutex_t mutex); + +#define hfthread_mutext_lock(_mu) hfthread_mutext_wait(_mu,0xFFFFFFFF) + + +/** + * @brief create a semaphore, not allow in ISR. + * + * @param[in] sem: a pointer to semaphore handle + * cnt: the count of the semaphore, maximum is 255 + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfthread_sem_new(hfthread_sem_t *sem,uint8_t cnt); + +/** + * @brief free a semaphore, not allow in ISR. + * + * @param[in] sem: the specified semaphore handle + * @return[out] None + * @see None. + * @note None. + */ +void HSF_API hfthread_sem_free(hfthread_sem_t sem); + +/** + * @brief increases the count of the specified semaphore object by 1. + * + * @param[in] sem: the specified semaphore handle + * @return[out] None + * @see None. + * @note None. + */ +void HSF_API hfthread_sem_signal(hfthread_sem_t sem); + +/** + * @brief wait until the specified mutex is in the signaled state or the time-out interval elapses, not allow in ISR. + * + * @param[in] sem: the specified semaphore handle + * timeout: timeout interval in millisecond, value >= 10, 0xFFFFFFFF mean the function will return only when the semaphore is signaled + * @return[out] 1-the state of the specified object is signaled, 0-the time-out interval elapsed, and the object's state is nonsignaled + * @see None. + * @note None. + */ +int HSF_API hfthread_sem_wait(hfthread_sem_t sem, uint32_t timeout); + diff --git a/application/ws63/hsf/hftime.h b/application/ws63/hsf/hftime.h new file mode 100755 index 0000000..527347f --- /dev/null +++ b/application/ws63/hsf/hftime.h @@ -0,0 +1,46 @@ +/* hftime.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_TIME_H_ +#define _HF_TIME_H_ + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include "hsf.h" + + +#ifdef CONFIG_NO_STRUCT_TIMEZONE +struct timezone +{ + int tz_minuteswest; + int tz_dsttime; +}; +#endif + +time_t time(time_t *timer); + + +#if !CONFIG_HAVE_SETTIMEOFDAY +int settimeofday(const struct timeval * tv, const struct timezone *tz); +#endif + +#if !CONFIG_HAVE_GETTIMEOFDAY +int gettimeofday(struct timeval * tv, struct timezone * tz); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/application/ws63/hsf/hfuart.h b/application/ws63/hsf/hfuart.h new file mode 100755 index 0000000..1f19010 --- /dev/null +++ b/application/ws63/hsf/hfuart.h @@ -0,0 +1,100 @@ + + +#ifndef _HF_UART_H_ +#define _HF_UART_H_ + +#include "hsf.h" +#include "ringbuf.h" +#include "hfthread.h" + + +#define DEBUG_LEVEL_CLOSE 0 + +#define DEBUG_LEVEL_NON -1 +#define DEBUG_LEVEL_CLOSE 0 +#define DEBUG_LEVEL_LOW 3 +#define DEBUG_LEVEL_MID 4 +#define DEBUG_LEVEL_HI 5 +#define DEBUG_LEVEL DEBUG_LEVEL_HI + + + +#define DEBUG_SMTLK DEBUG_LEVEL_MID +#define DEBUG_UPGRADE DEBUG_LEVEL_MID +#define DEBUG_ASSIS DEBUG_LEVEL_LOW //DEBUG_LEVEL_CLOSE +#define DEBUG_FLASH DEBUG_LEVEL_LOW +#define DEBUG_BOOTUP DEBUG_LEVEL_LOW +#define DEBUG_ATCMD DEBUG_LEVEL_LOW +#define DEBUG_CONFIG DEBUG_LEVEL_LOW + + +#define DEBUG_LEVEL_USER 10 +#define DEBUG_WARN (DEBUG_LEVEL_USER-2) +#define DEBUG_ERROR (DEBUG_LEVEL_USER-2) + +typedef void * hfuart_handle_t; + +typedef struct _HFUART_THREAD +{ + int uart_id; + hfuart_handle_t uart_handle; + char *uart_buf; + int uart_buf_size; +}HFUART_THREAD,*PHFUART_THREAD; + +typedef struct _HFUART +{ + unsigned char port; //端口 HF_UART0 0;HF_UART1 1; + char tx_enable; + char rx_enable; + char *rxbuf; //环形buff数据缓冲区 + struct ringbuf uart_rx_buf; //串口环形buff句柄 + volatile int b_wait_rx; + hfthread_sem_t rx_wait_event; //信号量 + char fc_enable; + char fc_full; + char valid; +}HFUART,*PHFUART; + + +void HSF_API HF_Debug(int debug_level, const char *format , ... ); + +#define hfdbg_error(...) HF_Debug(DEBUG_ERROR,"[ %d error %s %d]",hfsys_get_time(),__FUNCTION__,__LINE__); \ + HF_Debug(DEBUG_ERROR,__VA_ARGS__) +#define hfdbg_warn(...) HF_Debug(DEBUG_WARN,"[warnning %d %s %d]",hfsys_get_time(),__FUNCTION__,__LINE__); \ + HF_Debug(DEBUG_WARN,__VA_ARGS__) +#define u_printf(...) HF_Debug(DEBUG_LEVEL_USER,__VA_ARGS__) + + +int hfuart_config(hfuart_handle_t huart, int baudrate, ENCOMPARITY_E parity, ENCOMBITS_E databits, ENCOMSTOPBITS_E stopbits, ENCOMUARTCTL_E fc); + +hfuart_handle_t HSF_API hfuart_open(int uart_id); + +int HSF_API hfuart_recv(hfuart_handle_t huart,char *recv,uint32_t bytes,uint32_t timeouts); + +int HSF_API hfuart_send(hfuart_handle_t huart, char *data, uint32_t bytes, uint32_t timeouts); +int HSF_API hfuart_close(hfuart_handle_t huart); + + +int HSF_API hfdbg_get_level(void); +void HSF_API hfdbg_set_level(int level); + +/** + * @brief set uart parameters. + * + * @param[in] + * baud: 串口波特率 + * data_bits:数据位 参考ENCOMBITS_E + * stop_bits:停止位 参考ENCOMSTOPBITS_E + * parity :校验位 参考ENCOMPARITY_E + * len: the length, in bytes, of the data pointed to write + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note 立即生效需在hfnet_start_uart前设置,默认不保存flash,如需参数保存调用hfconfig_file_save();. + */ +int HSF_API hfset_uart_parameters(int baud,ENCOMBITS_E data_bits,ENCOMSTOPBITS_E stop_bits,ENCOMPARITY_E parity); + + + +#endif + diff --git a/application/ws63/hsf/hfupdate.h b/application/ws63/hsf/hfupdate.h new file mode 100755 index 0000000..238a56c --- /dev/null +++ b/application/ws63/hsf/hfupdate.h @@ -0,0 +1,137 @@ +/* hfupdate.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HF_UPDATE_H_ +#define _HF_UPDATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define HF_CONFIG_OTA_FLAG_REDAY (0x0A0A55A0) +#define HF_CONFIG_OTA_FLAG_OK (0x0505AA50) +#define HF_BOOT_CONFIG_MAGIC_CODE (0x48464254) +#define HF_CONFIG_OTA_FLAG_FAIL (0x5A5A5A00) + +#define HF_BOOT_RUN_MODE_NORMAL (0) +#define HF_BOOT_RUN_MODE_AUTO_UPGRADE (0xA5010202) +#define HF_BOOT_RUN_MODE_DEBUG (0xA5010203) + + +typedef enum HFUPDATE_TYPE +{ + HFUPDATE_SW=0, + HFUPDATE_CONFIG=1, + HFUPDATE_WIFIFW, + HFUPDATE_WEB, +}HFUPDATE_TYPE_E; + +typedef enum http_download_type{ + HTTP_DOWNLOAD_TYPE_TMP = 1, //下载到buff + HTTP_DOWNLOAD_TYPE_FLASH = 2, //下载到FLASH + HTTP_DOWNLOAD_LOCATION_UPGRADE = 4, //upgrade分区 + HTTP_DOWNLOAD_LOCATION_FLASH_UPGRADE = HTTP_DOWNLOAD_TYPE_FLASH|HTTP_DOWNLOAD_LOCATION_UPGRADE, //FLASH中upgrade分区 + HTTP_DOWNLOAD_LOCATION_WEB = 8, //web分区 + HTTP_DOWNLOAD_LOCATION_FLASH_WEB = HTTP_DOWNLOAD_TYPE_FLASH|HTTP_DOWNLOAD_LOCATION_WEB, //FLASH中web分区 +}http_download_type_t; + +int HSF_IAPI hfupdate_auto_upgrade(uint32_t flags); + +int HSF_IAPI http_download_enable_range(char enable); + +int HSF_IAPI hfupdate_auto_upgrade_start(void); + +int HSF_IAPI check_webpage_file_ok(char *addr, char *version); + + +/** + * @brief start OTA to update application. + * + * @param[in] type: update type, now only support 'HFUPDATE_SW' & 'HFUPDATE_WEB' + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note this function will need time to erase flash. + */ +int HSF_API hfupdate_start(HFUPDATE_TYPE_E type); + +/** + * @brief write update file. + * + * @param[in] type: update type, now only support 'HFUPDATE_SW' & 'HFUPDATE_WEB' + * offset: offset address, start from 0 + * data: a pointer to data + * len: the len of data + * @return[out] the length of write success + * @see None. + * @note this function will need some time to erase flash. + */ +int HSF_API hfupdate_write_file(HFUPDATE_TYPE_E type, uint32_t offset, uint8_t *data, int len); + +/** + * @brief complete update. + * + * @param[in] type: update type, now only support 'HFUPDATE_SW' & 'HFUPDATE_WEB' + * file_total_len: the len of file + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note return -1 means file type error, return -2 means file crc error. + */ +int HSF_API hfupdate_complete(HFUPDATE_TYPE_E type, uint32_t file_total_len); + +/** + * @brief download OTA file use http. + * + * @param[in] purl: http url + * @return[out] HF_SUCCESS-successfully, other value is failed + * @see None. + * @note None. + */ +int HSF_API hfupdate_fw_as_http(const char *purl); + +/** + * @brief get bootloader version. + * + * @param[in] version: the buffer to store bootloader version + * @return[out] the crc32 of bootloader, 0 is failed + * @see None. + * @note None. + */ +unsigned int HSF_API hfupdate_read_boot_ver(char *version); + +/** + * @brief check whether or not in updating + * + * @param[in] None + * @return[out] 0-not in updating, 1-in updating + * @see None. + * @note None. + */ +int HSF_API hfupdate_auto_upgrade_is_running(void); + +/** + * @desc: + * @params: start_range is 0,file_len is NULL when DISABLE_HTTP_DOWNLOAD_RANGE + * @param[in] purl: http url + * @param[in] p_data: a buffer or a FLASH address to store update file + * @param[in] len: the len of p_data FLASH + * @param[in] type: the HTTP Download data to LOCATION + * @param[in] start_range: Download from Start position + * @return[out] < 0 error numb , > 0 down file length + */ +int HSF_API http_download_file(const char *purl, char *p_data, uint32_t len, http_download_type_t type, int start_range, int *file_len); + + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/application/ws63/hsf/hfwifi.h b/application/ws63/hsf/hfwifi.h new file mode 100755 index 0000000..05f2efd --- /dev/null +++ b/application/ws63/hsf/hfwifi.h @@ -0,0 +1,84 @@ + +/* hfupdate.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + + +#ifndef _HF_WIFI_H_ +#define _HF_WIFI_H_ + +#define DEBUG_WIFI DEBUG_LEVEL_LOW + +#define AUTH_TYPE_OPEN 0 +#define AUTH_TYPE_SHARED 1 +#define AUTH_TYPE_WPAPSK 2 +#define AUTH_TYPE_WPA2PSK 3 +#define AUTH_TYPE_WPAPSKWPA2PSK 4 +#define AUTH_TYPE_WPAENT 5 +#define AUTH_TYPE_WPA3SAE 6 +#define AUTH_TYPE_WPA2PSKWPA3SAE 7 + +#define ENC_TYPE_NONE 0 +#define ENC_TYPE_WEP 1 +#define ENC_TYPE_TKIP 2 +#define ENC_TYPE_AES 3 +#define ENC_TYPE_TKIPAES 4 +#define ENC_TYPE_CCMP 5 + +#define ENC_TYPE_INVALID 255 + +#define WIFI_MODE_AP 0 +#define WIFI_MODE_STA 1 +#define WIFI_MODE_APSTA 2 +#define WIFI_MODE_NOSTART 0xFF + +#define WIFI_STATE_UNINIT 0 +#define WIFI_STATE_START 1 +#define WIFI_STATE_STOPPING 2 +#define WIFI_STATE_STOPPED 3 + +#define MAX_WIFI_SCAN_RESULT 50 + + + typedef struct + { + char ssid[65]; + uint8_t mac[20]; + char enc[25]; + char channl; + int sco; + int rssi; + }ScanResult_t; + + typedef struct _WIFI_SCAN_RESULT_ITEM + { + uint8_t auth; + uint8_t encry; + uint8_t channel; + uint8_t rssi; + char ssid[32+1]; + uint8_t mac[6]; + int rssi_dbm; + int sco; + }WIFI_SCAN_RESULT_ITEM,*PWIFI_SCAN_RESULT_ITEM; + + enum + { + HFWIFI_SCAN_EXIT=0, + HFWIFI_SCANING=1 + }; + typedef int (*hfwifi_scan_callback_ex_t)(PWIFI_SCAN_RESULT_ITEM,void*); + void wifi_auto_connect(void* arg); + void product_wifi_thread(void* arg); + int HSF_API hfwifi_transform_rssi(int rssi_dbm); + int HSF_API hfwifi_scan_ex(hfwifi_scan_callback_ex_t p_callback, void *ctx, unsigned char ch, unsigned char scan_time); + int HSF_API hfwifi_sta_get_current_rssi(int *dBm); + int HSF_API hf_get_wifi_state(void); + void HSF_API hf_set_wifi_state(int state); + + +#endif diff --git a/application/ws63/hsf/hsf.h b/application/ws63/hsf/hsf.h new file mode 100755 index 0000000..a3d3b73 --- /dev/null +++ b/application/ws63/hsf/hsf.h @@ -0,0 +1,103 @@ +/* hsf.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _HSF_H_ +#define _HSF_H_ + +#define HSF_API +#define HSF_IAPI HSF_API +#define USER_FUNC + + +#include +#include +#include +#include + +#ifndef BYTE +// typedef unsigned char BOOL; +typedef unsigned char BYTE; +typedef short SHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; +typedef int INT; +typedef unsigned int UINT; +typedef long LONG; +typedef unsigned long DWORD; +#endif + +#ifndef TRUE + #define TRUE 1 +#endif +#ifndef FALSE + #define FALSE 0 +#endif + +#define HF_SUCCESS 0 + +#ifdef __cplusplus +#define EXTERNC extern "C" +#else +#define EXTERNC extern +#include +//typedef unsigned char bool; +// #define true 1 +// #define false 0 +#endif + + +#ifndef NULL + #if defined(__cplusplus) + #define NULL 0 + #else + #define NULL ((void *) 0) + #endif +#endif + + +// #define _HSF_ + +#ifndef WEAK +#define WEAK __attribute__ ((weak)) +#endif + +#define FUNC_IN_RAM __attribute__((section(".tcm_code"))) +// #include "hferrno.h" +#include "hfconfig.h" +#include "hfuart.h" +#include "hfat.h" +#include "hfsys.h" +#include "hfflash.h" +#include "hfthread.h" +#include "hfflashlayout.h" +#include "hfproduct.h" +#include "hfnet.h" +// #include "hf_debug.h" +#include "hfupdate.h" +#include "hfcrypto.h" +#include "hfgpio.h" +#include "hfwifi.h" +#include "hfnet.h" +#include "hfntp.h" + +#include "debug_print.h" +#define DEBUG_NTP DEBUG_LEVEL_LOW + +extern const char *HILINK_GetSdkVersion(void); + +#define GLOBAL_VER HILINK_GetSdkVersion() + +#ifdef CONFIG_FLASH_SIZE_4MB + #define GLOBAL_LVER " (2025-04-11 14:00 4M)" +#elif defined CONFIG_FLASH_SIZE_8MB + #define GLOBAL_LVER "06 (2024-09-20 17:00 8M)" +#endif + + +#endif + diff --git a/application/ws63/hsf/httpclient.h b/application/ws63/hsf/httpclient.h new file mode 100755 index 0000000..005d5a7 --- /dev/null +++ b/application/ws63/hsf/httpclient.h @@ -0,0 +1,623 @@ +/*! \file httpc.h + * \brief HTTP Client Module + * + * The HTTP Client module implements the functionality to perform HTTP + * operations like GET and POST on a remote web server. The HTTP client handles + * chunked encoding making it transparent to the user. It also supports + * persistent connections with the web server. Multiple HTTP requests can thus + * be channelled through the same persistent connection with the server. + * + * \section httpc_usage Usage + * + * The typical HTTP Client usage scenario is as follows: + * + * -# Initiate a connection with the remote Web Server using the + * http_open_session() call. + * -# Prepare the request with a call to http_prepare_req. The mandatory + * fields are filled depending on the members set in httpc_req_t. If some + * default fields are to be set, this is set by enabling the + * corresponding flag bits passed to http_prepare_req. If more custom + * headers are to be added please add them using the call add_header. + * -# Send one or more HTTP requests to the server using the + * http_prepare_req and http_send_request pair together. . The \ref + * httpc_req_t structure should be populated with the desired fields for + * each call if changed + * -# An optional call to http_get_response_hdr() can be made if the application + * wishes to determine certain characteristics of the HTTP response. + * -# Mutiple calls to http_read_content() are made for reading the response of + * the remote Web Server. + * -# Once all the HTTP requests have been made, the connection with the remote + * server is terminated using the http_close_session() call. + * + */ + +/* + * Copyright 2008-2012, Marvell International Ltd. + * All Rights Reserved. + */ + +#ifndef _HTTPC_H_ +#define _HTTPC_H_ +#include + +#include +#include + +// #define CONFIG_ENABLE_TLS + +// #ifdef CONFIG_ENABLE_TLS +typedef void* tls_handle_t; +typedef void tls_init_config_t; +// #endif /* CONFIG_ENABLE_TLS */ + +#ifdef __cplusplus +extern "C"{ +#endif + +typedef int http_session_t; + +/* Request methods */ +typedef enum { + HTTP_OPTIONS, /* request to server for communication options */ + HTTP_GET, /* retrieve information */ + HTTP_HEAD, /* get meta-info */ + HTTP_POST, /* request to accept new sub-ordinate of resource */ + HTTP_PUT, /* modify or create new resource referred to by URI */ + HTTP_DELETE, /* delete the resource */ + HTTP_TRACE, /* echo */ + HTTP_CONNECT, /* do we need this ? */ +} http_method_t; + +typedef enum { + HTTP_VER_1_0, + HTTP_VER_1_1, +} http_ver_t; + + +/* + * The OR of zero or more flags below is passed to the function + * \ref http_prepare_req. If the a flag is passed the corresponding HTTP + * header field is added to the HTTP header. The values added will be + * default ones. + */ +typedef enum { + HDR_ADD_DEFAULT_USER_AGENT = 0x0001, + /* Note: This flag is not necessary to set up persistent + * connections in HTTP 1.1. However, if you want the server to + * respond with persistent connection timeout values you may need + * to add this flag. These timeout values are used to find out how + * long a persistent connection will be kept alive by the + * server. */ + HDR_ADD_CONN_KEEP_ALIVE = 0x0002, + HDR_ADD_CONN_CLOSE = 0x0004, + HDR_ADD_TYPE_CHUNKED = 0x0008, +} http_hdr_field_sel_t; + + +#define STANDARD_HDR_FLAGS \ + (HDR_ADD_DEFAULT_USER_AGENT) + +/* + * Note 1: A resource is a part of the string immediately after the + * hostname[:portno] part of the URL. In the URL, + * [http://]hostname[:portno][/path/to/resource], + * "/path/to/resource" part is called as a resource. It starts with the + * character '/'. + */ +/** The HTTP Client's Request structure + * + * \par + * The application should fill up this structure and pass it to the + * http_prepare_req() function while making an HTTP request. More name-value + * fields can be added to HTTP header using http_add_header(). + */ +typedef struct { + /** The Type of HTTP Request */ + http_method_t type; + /** The target resource for the HTTP Request. A complete URL is also + * accepted. + */ + const char *resource; + /** The HTTP Protocol Version */ + http_ver_t version; + const char *content; + /** The length of the data pointed to by \a content above. This is + * don't-care if the content is set to NULL + */ + int content_len; +} httpc_req_t; + +typedef struct { + const char *protocol; + http_ver_t version; + int status_code; + const char *reason_phrase; /* verbose string describing status code */ + const char *server; + time_t modify_time; /* time when the resource was last modified */ + const char *content_type; + const char *content_encoding; + bool keep_alive_ack; + int keep_alive_timeout; /* Server timeout */ + int keep_alive_max; /* Max time for which a persistent + connection will be open, irrespective of + connection activity */ + bool chunked; + uint32_t content_length; /* This will be 0 if chunked == TRUE */ +} http_resp_t; + +typedef struct { + char *name; + char *value; +} http_header_pair_t; + +typedef struct { + const char *scheme; + const char *hostname; + unsigned portno; + const char *resource; +} parsed_url_t; + +/** HTTPC Error Codes **/ + +enum wm_httpc_errno { + WM_E_HTTPC_ERRNO_START = MOD_ERROR_START(MOD_HTTPC), + /* TCP connection failed (maybe due to unreachable server) */ + WM_E_HTTPC_TCP_CONNECT_FAIL, + /* HTTP File not found */ + WM_E_HTTPC_FILE_NOT_FOUND, + /* HTTP Bad Request */ + WM_E_HTTPC_BAD_REQUEST, + /* TLS not enabled */ + WM_E_HTTPC_TLS_NOT_ENABLED, +}; + + +/* Status codes */ +#define HTTP_RESP_INFORMATIONAL(x) (x >=100 && < 200) +#define HTTP_RESP_SUCCESS(x) (x >= 200 && x < 300) +#define HTTP_RESP_REDIR(x) (x >= 300 && x < 400) +#define HTTP_RESP_CLIENT_ERR(x) (x >= 400 && x < 500) +#define HTTP_RESP_SERVER_ERR(x) (x >= 500 && x < 600) + +/* + * These macros are not of any use to the HTTP client itself. They are used + * by the users of the HTTP client. This list may be extended if required + */ +#define HTTP_OK 200 +#define HTTP_CREATED 201 +#define HTTP_ACCEPTED 202 +#define HTTP_FOUND 302 +#define HTTP_NOT_MODIFIED 304 + +#define HTTP_BAD_REQUEST 400 +#define HTTP_NOT_AUTH 401 +#define HTTP_FORBIDDEN 403 +#define HTTP_NOT_FOUND 404 + +/** + * If the given URL has a scheme field, and it is https then the http + * client will auto-switch to SSL mode, irrespective of the TLS_ENABLE + * flag below. + */ +typedef enum { + /** Pass this flag when you want the connection to be SSL based */ + TLS_ENABLE = 0x01, +} http_open_flags_t; + +/** + * Start an HTTP session. + * + * @par + * This function starts a new HTTP session. It will create a socket and + * then connect to the server. + * + * @param[in,out] handle Pointer to a handle for the session. Will be + * assigned by the callee. + * @param[in] hostname Host name or IP address. The hostname should be in + * the format [http://]hostname[:portno][/path/to/resource]. The fields + * between the square brackets above are optional. The part specifying + * the resource will be ignored. The resource detail is expected by the \a + * http_send_request API to be called later after calling current function. + * @param[in] flags This is OR of the flags mentioned in enum + * \ref http_open_flags_t. Please look at the declaration of the enum for + * more information. + * @param[in] cfg This is a pointer of the type + * \ref tls_init_config_t. This will be passed verbatim to the tls + * layer. Please look at the wm-tls.h for the structure members. \b If TLS + * (secure connection) is not needed please pass NULL. + * @param[in] retry_cnt On some systems with constrained network resources, + * only a limited sockets can be active at any given time. If the socket + * creation fails, http_open_session will wait for some time and try to create + * the socket again for retry_cnt number of times. If 0 is passed then it will + * try default number of times depending on the platform. 0 is the recommended + * option. + * + * @return WM_SUCCESS on success + * @return -WM_E_INVAL if any of the arguments were invalid + * @return -WM_FAIL if the function was unable to initiate an HTTP session with + * the server. + */ +int http_open_session(http_session_t * handle, const char *hostname, + int flags, const tls_init_config_t *cfg, + int retry_cnt); + +#define hfhttp_open_session http_open_session + +/** + * Prepare the HTTP header. + * + * This function will prepare an HTTP request before sending out an HTTP + * request using the function \ref http_send_request. Calling this function is + * mandatory before calling \ref http_send_request. + * + * @pre \ref http_open_session + * + * @param[in] handle Handle returned from the call to \a http_open_session + * @param[in] req Allocated and initialized \ref httpc_req_t structure. + * @param[in] field_flags Bitwise OR of flags of enum \ref + * http_hdr_field_sel_t as required by the caller. + * + * @note The field_flags parameter is a way to request the http client to + * use default field values for standard fields. If the corresponding bits + * are not set then the respective fields are not added. The user can add + * any custom fields including the standard ones using the API + * \ref http_add_header + * + * @return Standard wmsdk return codes. + */ +int http_prepare_req(http_session_t handle, const httpc_req_t *req, + http_hdr_field_sel_t field_flags); + +#define hfhttp_prepare_req http_prepare_req + +/** + * Add custom http headers to the partial generated header. + * + * This function allows the caller to add custom headers to the partial + * http header generated by earlier call to \ref http_prepare_req. + * + * @note This function is optional and needs to be called only if custom + * headers (or standard headers with non-default values) are to be added. + * + * @pre \ref http_prepare_req + * + * @param[in] handle Handle returned from the call to \a http_open_session + * @param[in] name The name of the field. e.g User-Agent or + * If-Modified-Since + * @param[in] value Value associated with the name given above. + * + * @return Standard wmsdk value. + */ +int http_add_header(http_session_t handle, const char *name, + const char *value); + +#define hfhttp_add_header http_add_header + +/** + * Perform an HTTP request. + * + * @par + * This function will peform an HTTP request. + * + * @note If this function fails and the caller decides to abandon this + * session altogether it needs to call http_close_session() + * explicitly. Failure to do this will cause undefined behaviour. + * + * @pre \a http_prepare_req mandatory. \a http_add_header optional. + * + * @param[in] handle Handle returned from the call to \a http_open_session + * @param[in] req The \httpc_req_t structure filled up with appropriate + * parameters as sent earlier to \ref http_prepare_req + * + * @return WM_SUCCESS on success + * @return -WM_E_IO if failed to send data to network + * @return -WM_E_INVAL for an invalid arguments. + */ +int http_send_request(http_session_t handle, const httpc_req_t * req); + +#define hfhttp_send_request http_send_request +/** + * Get the HTTP response header + * + * @par + * This function parses the response header received from the server and + * populates the \a http_resp_t structure and returns the pointer to this + * structure. The structure \a http_resp_t is allocated by the callee. + * + * @par + * The caller is expected to analyse this information to find out the + * result of the earlier request sent through http_send_request(). If the + * earlier request was HTTP_GET then the caller will need to call + * http_read_content() to read the data sent by the server. + * + * @note Calling this function is \b optional. If the caller does not want to + * read/analyse the header and knows beforehand what to expect, s/he can + * directly call http_read_content(). The function \a http_read_content + * will internally read the HTTP response header. However, the function + * \a http_read_content will return an error if the HTTP status code + * returned is not 200. If you need to read content in cases where the + * return status code is other than 200 you need to call \ref + * http_get_response_hdr first. + * + * @note If this function fails and the caller decides to abandon this + * session altogether it needs to call http_close_session() + * explicitly. Failure to do this will cause undefined behaviour. + * + * @pre \a http_send_request is called before this call. + * + * @param[in] handle Handle returned from the call to \a http_new_session + * @param[in,out] resp Pointer to a pointer of type \a http_resp_t. The + * structure will be allocted by the callee. + * + * @return WM_SUCCESS on success + * @return -WM_FAIL on error + */ +int http_get_response_hdr(http_session_t handle, http_resp_t ** resp); +#define hfhttp_get_response_hdr http_get_response_hdr +/** + * Get a particular HTTP response header value. + * + * @par + * This function parses the response header received from the server and + * returns the value corresponding to a given name. + * + * @par + * The caller is not expected to call \ref http_get_response_hdr before + * this. However, calling \ref http_get_response_hdr is recommended so that + * the user gets to know the exact status of the HTTP operation before he + * tries to extract any field not present in structure \ref http_resp_t. + * + * @note Calling this function is \b optional. If the caller does not want to + * read/analyse the header and knows beforehand what to expect, s/he can + * directly call http_read_content(). The function \a http_read_content + * will internally read the HTTP response header. However, the function + * \a http_read_content will return an error if the HTTP status code + * returned is not 200. If you need to read content in cases where the + * return status code is other than 200 you need to call \ref + * http_get_response_hdr or the current function first. + * + * @note If this function fails and the caller decides to abandon this + * session altogether it needs to call http_close_session() + * explicitly. Failure to do this will cause undefined behaviour. + * + * @pre \a http_send_request is called before this call. Calling \ref + * http_get_response_hdr is \b not mandatory but recommended. + * + * @param[in] handle Handle returned from the call to \a http_new_session + * @param[in] header_name The name of the field whose value you wish to + * know + * @param[in,out] value A pointer which will point to the value + * corresponding to the name passed as second parameter. + * + * @return WM_SUCCESS on success + * @return -WM_FAIL on error + */ + +int http_get_response_hdr_value(http_session_t handle, + const char *header_name, char **value); + +#define hfhttp_get_response_hdr_value http_get_response_hdr_value +/** + * Get requested number of HTTP response header name-value pairs. + * + * @par + * This function parses the response header received from the server and + * returns requested number of HTTP response header name-value pairs. + * + * @par + * The caller is not expected to call \ref http_get_response_hdr before + * this. However, calling \ref http_get_response_hdr is recommended so that + * the user gets to know the exact status of the HTTP operation before he + * tries to extract any field not present in structure \ref http_resp_t. + * + * @note Calling this function is \b optional. If the caller does not want to + * read/analyse the header and knows beforehand what to expect, s/he can + * directly call http_read_content(). The function \a http_read_content + * will internally read the HTTP response header. However, the function + * \a http_read_content will return an error if the HTTP status code + * returned is not 200. If you need to read content in cases where the + * return status code is other than 200 you need to call \ref + * http_get_response_hdr or the current function first. + * + * @note If this function fails and the caller decides to abandon this + * session altogether it needs to call http_close_session() + * explicitly. Failure to do this will cause undefined behaviour. + * + * @pre \a http_send_request is called before this call. Calling \ref + * http_get_response_hdr is \b not mandatory but recommended. + * + * @param[in] handle Handle returned from the call to \a http_new_session + * @param[in,out] arr A pointer that points to an array of the + * structure to hold the response header name-value pairs. + * This array needs to be pre-allocated and its pointer is to be passed, + * this pointer shall point to the array of requested number of + * response header name-value pairs. + * @param[in,out] count An interger pointer that points to the number of + * response header name-value pairs that the user wants. + * This has to be passed by the user and it is later updated to the + * actual number of response header name-value pairs that were filled + * in the array mentioned above. + * @return WM_SUCCESS on success + * @return -WM_FAIL on error + */ + +int http_get_response_hdr_all(http_session_t handle, http_header_pair_t *arr, + int *count); + +#define hfhttp_get_response_hdr_all http_get_response_hdr_all +/** + * Read data content from the stream. + * + *@par + * This function will read the data sent by the server. + * + * @par + * The data transfer from the server to the client may be chunked. This + * fact will be reported in the response structure \ref http_resp_t returned + * in a previous call to http_get_response_hdr(). Notwithstanding this + * information, chunked data handling is transparent to the + * caller. Irrespective of the transfer type, this function should be called + * repeatedly till the return value of the function is zero. + * + * @note If this function fails and the caller decides to abandon this + * session altogether it needs to call http_close_session() + * explicitly. Failure to do this will cause undefined behaviour. + * + * @param[in] handle Handle returned from the call to http_new_session() + * @param[in, out] buf Caller allocated buffer of size max_len + * @param[in] Size of the buffer. The data read will be less than or equal + * to this size, depending on the size of the resource. + * + * @return On success, the number of bytes read is returned. Return value + * of zero is \a not an error case and should be treated as a signal that + * server is done with sending the data. + * @return -WM_FAIL if this function is called again after the previous call + * retuned 0 or for any other error. + */ + +int http_read_content(http_session_t handle, void *buf, uint32_t max_len); +#define hfhttp_read_content http_read_content +/** + * Parse the given string into URL subcomponents. + * + * The hostname string syntax is: + *[scheme://]hostname[:port][/path_to_resource?query_string#fragment_id] + * The fields between the square brackets above are optional. + * + * @note Buffer management: To free the caller of the task of + * allocating multiple buffers of magic size to store each of the + * subcomponents we use the following strategy. This function takes a tmp + * buffer, allocted (static or dynamic) by the caller to store the + * subcomponents. The caller needs to allocate this buffer with size equal + * to (strlen(URL) + 10). When this function returns, the pointers in the + * parsed_url structure will point to appropriate address in this + * buffer. The caller may free this buffer after usage of the + * sub-components is complete. Freeing before that will cause undefined behavior. + * + * @param[in] URL Pointer to the string containing the URL. This function + * will not modify this argument. + * @param[in] tmp_buf A buffer where the strings will be stored after + * parsing. Needs to be allocated by the caller and should be of size + * atleast 10 greater than size of the URL string passed as first + * argument. + * @param[in] tmp_buf_len Size of the caller allocated, temporary buffer + * sent as second argument. + * @param[in, out] Pointer to an allocated structure. The member pointers + * will point to the appropriate address in the temporary buffer holding + * the NULL terminated string corresponding to the subcomponent. + * + */ +int http_parse_URL(const char *URL, char *tmp_buf, int tmp_buf_len, + parsed_url_t * parsed_url); + +#define hfhttp_parse_URL http_parse_URL +/** + * HTTP lowlevel read + * + * This API is present to serve clients which want to handle the + * HTTP stream directly. This is useful for handling websockets for e.g. + * + * @warning This is not for general users of HTTP client API. Normal HTTP + * transactions do not need this API. + * + * @note Once this API used no other API from the HTTP API set, except \a + * http_close_session, can be used. This is because once this API is used + * the HTTP client loses track of the stream and only the caller using the + * API can know the state of the stream. + * + * @param[in] handle Handle returned from the call to http_new_session() + * @param[in, out] buf Pointer to an allocated buffer of size equal to or + * more than the value of the third parameter maxlen + * @param[in] maxlen The maximum number of bytes to be read from the + * network. Note that the actual read bytes can be less than this. + * + * @return Number of bytes read. -WM_E_INVAL is returned in case of invalid + * parameters. Standard libc error codes are returned in case when there + * other problems. + */ + +int http_lowlevel_read(http_session_t handle, void *buf, unsigned maxlen); + +/** + * HTTP lowlevel write + * + * This API is present to serve clients which want to handle the + * HTTP stream directly. This is useful for handling websockets for e.g. + * + * @warning This is not for general users of HTTP client API. Normal HTTP + * transactions do not need this API. + * + * @note Once this API used no other API from the HTTP API set, except \a + * http_close_session, can be used. This is because once this API is used + * the HTTP client loses track of the stream and only the caller using the + * API can know the state of the stream. + * + * @param[in] handle Handle returned from the call to http_new_session() + * @param[in, out] buf Pointer to a buffer which has the data to be written + * out. + * @param[in] maxlen The number of bytes to be written to the + * network. + * + * @return Number of bytes written. -WM_E_INVAL is returned in case of + * invalid parameters. Standard libc error codes are returned in case when + * there other problems. + */ + +int http_lowlevel_write(http_session_t handle, const void *buf, unsigned len); + +/** + * HTTP write chunked + * + * This API is used for chunked transfer encoding + * + * @note To end the chunked data transfer, this function should be called with + * len=0, buf may be NULL + * + * @param[in] handle Handle retrieved from the call to http_open_session + * @param[in] data Pointer to the buffer to be posted + * @param[in] len The number of bytes to be posted + * @return WM_SUCCESS is returned on success. -WM_E_INVAL is returned in case + * of invalid parameters. -WM_FAIL is returned if session is invalid. + * Standard libc error codes are returned when there are other problems. + */ + +int httpc_write_chunked(http_session_t handle, const char *data, int len); + +/** + * Close the session. + * + * @par + * This function will close the session represented by the given + * handle. The socket associated with this session will be closed and thus + * the TCP connection with the server will be terminated. No requests on + * this same session will succeed after this function is called. + * + * @note The response structure \ref http_resp_t returned earlier from + * http_get_response_hdr() will be invalid after this call. + * + * @param[in] handle Handle returned from the previous call to + * http_new_session(). The handle will be set to NULL by the callee thus + * effectively blocking futher requests on the same session handle. + * + */ +void http_close_session(http_session_t * handle); + +#define hfhttp_close_session http_close_session + +int http_check_data_ready(http_session_t handle,uint32_t timeous); +int hfhttp_sock_check(http_session_t handle,uint32_t timeous); +void hfhttp_set_init_state(http_session_t handle); + +#define hfhttp_check_data_ready http_check_data_ready + +int http_read_content_timeout(http_session_t handle, void *buf, uint32_t max_len,uint32_t timeouts); +#define hfhttp_read_content_timeout http_read_content_timeout + +int http_read_content_length(http_session_t handle); +#define hfhttp_read_content_length http_read_content_length + +#ifdef __cplusplus +} +#endif + +#endif /* _HTTPC_H_ */ diff --git a/application/ws63/hsf/ringbuf.h b/application/ws63/hsf/ringbuf.h new file mode 100755 index 0000000..9cf5c3b --- /dev/null +++ b/application/ws63/hsf/ringbuf.h @@ -0,0 +1,143 @@ +/** \addtogroup lib + * @{ */ + +/** + * \defgroup ringbuf Ring buffer library + * @{ + * + * The ring buffer library implements ring (circular) buffer where + * bytes can be read and written independently. A ring buffer is + * particularly useful in device drivers where data can come in + * through interrupts. + * + */ +/* + * Copyright (c) 2008, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute 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 INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * Header file for the ring buffer library + * \author + * Adam Dunkels + */ + +#ifndef __RINGBUF_H__ +#define __RINGBUF_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief Structure that holds the state of a ring buffer. + * + * This structure holds the state of a ring buffer. The + * actual buffer needs to be defined separately. This + * struct is an opaque structure with no user-visible + * elements. + * + */ +struct ringbuf { + uint8_t *data; + uint16_t mask; + + /* XXX these must be 8-bit quantities to avoid race conditions. */ + uint16_t put_ptr, get_ptr; +}; + +/** + * \brief Initialize a ring buffer + * \param r A pointer to a struct ringbuf to hold the state of the ring buffer + * \param a A pointer to an array to hold the data in the buffer + * \param size_power_of_two The size of the ring buffer, which must be a power of two + * + * This function initiates a ring buffer. The data in the + * buffer is stored in an external array, to which a + * pointer must be supplied. The size of the ring buffer + * must be a power of two and cannot be larger than 128 + * bytes. + * + */ +void ringbuf_init(struct ringbuf *r, uint8_t *a, + uint16_t size_power_of_two); + +/** + * \brief Insert a byte into the ring buffer + * \param r A pointer to a struct ringbuf to hold the state of the ring buffer + * \param c The byte to be written to the buffer + * \return Non-zero if there data could be written, or zero if the buffer was full. + * + * This function inserts a byte into the ring buffer. It + * is safe to call this function from an interrupt + * handler. + * + */ +int ringbuf_put(struct ringbuf *r, uint8_t c); + + +/** + * \brief Get a byte from the ring buffer + * \param r A pointer to a struct ringbuf to hold the state of the ring buffer + * \return The data from the buffer, or -1 if the buffer was empty + * + * This function removes a byte from the ring buffer. It + * is safe to call this function from an interrupt + * handler. + * + */ +int ringbuf_get(struct ringbuf *r); + +/** + * \brief Get the size of a ring buffer + * \param r A pointer to a struct ringbuf to hold the state of the ring buffer + * \return The size of the buffer. + */ +int ringbuf_size(struct ringbuf *r); + +/** + * \brief Get the number of elements currently in the ring buffer + * \param r A pointer to a struct ringbuf to hold the state of the ring buffer + * \return The number of elements in the buffer. + */ +int ringbuf_elements(struct ringbuf *r); + +int +ringbuf_gets(struct ringbuf *r,uint8_t *data,int size); + +#ifdef __cplusplus +} +#endif + + +#endif /* __RINGBUF_H__ */ diff --git a/application/ws63/hsf/xmodem.h b/application/ws63/hsf/xmodem.h new file mode 100755 index 0000000..02c059c --- /dev/null +++ b/application/ws63/hsf/xmodem.h @@ -0,0 +1,32 @@ + /* xmodem.h + * + * Copyright (C) 2017 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#ifndef _XMODEM_H_ +#define _XMODEM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef int (*xmodem_send_callback_t)(unsigned char *data, int len); + +typedef int (*xmodem_recv_callback_t)(unsigned char *data, int len, int timeout); + +typedef int (*xmodem_setfile_callback_t)(unsigned char *data, int len, unsigned int offset); + + +int xmodem_receive_process(int wait, xmodem_send_callback_t send, xmodem_recv_callback_t recv, xmodem_setfile_callback_t write); + + +#ifdef __cplusplus +} +#endif + +#endif/* _XMODEM_H_ */ + diff --git a/application/ws63/user_main/CMakeLists.txt b/application/ws63/user_main/CMakeLists.txt new file mode 100755 index 0000000..feab344 --- /dev/null +++ b/application/ws63/user_main/CMakeLists.txt @@ -0,0 +1,73 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) ShangHai High-flying Electronics Technology Co.,Ltd 2024-2024. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "user_main") + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/app_main.c +) +if (DEFINES MATCHES "HF_MCU_OTA") + list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/mcu_update.c) +endif() +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR} +) + +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES +) + +set(PUBLIC_DEFINES +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS #当前组件需要对外提供的编译选项 + #-Wno-error=maybe-uninitialized #变量未初始化 + #-Wno-error=pointer-sign #传递参数类型不匹配 + #-Wno-error=char-subscripts #使用char类作为数组下标,char有符号 + #-Wno-error=unused-label #未使用的标签,比如用goto + #-Wno-error=strict-prototypes #函数的声明或定义没有参数 + #-Wno-unused-parameter #未使用的函数参数 + #-Wno-unused-variable #未使用的变量 + #-Wno-unused-function #声明但未使用函数 + #-Wno-unused-but-set-variable #设置了但未使用的变量 + #-Wsign-compare #有符号与无符号比较 + #-Wno-error=pointer-arith + #-Wno-error=sign-compare + #-Wno-error=jump-misses-init + #-Wno-error=incompatible-pointer-types + #-Wno-error=logical-op + #-Wno-error=empty-body +) + +set(COMPONENT_CCFLAGS #当前组件内部生效的编译选项 + -Wno-error=maybe-uninitialized #变量未初始化 + -Wno-error=pointer-sign #传递参数类型不匹配 + -Wno-error=char-subscripts #使用char类作为数组下标,char有符号 + -Wno-error=unused-label #未使用的标签,比如用goto + -Wno-error=strict-prototypes #函数的声明或定义没有参数 + -Wno-unused-parameter #未使用的函数参数 + -Wno-unused-variable #未使用的变量 + -Wno-unused-function #声明但未使用函数 + -Wno-unused-but-set-variable #设置了但未使用的变量 + -Wsign-compare #有符号与无符号比较 + -Wno-error=pointer-arith + -Wno-error=sign-compare + -Wno-error=jump-misses-init + -Wno-error=incompatible-pointer-types + -Wno-error=logical-op + -Wno-error=empty-body +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + true +) + +build_component() diff --git a/application/ws63/user_main/app_main.c b/application/ws63/user_main/app_main.c new file mode 100755 index 0000000..17a90bb --- /dev/null +++ b/application/ws63/user_main/app_main.c @@ -0,0 +1,258 @@ +/* assis_thread.c + * + * Copyright (C) 2024 ShangHai High-flying Electronics Technology Co.,Ltd. + * + * This file is part of HSF. + * + */ + +#include "hsf.h" +#include "spotlight.h" +#ifdef HF_MCU_OTA +#include "mcu_update.h" +#endif +int g_module_id = HFM_TYPE_LPT262; +const int hf_lpt_262_gpio_fid_to_pid_map_table[HFM_MAX_FUNC_CODE]= +{ + HFM_NOPIN, //HFGPIO_F_JTAG_TCK + HFM_NOPIN, //HFGPIO_F_JTAG_TDO + HFM_NOPIN, //HFGPIO_F_JTAG_TDI + HFM_NOPIN, //HFGPIO_F_JTAG_TMS + HFM_NOPIN, //HFGPIO_F_USBDP + HFM_NOPIN, //HFGPIO_F_USBDM + LPT26x_GPIO17, //HFGPIO_F_UART0_TX + HFM_NOPIN, //HFGPIO_F_UART0_RTS + LPT26x_GPIO18, //HFGPIO_F_UART0_RX + HFM_NOPIN, //HFGPIO_F_UART0_CTS + HFM_NOPIN, //HFGPIO_F_SPI_MISO + HFM_NOPIN, //HFGPIO_F_SPI_CLK + HFM_NOPIN, //HFGPIO_F_SPI_CS + HFM_NOPIN, //HFGPIO_F_SPI_MOSI + LPT26x_GPIO15, //HFGPIO_F_UART1_TX, + HFM_NOPIN, //HFGPIO_F_UART1_RTS, + LPT26x_GPIO16, //HFGPIO_F_UART1_RX, + HFM_NOPIN, //HFGPIO_F_UART1_CTS, + + LPT26x_GPIO2, //HFGPIO_F_NLINK + LPT26x_GPIO10, //HFGPIO_F_NREADY + LPT26x_GPIO5, //HFGPIO_F_NRELOAD + + HFM_NOPIN, //HFGPIO_F_SLEEP_RQ + HFM_NOPIN, //HFGPIO_F_SLEEP_ON + + HFM_NOPIN, //HFGPIO_F_WPS + HFM_NOPIN, //HFGPIO_F_RESERVE1 + + HFM_NOPIN, //HFGPIO_F_RESERVE2 + HFM_NOPIN, //HFGPIO_F_RESERVE3 + HFM_NOPIN, //HFGPIO_F_RESERVE4 + HFM_NOPIN, //HFGPIO_F_RESERVE5 + + HFM_NOPIN, //HFGPIO_F_USER_DEFINE +}; + +const int hf_lpt_263_gpio_fid_to_pid_map_table[HFM_MAX_FUNC_CODE]= +{ + HFM_NOPIN, //HFGPIO_F_JTAG_TCK + HFM_NOPIN, //HFGPIO_F_JTAG_TDO + HFM_NOPIN, //HFGPIO_F_JTAG_TDI + HFM_NOPIN, //HFGPIO_F_JTAG_TMS + HFM_NOPIN, //HFGPIO_F_USBDP + HFM_NOPIN, //HFGPIO_F_USBDM + LPT26x_GPIO17, //HFGPIO_F_UART0_TX + HFM_NOPIN, //HFGPIO_F_UART0_RTS + LPT26x_GPIO18, //HFGPIO_F_UART0_RX + HFM_NOPIN, //HFGPIO_F_UART0_CTS + HFM_NOPIN, //HFGPIO_F_SPI_MISO + HFM_NOPIN, //HFGPIO_F_SPI_CLK + HFM_NOPIN, //HFGPIO_F_SPI_CS + HFM_NOPIN, //HFGPIO_F_SPI_MOSI + LPT26x_GPIO15, //HFGPIO_F_UART1_TX, + HFM_NOPIN, //HFGPIO_F_UART1_RTS, + LPT26x_GPIO16, //HFGPIO_F_UART1_RX, + HFM_NOPIN, //HFGPIO_F_UART1_CTS, + + LPT26x_GPIO7, //HFGPIO_F_NLINK + LPT26x_GPIO8, //HFGPIO_F_NREADY + LPT26x_GPIO9, //HFGPIO_F_NRELOAD + + HFM_NOPIN, //HFGPIO_F_SLEEP_RQ + HFM_NOPIN, //HFGPIO_F_SLEEP_ON + + HFM_NOPIN, //HFGPIO_F_WPS + HFM_NOPIN, //HFGPIO_F_RESERVE1 + + HFM_NOPIN, //HFGPIO_F_RESERVE2 + HFM_NOPIN, //HFGPIO_F_RESERVE3 + HFM_NOPIN, //HFGPIO_F_RESERVE4 + HFM_NOPIN, //HFGPIO_F_RESERVE5 + + HFM_NOPIN, //HFGPIO_F_USER_DEFINE +}; + +const int hf_lpt_162_gpio_fid_to_pid_map_table[HFM_MAX_FUNC_CODE]= +{ + HFM_NOPIN, //HFGPIO_F_JTAG_TCK + HFM_NOPIN, //HFGPIO_F_JTAG_TDO + HFM_NOPIN, //HFGPIO_F_JTAG_TDI + HFM_NOPIN, //HFGPIO_F_JTAG_TMS + HFM_NOPIN, //HFGPIO_F_USBDP + HFM_NOPIN, //HFGPIO_F_USBDM + LPT26x_GPIO17, //HFGPIO_F_UART0_TX + HFM_NOPIN, //HFGPIO_F_UART0_RTS + LPT26x_GPIO18, //HFGPIO_F_UART0_RX + HFM_NOPIN, //HFGPIO_F_UART0_CTS + HFM_NOPIN, //HFGPIO_F_SPI_MISO + HFM_NOPIN, //HFGPIO_F_SPI_CLK + HFM_NOPIN, //HFGPIO_F_SPI_CS + HFM_NOPIN, //HFGPIO_F_SPI_MOSI + LPT26x_GPIO15, //HFGPIO_F_UART1_TX, + HFM_NOPIN, //HFGPIO_F_UART1_RTS, + LPT26x_GPIO16, //HFGPIO_F_UART1_RX, + HFM_NOPIN, //HFGPIO_F_UART1_CTS, + + LPT26x_GPIO7, //HFGPIO_F_NLINK + LPT26x_GPIO8, //HFGPIO_F_NREADY + LPT26x_GPIO9, //HFGPIO_F_NRELOAD + + HFM_NOPIN, //HFGPIO_F_SLEEP_RQ + HFM_NOPIN, //HFGPIO_F_SLEEP_ON + + HFM_NOPIN, //HFGPIO_F_WPS + HFM_NOPIN, //HFGPIO_F_RESERVE1 + + HFM_NOPIN, //HFGPIO_F_RESERVE2 + HFM_NOPIN, //HFGPIO_F_RESERVE3 + HFM_NOPIN, //HFGPIO_F_RESERVE4 + HFM_NOPIN, //HFGPIO_F_RESERVE5 + + HFM_NOPIN, //HFGPIO_F_USER_DEFINE +}; +#ifdef ENABLE_BLE_SCAN +void hf_ble_scan_callback(gap_scan_result_data_t *scan_result_data) +{ + // todo + return ; +} + +int hfble_start_scan(void) +{ + int ret = 0; + gap_ble_scan_params_t ble_scan_param = { + .scan_interval = 0x40, //30*8/5*2*2, + .scan_window = 0x20, //30*8/5/2, + .scan_type = 0x00, + .scan_phy = GAP_BLE_PHY_1M, + .scan_filter_policy = 0x00, + }; + gap_ble_extern_scan_params_t ble_extern_scan_param = { + .filter_duplicate = 0, + .duration = 0, + .period = 0, + }; + + ret = gap_ble_set_scan_parameters(&ble_scan_param); + if(ret != 0){ + HILINK_SAL_DEBUG("gap_ble_set_scan_parameters failed, errcode = 0x%X\r\n", ret); + return -1; + } + ret = gap_ble_set_scan_extern_parameters(&ble_extern_scan_param); + if(ret != 0){ + HILINK_SAL_DEBUG("gap_ble_set_scan_extern_parameters failed, errcode = 0x%X\r\n", ret); + return -1; + } + ret = gap_ble_start_scan(); + if(ret != 0){ + HILINK_SAL_DEBUG("gap_ble_start_scan failed, errcode = 0x%X\r\n", ret); + return -1; + } + HILINK_SAL_DEBUG("*****************ble start scan*****************\r\n"); + return 0; +} +#endif +static int USER_FUNC uart_recv_callback(uint32_t event,char *data,uint32_t len,uint32_t buf_len) +{ + if(data == NULL) + return 0; + if(event == HFNET_UART0_DATA_READY) + HF_Debug(DEBUG_LEVEL_LOW,"[%d]uart 0 recv %d bytes data %d\n",event,len,buf_len); + else if(event == HFNET_UART1_DATA_READY) + HF_Debug(DEBUG_LEVEL_LOW,"[%d]uart 1 recv %d bytes data %d\n",event,len,buf_len); + if(hfsys_get_run_mode() == HFSYS_STATE_RUN_CMD) + return len; + + return len; +} +void user_app_init(void) +{ + u_printf("user app init\r\n"); +} +#define APPVER "1.0.0" +int hf_atcmd_appver(pat_session_t s,int argc,char *argv[],char *rsp,int len) +{ + if(argc == 0) + { + sprintf(rsp,"=LPT262_Harmonyos_%s_%s",APPVER,"20250227"); + return 0; + } + return -3; +} +const hfat_cmd_t user_define_at_cmds_table[]= +{ + {"APPVER", hf_atcmd_appver, "AT+APPVER: get version. \r\n",NULL}, + #ifdef HF_MCU_OTA + {"MCUOTA", hf_atcmd_mcu, "AT+MCUOTA: start mcu ota. \r\n",NULL}, + {"MCUVER", hf_atcmd_mcuver, "AT+MCUVER: get mcu version. \r\n",NULL}, + {"OTAWAITTIME", hf_atcmd_ota_wait_time, "AT+OTAWAITTIME: set/get uart send mcu ota time\r\n", NULL}, + #endif + {NULL, NULL, NULL, NULL} //the last item must be null +}; + +int USER_FUNC user_app_main(void) +{ + //AT+UART uart0 + if(hfnet_start_uart(HFTHREAD_PRIORITIES_LOW,(hfnet_callback_t)uart_recv_callback)!=HF_SUCCESS) + { + HF_Debug(DEBUG_WARN,"start uart fail!\r\n"); + } + #ifdef HF_MCU_OTA + if(hf_mcu_init() != HF_SUCCESS) + HF_Debug(DEBUG_WARN,"init mcu ota fail!\r\n"); + #endif + //See Wi-Fi Config tools APP for detailed usage of this thread, only debug mode open + if(hfdbg_get_level()) + { + while(!hfnet_wifi_is_active()) + { + msleep(50); + } + if(hfnet_start_assis(ASSIS_PORT)!=HF_SUCCESS) + { + HF_Debug(DEBUG_WARN,"start assis fail\r\n"); + } + } + e_printf("start assis success!\r\n"); + // hfgpio_pwm_enable(HFGPIO_F_SPI_CLK, 1000, 50); + spotlight_main(); + return 1; +} + + + + + + + + + + + + + + + + + + + + diff --git a/application/ws63/user_main/mcu_update.c b/application/ws63/user_main/mcu_update.c new file mode 100755 index 0000000..76a3863 --- /dev/null +++ b/application/ws63/user_main/mcu_update.c @@ -0,0 +1,259 @@ +#include "mcu_update.h" +#include "string.h" +#include "hilink_open_ota_mcu_adapter.h" +#include "hilink_device.h" + +mcu_info_t hf_mcu_info = {0}; +unsigned char hf_mcu_step = OTA_STEP_NULL; +static int ota_wait_time=100; + +int hf_atcmd_mcu(pat_session_t s,int argc,char *argv[],char *rsp,int len) +{ + if(argc==0) + { + if(hf_mcu_info.ota == 0) + sprintf(rsp,"=%s","off"); + else if(hf_mcu_info.ota == 1) + sprintf(rsp,"=%s","on"); + return 0; + } + else if(argc==1) + { + if(strcasecmp(argv[0],"on") == 0) + { + if(hf_mcu_info.ota == 0) + { + hf_mcu_info.ota=1; + hf_save_mcu_info(); + } + return 0; + } + else if(strcasecmp(argv[0],"off") == 0) + { + if(hf_mcu_info.ota == 1) + { + hf_mcu_info.ota=0; + hf_save_mcu_info(); + } + return 0; + } + return -4; + } + return -3; +} +int hf_atcmd_mcuver(pat_session_t s,int argc,char *argv[],char *rsp,int len) +{ + if(argc == 1) + { + if(strlen(argv[0]) > 10) + return -4; + hf_set_mcu_version((char *)argv[0]); + return 0; + } + return -3; +} + +int hf_atcmd_ota_wait_time(pat_session_t s,int argc,char *argv[],char *rsp,int len) +{ + if(argc == 0) + { + sprintf(rsp,"=%d",ota_wait_time); + return 0; + } + else if(argc == 1) + { + int time_wait=atoi(argv[0]); + if(time_waitSEND_UART_WAIT_TIME_MAX) + return -4; + ota_wait_time=time_wait; + if(hf_mcu_info.wait_time != time_wait) + { + hf_mcu_info.wait_time=ota_wait_time; + hf_save_mcu_info(); + } + return 0; + } + return -3; +} +const char *hf_get_mcu_ver(void) +{ + if(hf_mcu_info.head != MCU_INFO_HEAD) + { + memset(&hf_mcu_info, 0, sizeof(hf_mcu_info)); + strcpy((char *)hf_mcu_info.ver, MCU_VER); + hf_save_mcu_info(); + } + return (const char *)hf_mcu_info.ver; +} +void hf_set_mcu_version(char *ver) +{ + if(strlen(ver) >= MCU_VER_MAX_SIZE) + return ; + strcpy((char *)hf_mcu_info.ver,ver); + if(hf_mcu_info.head != MCU_INFO_HEAD || strcmp((char *)hf_mcu_info.ver,ver) != 0) + { + memset((char *)hf_mcu_info.ver,0,sizeof(hf_mcu_info.ver)); + strcpy((char *)hf_mcu_info.ver,ver); + hf_save_mcu_info(); + } + u_printf("get mcu ver:%s\r\n",hf_mcu_info.ver); +} +int hf_save_mcu_info(void) +{ + hf_mcu_info.head=MCU_INFO_HEAD; + hfuflash_erase_page(MCU_INFO_FILE,1); + hfuflash_write(MCU_INFO_FILE,&hf_mcu_info,sizeof(mcu_info_t)); + return 0; +} +static int hf_mcu_ota_is_vaild(void) +{ + return hf_mcu_info.ota; +} +void hf_save_mcu_status(unsigned char flag, int len) +{ + if(flag == START_SEND_DATA) + { + u_printf("ready to recv mcu firmware...\n"); + } + else if(flag == STOP_SEND_DATA) + { + u_printf("recv mcu firmware over...\n"); + hf_mcu_info.updateFlag = 1; + hf_mcu_info.len = len; + hf_save_mcu_info(); + } + else if(flag == SEND_DATA_ERROR) + { + u_printf("recv mcu firmware error...\n"); + } +} + +static void mcu_upgrade_thread(void *arg) +{ + int i = 0; + int ret = 0; + int seq = 0; + int offset = 0; + unsigned char *buff = hfmem_malloc(512); + unsigned char *data = hfmem_malloc(1024); + if(data == NULL || buff == NULL) + return ; + + u_printf("mcu ver:%s\r\n",hf_mcu_info.ver); + + if((hf_mcu_info.updateFlag > 0) && (hf_mcu_info.len > 0)) + hf_mcu_step = OTA_STEP_START; + + if(hf_mcu_info.wait_time >= SEND_UART_WAIT_TIME_MIN && hf_mcu_info.wait_time <= SEND_UART_WAIT_TIME_MAX) + ota_wait_time=hf_mcu_info.wait_time; + else + ota_wait_time=100; + while(1) + { + switch (hf_mcu_step) + { + case OTA_STEP_START: + { + memset(buff, 0, 512); + if(HILINK_GetDevStatus() == HILINK_M2M_CLOUD_ONLINE) + { + sprintf((char *)buff, "AT+OTASTART=%d\r\n", hf_mcu_info.len); + hfuart_send(HFUART0,buff, strlen((char *)buff),0); + u_printf("mcu ota OTA_STEP_START\r\n"); + hf_mcu_step += 0x01; + } + + break; + } + + case OTA_STEP_TRANS: + { + memset(buff, 0, 512); + memset(data, 0, 1024); + + if(hf_mcu_info.len - offset >= OTA_READ_LEN) + { + flash_read(UPGRADE_ADDRESS + offset, buff, OTA_READ_LEN,0); + offset += OTA_READ_LEN; + seq += 0x01; + u_printf("mcu send data count :%d\r\n",offset/OTA_READ_LEN); + sprintf((char *)data, "AT+OTADATA=%d,%d,", seq, OTA_READ_LEN); + ret = strlen((char *)data); + for(i = 0; i < OTA_READ_LEN; i++) + sprintf((char *)data + ret + 2 * i, "%02x", buff[i]); + + strncat((char *)data, "\r\n", 2); + + hfuart_send(HFUART0,data, ret + (OTA_READ_LEN * 2) + 2,0); + } + else + { + flash_read(UPGRADE_ADDRESS + offset, buff, hf_mcu_info.len - offset,0); + seq += 0x01; + + sprintf((char *)data, "AT+OTADATA=%d,%d,", seq, hf_mcu_info.len - offset); + ret = strlen((char *)data); + for(i = 0; i < (hf_mcu_info.len - offset); i++) + sprintf((char *)data + ret + 2 * i, "%02x", buff[i]); + + strncat((char *)data, "\r\n", 2); + + hfuart_send(HFUART0,data, ret + ((hf_mcu_info.len - offset) * 2) + 2,0); + + offset = hf_mcu_info.len; + + hf_mcu_step += 0x01; + } + + break; + } + + case OTA_STEP_END: + { + hfuart_send(HFUART0,(unsigned char *)"AT+OTAEND\r\n", strlen("AT+OTAEND\r\n"),0); + seq = 0; + offset = 0; + hf_mcu_step = OTA_STEP_NULL; + hf_mcu_info.updateFlag = 0; + hf_save_mcu_info(); + goto EXIT; + break; + } + + case OTA_STEP_ERROR: + { + hfuart_send(HFUART0,(unsigned char *)"AT+OTAERR\r\n", strlen("AT+OTAERR\r\n"),0); + hf_mcu_step = OTA_STEP_NULL; + goto EXIT; + break; + } + + default: + break; + } + msleep(ota_wait_time); + } + EXIT: + hfmem_free(data); + hfmem_free(buff); + hfthread_destroy(0); +} + +void hf_mcu_thread(void) +{ + hfthread_create(mcu_upgrade_thread, "hf-mcu-thread", 1024, NULL, HFTHREAD_PRIORITIES_LOW, NULL, NULL); +} + +int hf_mcu_init(void) +{ + hfuflash_read(MCU_INFO_FILE,&hf_mcu_info,sizeof(mcu_info_t)); + if(hf_mcu_ota_is_vaild()) + { + return -1; + } + char *get_mcu_ver="AT+GETMCUVER\r\n"; + hfuart_send(HFUART0,(unsigned char *)get_mcu_ver, strlen(get_mcu_ver),0); + if(hf_mcu_info.updateFlag && hf_mcu_info.len) + hf_mcu_thread(); + return HF_SUCCESS; +} \ No newline at end of file diff --git a/application/ws63/user_main/mcu_update.h b/application/ws63/user_main/mcu_update.h new file mode 100755 index 0000000..42deaa6 --- /dev/null +++ b/application/ws63/user_main/mcu_update.h @@ -0,0 +1,49 @@ +#ifndef MCU_UPDATE_H +#define MCU_UPDATE_H +#include +#include "hsf.h" +#define MCU_INFO_HEAD 0xA5A5 +#define MCU_INFO_FILE 0 + +#define MCU_VER "1.0.0" + +#define OTA_READ_LEN 256 + +#define OTA_STEP_NULL 0 +#define OTA_STEP_START 1 +#define OTA_STEP_TRANS 2 +#define OTA_STEP_END 3 +#define OTA_STEP_ERROR 4 + +#define MCU_VER_MAX_SIZE 8 +#define SEND_UART_WAIT_TIME_MIN 20 +#define SEND_UART_WAIT_TIME_MAX 500 + + +#pragma pack(push) +#pragma pack(1) + +typedef struct{ + uint16_t head; + unsigned char ota; + unsigned char updateFlag; + uint16_t wait_time; + unsigned char ver[MCU_VER_MAX_SIZE]; + unsigned int len; + unsigned char reserve[5]; +}mcu_info_t; +#pragma pack(pop) + + +const char *hf_get_mcu_ver(void); +void hf_save_mcu_status(unsigned char flag, int len); +void hf_mcu_thread(void); +void hf_set_mcu_version(char *ver); +int hf_mcu_init(void); +int hf_save_mcu_info(void); +int hf_atcmd_mcu(pat_session_t s,int argc,char *argv[],char *rsp,int len); +int hf_atcmd_mcuver(pat_session_t s,int argc,char *argv[],char *rsp,int len); +int hf_atcmd_ota_wait_time(pat_session_t s,int argc,char *argv[],char *rsp,int len); + +#endif + diff --git a/application/ws63/user_main/spotlight/device_module.c b/application/ws63/user_main/spotlight/device_module.c new file mode 100644 index 0000000..26cfe0d --- /dev/null +++ b/application/ws63/user_main/spotlight/device_module.c @@ -0,0 +1,70 @@ +#include "spotlight.h" +#include "cJSON.h" + + +#define CHECK_JSON_ITEM(condition) if(condition) { \ + goto lab_end; \ +} + +#define MAX_BRIGHTNESS 100 +#define MIN_BRIGHTNESS 0 +#define MAX_CCT 6500 +#define MIN_CCT 2700 + +typedef struct device_control_s { + bool on; + int32_t colorTemperature; + int32_t brightness; +} device_control_t; + +device_control_t g_device_control = { + .on = false, + .colorTemperature = MAX_CCT, + .brightness = MAX_BRIGHTNESS / 2, +}; + +int device_module_control(const char *svcId, const char *payload, unsigned int len) +{ + if ((svcId == NULL) || (payload == NULL)) { + return -1; + } + cJSON *item = NULL; + cJSON *json = cJSON_Parse(payload); + CHECK_JSON_ITEM(json == NULL); + + e_printf("put char sid:%s,payload:%s\r\n",svcId,payload); + if(strcmp(svcId, "brightness") == 0) + { + item = cJSON_GetObjectItem(json,"brightness"); + CHECK_JSON_ITEM(item == NULL); + CHECK_JSON_ITEM(!cJSON_IsNumber(item)); + } + else if(strcmp(svcId, "cct") == 0) + { + item = cJSON_GetObjectItem(json,"colorTemperature"); + CHECK_JSON_ITEM(item == NULL); + CHECK_JSON_ITEM(!cJSON_IsNumber(item)); + } else if(strcmp(svcId, "lightMode") == 0) // scense mode + { + item = cJSON_GetObjectItem(json,"mode"); + CHECK_JSON_ITEM(item == NULL); + CHECK_JSON_ITEM(!cJSON_IsNumber(item)); + + } + else if(strcmp(svcId, "switch") == 0) // device open/close + { + item = cJSON_GetObjectItem(json,"on"); + CHECK_JSON_ITEM(item == NULL); + CHECK_JSON_ITEM(!cJSON_IsNumber(item)); + } + +lab_end: + if(json != NULL) + { + cJSON_Delete(json); + json = NULL; + } + return 0; +} + + diff --git a/application/ws63/user_main/spotlight/spotlight.h b/application/ws63/user_main/spotlight/spotlight.h new file mode 100644 index 0000000..8520ee5 --- /dev/null +++ b/application/ws63/user_main/spotlight/spotlight.h @@ -0,0 +1,7 @@ +#ifndef __SPOTLIGHT_H__ +#define __SPOTLIGHT_H__ + +#include +int spotlight_main(void); +#endif + diff --git a/application/ws63/user_main/spotlight/spotlight_main.c b/application/ws63/user_main/spotlight/spotlight_main.c new file mode 100644 index 0000000..aef155a --- /dev/null +++ b/application/ws63/user_main/spotlight/spotlight_main.c @@ -0,0 +1,120 @@ +#include "hsf.h" +#if defined(CONFIG_PWM_SUPPORT_LPM) +#include "pm_veto.h" +#endif +#include "pinctrl.h" +#include "gpio.h" +#include "pwm.h" +// #include "tcxo.h" + +#include "spotlight.h" + +#define BRIGHTNESS_PIN GPIO_00 +#define CCT_PIN GPIO_04 +#define SWITCH_PIN GPIO_13 + +#define BRIGHTNESS_PWM_CHANNEL 0 +#define CCT_PWM_CHANNEL 4 + +#define CONFIG_PWM_GROUP_ID 0 + +static errcode_t pwm_sample_callback(uint8_t channel) +{ + e_printf("PWM %d, cycle done. \r\n", channel); + return ERRCODE_SUCC; +} + +static void gpio_init(pin_t pin) +{ + /* PINCTRL init. */ + uapi_pin_init(); + uapi_pin_set_mode(pin, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(pin, GPIO_DIRECTION_OUTPUT); + uapi_pin_set_ds(pin, PIN_DS_3); + uapi_pin_set_pull(pin, PIN_PULL_TYPE_DOWN); + uapi_gpio_set_val(pin, GPIO_LEVEL_LOW); +} + +static void pwm_sys_init() { + uapi_pwm_deinit(); + uapi_pwm_init(); +} + +static void pwm_init(pin_t pin, pin_t pin1, uint8_t channel, uint channel1) +{ + pwm_config_t cfg_no_repeat = { + 0, + 0, + 0, + 0, + true + }; + uint32_t frequency = uapi_pwm_get_frequency(channel); + e_printf("pwm基础时钟频率为: %dHZ\r\n", frequency); + + // 计算1KHz PWM所需的周期值(高电平+低电平) + uint32_t total_period = frequency / 1000; + // 50%占空比,高低电平时间相等 + cfg_no_repeat.high_time = total_period / 2; + cfg_no_repeat.low_time = total_period / 2; + + e_printf("设置1KHz PWM,50%%占空比,周期值: %d\r\n", total_period); + uapi_pin_set_mode(pin, PIN_MODE_3); //set pin as pwm output + uapi_pin_set_mode(pin1, PIN_MODE_3); //set pin as pwm output + uapi_pwm_open(channel, &cfg_no_repeat); + uapi_pwm_open(channel1, &cfg_no_repeat); + + // uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); + // uapi_pwm_unregister_interrupt(channel); + // uapi_pwm_register_interrupt(channel, pwm_sample_callback); +#ifdef CONFIG_PWM_USING_V151 + uint8_t channel_id[2] = {channel, channel1}; + /* channel_id can also choose to configure multiple channels, and the third parameter also needs to be adjusted + accordingly. */ + uapi_pwm_set_group(CONFIG_PWM_GROUP_ID, channel_id, 2); +#else + uapi_pwm_start(channel); +#endif + +} +void pwm_start() +{ +#ifdef CONFIG_PWM_USING_V151 + /* Here you can also call the uapi_pwm_start interface to open each channel individually. */ + uapi_pwm_start_group(CONFIG_PWM_GROUP_ID); +#endif +} +void pwm_sys_deinit(void) +{ + // uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); +#ifdef CONFIG_PWM_USING_V151 + uapi_pwm_close(CONFIG_PWM_GROUP_ID); +#else + uapi_pwm_close(CONFIG_PWM_CHANNEL); +#endif + + // uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); + uapi_pwm_deinit(); +} + +static void pwm_entry(void) +{ + pwm_sys_init(); + pwm_init(BRIGHTNESS_PIN, BRIGHTNESS_PWM_CHANNEL, CCT_PIN, CCT_PWM_CHANNEL); + pwm_start(); +} + + +int spotlight_main(void) { + gpio_init(SWITCH_PIN); + pwm_entry(); + + while (1) { + e_printf("spotlight_main\r\n"); + uapi_gpio_toggle(SWITCH_PIN); + msleep(1000); + + } + return 0; +} + diff --git a/application/ws63/ws63_liteos_application/CMakeLists.txt b/application/ws63/ws63_liteos_application/CMakeLists.txt new file mode 100755 index 0000000..928e434 --- /dev/null +++ b/application/ws63/ws63_liteos_application/CMakeLists.txt @@ -0,0 +1,40 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "ws63_liteos_app") + +set(SOURCES +) + +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR} +) +set(LIBS + ${CMAKE_CURRENT_SOURCE_DIR}/libws63_liteos_app.a +) +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES +) + +set(PUBLIC_DEFINES +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + true +) + +build_component() diff --git a/application/ws63/ws63_liteos_application/clock_init.h b/application/ws63/ws63_liteos_application/clock_init.h new file mode 100755 index 0000000..638c559 --- /dev/null +++ b/application/ws63/ws63_liteos_application/clock_init.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Description: the header file for main. + * + */ + +#ifndef __CLOCK_INIT_H__ +#define __CLOCK_INIT_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define CMU_XO_SIG 0X40003404 +#define XO_TRIM_ENABLE 1 +#define SIZE_8_BITS 8 +#define EFUSE_GROUP_MAX 3 +#define EXT_EFUSE_LOCK_XO_TRIM_BIT_POS 7 +#define EXT_EFUSE_XO_TRIM_1_ID 144 +#define EXT_EFUSE_XO_TRIM_2_ID 162 +#define EXT_EFUSE_XO_TRIM_3_ID 180 +#define EXT_EFUSE_RSSI_BAND3_1_ID 160 +#define EXT_EFUSE_RSSI_BAND3_2_ID 178 +#define EXT_EFUSE_RSSI_BAND3_3_ID 196 + +typedef union { + /* Define the struct bits */ + struct { + uint32_t rg_cmu_xo_trim_fine : 8; /* [7..0] */ + uint32_t rg_cmu_xo_trim_coarse : 4; /* [11..8] */ + uint32_t rg_cmu_xo_trim_rev : 4; /* [15..12] */ + uint32_t rg_cmu_xo_trim_fine_sel : 1; /* [16] */ + uint32_t rg_cmu_xo_trim_coarse_sel : 1; /* [17] */ + uint32_t rg_cmu_xo_trim_rev_sel : 1; /* [18] */ + uint32_t reserved_0 : 13; /* [31..19] */ + } bits; + + /* Define an unsigned member */ + uint32_t u32; +} u_cmu_xo_sig; + +extern void LOS_SetSysClosk(uint32_t clock); + +void open_rf_power(void); +void switch_clock(void); +void set_uart_tcxo_clock_period(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // __MAIN_H__ diff --git a/application/ws63/ws63_liteos_application/main.h b/application/ws63/ws63_liteos_application/main.h new file mode 100755 index 0000000..9bb30e0 --- /dev/null +++ b/application/ws63/ws63_liteos_application/main.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. + * Description: the header file for main. + * + */ + +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +__attribute__((section(".text.runtime.init"))) void copy_bin_to_ram(unsigned int *start_addr, + const unsigned int *const load_addr, unsigned int size); +__attribute__((section(".text.runtime.init"))) void init_mem_value(unsigned int *start_addr, + const unsigned int *const end_addr, unsigned int init_val); +__attribute__((section(".text.runtime.init"))) void do_relocation(void); +__attribute__((section(".text.runtime.init"))) void runtime_init(void); + +extern void LOS_PrepareMainTask(void); + +#ifdef WIFI_TASK_EXIST +extern int wifi_host_task(void *param); +extern __attribute__((weak)) int demo_init(void *param); +#endif + +#ifdef CONFIG_SUPPORT_HILINK +extern __attribute__((weak)) int hilink_entry(void *param); +#endif +#ifdef BGLE_TASK_EXIST +extern void bt_thread_handle(void *para); +#ifdef SPARKLYZER_ACTIVATED +extern void splz_thread_handle(void *para); +#endif +#endif + +#ifdef AT_COMMAND +void at_uart_init(void); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // __MAIN_H__ diff --git a/application/ws63/ws63_liteos_application/reset_vector.S b/application/ws63/ws63_liteos_application/reset_vector.S new file mode 100755 index 0000000..9741204 --- /dev/null +++ b/application/ws63/ws63_liteos_application/reset_vector.S @@ -0,0 +1,62 @@ +/** + * @file reset_vector.S + * @author Huawei LiteOS + * @brief RISC-V trap handling and startup code. + */ +#include "arch/cpu.h" + +.extern TrapVector +.extern runtime_init + +.global reset_vector + +.local HandleReset + +.section .text.entry +.option rvc + +.section .text.entry +reset_vector: + tail HandleReset + +HandleReset: +#ifdef CHIP_EDA + li t0,0x0 + csrw pmpcfg0,t0 + li t0,0x0 + csrw pmpcfg1,t0 +#endif + + la t0, TrapVector + csrw mtvec, t0 + csrwi mstatus, 0 + csrwi mie, 0 + +/* set to initial state of FPU */ + li t0, 0x00006000 + csrs mstatus, t0 + fssr x0 + + .option push + .option norelax + +/* initialize global pointer */ + la gp, _gp_ + .option pop + +/* initialize stack pointer: irq stack used for startup stack */ + la sp, __stack_top__ + +/* init stack */ + la t0, g_system_stack_begin + la t1, g_system_stack_end + beq t0, t1, end_set_stack_loop + li t2, 0xefbeadde + +set_stack_loop: + sw t2, (t0) + addi t0, t0, 4 + blt t0, t1, set_stack_loop +end_set_stack_loop: + + tail runtime_init diff --git a/application/ws63/ws63_liteos_mfg/CMakeLists.txt b/application/ws63/ws63_liteos_mfg/CMakeLists.txt new file mode 100755 index 0000000..3e8ed3c --- /dev/null +++ b/application/ws63/ws63_liteos_mfg/CMakeLists.txt @@ -0,0 +1,6 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + +install_sdk("${CMAKE_CURRENT_SOURCE_DIR}" "*.bin") \ No newline at end of file diff --git a/build.py b/build.py new file mode 100755 index 0000000..e17f5c0 --- /dev/null +++ b/build.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# encoding=utf-8 +# ============================================================================ +# @brief build system entry, receive param & start to build +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +# ============================================================================ +""" +接收参数列表及解释: + -c: + clean后编译 + -j: + -j, 以num线程数编译 + 默认为机器最大线程数 + -def=: + -def=XXX,YYY,ZZZ=x,... 向本次编译target中添加XXX、YYY、ZZZ=x编译宏 + 可使用-def=-:XXX 来屏蔽XXX宏 + 可使用-def=-:ZZZ=x 来添加或者修改ZZZ宏 + -component=: + -component=XXX,YYY,... 仅编译XXX,YYY组件 + -ninja: + 使用ninja生成中间文件 + 默认使用Unix makefile + -[release/debug]: + debug: 在生成反汇编文件时信息更加全面但也更耗时 + release: 在生成反汇编文件时节省时间 + 默认为debug + -dump: + 输出target的编译参数 + -nhso: + 不更新HSO数据库 + -out_libs: + -out_libs=file_path, 不再链接成elf, 转而将所有.a打包成一个大的.a + others: + 作为匹配编译target_names的关键字 +""" +import os +import sys +from distutils.spawn import find_executable + +sys.dont_write_bytecode = True +root_dir = os.path.split(os.path.realpath(__file__))[0] +sys.path.append(os.path.join(root_dir, 'build', 'config')) +sys.path.append(os.path.join(root_dir, 'build', 'script')) + +from cmake_builder import CMakeBuilder + +def check_enviroment(): + if not find_executable("cmake"): + print("cmake is not installed or not added to system path.") + if not find_executable("ninja") and not find_executable("make"): + print("make/ninja is not installed or not added to system path.") + +builder = CMakeBuilder(sys.argv) + +builder.build() diff --git a/build/cmake/build_boot_bin_cp.cmake b/build/cmake/build_boot_bin_cp.cmake new file mode 100755 index 0000000..c8dc92c --- /dev/null +++ b/build/cmake/build_boot_bin_cp.cmake @@ -0,0 +1,23 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + +if(NOT "${FLASHBOOT_CFG}" STREQUAL "") +add_custom_target(COPY_FLASHBOOT_BIN ALL + COMMAND ${CP} ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${FLASHBOOT_CFG}/flashboot_sign_a.bin ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/flashboot_sign_a.bin && + ${CP} ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${FLASHBOOT_CFG}/flashboot_sign_b.bin ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/flashboot_sign_b.bin + COMMENT "copy bin file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_SIGNBIN +) +endif() + +if(NOT "${LOADERBOOT_CFG}" STREQUAL "") +add_custom_target(COPY_LOADERBOOT_BIN ALL + COMMAND ${CP} ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${LOADERBOOT_CFG}/loaderboot_sign.bin ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/loaderboot_sign.bin + COMMENT "copy bin file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_SIGNBIN +) +endif() \ No newline at end of file diff --git a/build/cmake/build_command.cmake b/build/cmake/build_command.cmake new file mode 100755 index 0000000..a1f1064 --- /dev/null +++ b/build/cmake/build_command.cmake @@ -0,0 +1,15 @@ +set(ECHO ${CMAKE_COMMAND} -E echo) +set(MKDIR ${CMAKE_COMMAND} -E make_directory) +set(RENAME ${CMAKE_COMMAND} -E rename) +set(CP_PY ${Python3_EXECUTABLE} ${BUILD_UTILS} copy) +set(CP_PY_FORCE ${Python3_EXECUTABLE} ${BUILD_UTILS} copy_force) +set(CP_DIR ${CMAKE_COMMAND} -E copy_directory) +set(RM ${CMAKE_COMMAND} -E rm -f) +set(RM_DIR ${CMAKE_COMMAND} -E rm -rf) +set(UNZIP ${CMAKE_COMMAND} -E tar x) + +if(${BUILD_PLATFORM} MATCHES "linux") +set(CP cp) +elseif(${BUILD_PLATFORM} MATCHES "windows") +set(CP ${CMAKE_COMMAND} -E copy) +endif() \ No newline at end of file diff --git a/build/cmake/build_component.cmake b/build/cmake/build_component.cmake new file mode 100755 index 0000000..2091458 --- /dev/null +++ b/build/cmake/build_component.cmake @@ -0,0 +1,335 @@ +#=============================================================================== +# @brief cmake component build +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== +macro(get_obj_path output obj_root) + set(ret) + foreach(src ${REGD_SOURCES}) + # filter full path + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" relpath ${src}) + # make suffix to be .o + list(APPEND ret ${obj_root}/${relpath}.o) + endforeach() + set(${output} ${ret}) +endmacro() + +macro(register_component) + set(${COMPONENT_NAME}_MODULE_NAME ${MODULE_NAME} CACHE INTERNAL "" FORCE) + set(${COMPONENT_NAME}_AUTO_DEF ${AUTO_DEF_FILE_ID} CACHE INTERNAL "" FORCE) + set(${COMPONENT_NAME}_SOURCES ${SOURCES} CACHE INTERNAL "" FORCE) +endmacro(register_component) + +macro(component_on_rom) + if(${COMPONENT_NAME} IN_LIST RAM_COMPONENT) + set(COMPONENT_ON_ROM false) + elseif(${COMPONENT_NAME} IN_LIST ROM_COMPONENT) + set(COMPONENT_ON_ROM true) + else() + unset(COMPONENT_ON_ROM) + endif() +endmacro() + +macro(need_whole_archiv) + set(WHOLE_ARCHIV false) + if (COMPONENT_ON_ROM STREQUAL true) + set(WHOLE_ARCHIV true) + endif() + if(DEFINED WHOLE_LINK AND WHOLE_LINK STREQUAL true) + set(WHOLE_ARCHIV true) + endif() + unset(WHOLE_LINK) +endmacro() + +macro(replace_lib_output_path) + install_lib_gen() + if(DEFINED LIB) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB}) + endif() + if(DEFINED LIB_OUT_PATH) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_OUT_PATH}) + endif() + if(DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY AND ${BUILD_ROM_CALLBACK} AND ${COMPONENT_ON_ROM}) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}-prerom) + endif() +endmacro() + +macro(build_library) + set(lib_type STATIC) + if(DEFINED BUILD_AS_OBJ AND BUILD_AS_OBJ STREQUAL true) + set(lib_type OBJECT) + endif() + + list(GET SOURCES 0 SOURCES0) + get_filename_component(SOURCES0 "${SOURCES0}" ABSOLUTE) + if(EXISTS ${SOURCES0}) + replace_lib_output_path() + add_library(${COMPONENT_NAME} + ${lib_type} + "${SOURCES}" + ) + + target_compile_definitions(${COMPONENT_NAME} + PRIVATE + ${DEFINES} + ${PRIVATE_DEFINES} + ${PUBLIC_DEFINES} + ) + + target_include_directories(${COMPONENT_NAME} + PRIVATE + ${PRIVATE_HEADER} + ${PUBLIC_HEADER} + $<$:${CXX_HEADERS}> + ) + + target_compile_options(${COMPONENT_NAME} + PRIVATE + ${COMPILE_CCFLAGS} + $<$:-include${PROJECT_BINARY_DIR}/mconfig.h> + ) + + set(LINK_LIB_${COMPONENT_NAME} ${COMPONENT_NAME}) + register_component() + target_link_libraries(${COMPONENT_NAME} PRIVATE ${TARGETS_INTERFACES}) + else() + if(DEFINED LIB) + else() + # message(STATUS "[HSF HiLink NOTE] ${SOURCES0} is not found, finding lib${COMPONENT_NAME}.a in ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_COMMAND}") + find_library(LINK_LIB_${COMPONENT_NAME} "lib${COMPONENT_NAME}.a" ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_COMMAND}) + if(NOT LINK_LIB_${COMPONENT_NAME}) + find_library(LINK_LIB_${COMPONENT_NAME} "lib${COMPONENT_NAME}.a" ${ROOT_DIR}/application/ws63/hsf) + if(NOT LINK_LIB_${COMPONENT_NAME}) + message(FATAL_ERROR "${SOURCES0} is not found && lib${COMPONENT_NAME}.a not find") + endif() + endif() + install_sdk(${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_COMMAND}/lib${COMPONENT_NAME}.a "*") + endif() + + endif() + + if(WHOLE_ARCHIV STREQUAL false) + # treat as a non-rom component + target_link_libraries(${TARGET_NAME} + PRIVATE + ${LINK_LIB_${COMPONENT_NAME}} + ) + else() + # one on rom. + target_link_libraries(${TARGET_NAME} + PRIVATE + -Wl,--whole-archive ${LINK_LIB_${COMPONENT_NAME}} -Wl,--no-whole-archive + ) + endif() +endmacro() + +macro(link_libs) + if(DEFINED LIBS) + if(WHOLE_ARCHIV STREQUAL false) + target_link_libraries(${TARGET_NAME} + PRIVATE + ${LIBS} + ) + else() + target_link_libraries(${TARGET_NAME} + PRIVATE + -Wl,--whole-archive ${LIBS} -Wl,--no-whole-archive + ) + endif() + endif() +endmacro(link_libs) + +macro(main_component) + if(DEFINED MAIN_COMPONENT AND MAIN_COMPONENT STREQUAL true) + set(SDK_PROJECT_FILE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "" FORCE) + set(MAIN_COMPONENT "${COMPONENT_NAME}" CACHE INTERNAL "" FORCE) + endif() +endmacro() + +macro(add_to_logdef) + if(DEFINED LOG_DEF) + set(LOG_DEF_LIST "${LOG_DEF_LIST}" "${LOG_DEF}" CACHE INTERNAL "" FORCE) + endif() +endmacro(add_to_logdef) + +macro(install_file) + if (DEFINED SDK_OUTPUT_PATH) + check_if_closed_component(${COMPONENT_NAME}) + if (${COMPONENT_IS_CLOSED}) + if (TARGET ${COMPONENT_NAME}) + get_property(LIB_PATH TARGET ${COMPONENT_NAME} PROPERTY BINARY_DIR) + endif() + + if(DEFINED LIB) + install_sdk(${LIB}/ "*") + elseif(DEFINED LIB_OUT_PATH) + install_dest_sdk(${LIB_OUT_PATH}/lib${COMPONENT_NAME}.a ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_COMMAND}/lib${COMPONENT_NAME}.a "*.a") + elseif(LIB_PATH) + install_dest_sdk(${LIB_PATH}/lib${COMPONENT_NAME}.a ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_COMMAND}/lib${COMPONENT_NAME}.a "*.a") + endif() + else() + foreach(src ${SOURCES}) + install_sdk(${src} "*") + endforeach() + foreach(header ${PRIVATE_HEADER} ${PUBLIC_HEADER}) + install_sdk(${header} "*.h") + endforeach() + endif() + + foreach(lib ${LIBS}) + install_sdk(${lib} "*") + endforeach() + endif() +endmacro(install_file) + +macro(define_this_module_and_file_id) + foreach(filename ${SOURCES}) + if(filename STREQUAL "") + continue() + endif() + if(${AUTO_DEF_FILE_ID}) + string(STRIP ${filename} filename) + get_filename_component(barename ${filename} NAME) + string(REPLACE "." "_" barename ${barename}) + string(TOUPPER ${barename} barename) + string(STRIP ${barename} barename) + set_property( + SOURCE ${filename} + APPEND + PROPERTY COMPILE_DEFINITIONS + THIS_FILE_ID=${barename}) + endif() + + if(${AUTO_DEF_MODULE_ID}) + set(prefix "LOG_") + set(suffix "MODULE") + string(TOUPPER ${MODULE_NAME} mod_name) + string(JOIN ${mod_name} mod_name ${prefix} ${suffix}) + set_property( + SOURCE ${filename} + APPEND + PROPERTY COMPILE_DEFINITIONS + THIS_MOD_ID=${mod_name}) + endif() + endforeach() +endmacro(define_this_module_and_file_id) + +macro(unset_var) + UNSET(COMPONENT_NAME) + UNSET(SOURCES) + UNSET(PRIVATE_HEADER) + UNSET(PUBLIC_HEADER) + UNSET(PRIVATE_DEFINES) + UNSET(PUBLIC_DEFINES) + UNSET(COMPONENT_CCFLAGS) + UNSET(COMPONENT_PUBLIC_CCFLAGS) + UNSET(BUILD_AS_OBJ) + UNSET(LOG_DEF) + UNSET(WHOLE_LINK) + UNSET(LINK_LIB_${COMPONENT_NAME}) + UNSET(LIB_OUT_PATH) + UNSET(LIB_DIR) + UNSET(LIBS) + UNSET(LIB) + UNSET(REWRITE_CCFLAGS) + UNSET(COMPONENT_IS_CLOSED) +endmacro(unset_var) + + +macro(build_component) + component_on_rom() + if(DEFINED ROM_SYM_PATH AND COMPONENT_ON_ROM) + add_library(${COMPONENT_NAME}_interface INTERFACE) + target_include_directories(${COMPONENT_NAME}_interface INTERFACE ${PUBLIC_HEADER}) + target_compile_definitions(${COMPONENT_NAME}_interface INTERFACE ${PUBLIC_DEFINES}) + list(GET SOURCES 0 SOURCES0) + get_filename_component(SOURCES0 "${SOURCES0}" ABSOLUTE) + if(EXISTS ${SOURCES0}) + register_component() + endif() + elseif(DEFINED COMPONENT_ON_ROM) + need_whole_archiv() + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/private) + set(PRIVATE_HEADER ${PRIVATE_HEADER} ${CMAKE_CURRENT_SOURCE_DIR}/private) + endif() + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/public) + set(PUBLIC_HEADER ${PUBLIC_HEADER} ${CMAKE_CURRENT_SOURCE_DIR}/public) + endif() + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/include) + set(PUBLIC_HEADER ${PUBLIC_HEADER} ${CMAKE_CURRENT_SOURCE_DIR}/include) + endif() + if(COMPONENT_ON_ROM STREQUAL false) + if(REWRITE_CCFLAGS STREQUAL true) + set(COMPILE_CCFLAGS ${COMPONENT_CCFLAGS}) + else() + # treat as a non-rom component + set(COMPILE_CCFLAGS ${CCFLAGS} ${COMPONENT_CCFLAGS}) + endif() + else() + # one on rom. + + set(COMPILE_CCFLAGS ${ROM_CCFLAGS}) + endif() + + check_if_closed_component(${COMPONENT_NAME}) + if (RELEASE OR ${COMPONENT_IS_CLOSED}) + list(REMOVE_ITEM COMPILE_CCFLAGS "-g") + endif() + + add_library(${COMPONENT_NAME}_interface INTERFACE) + target_include_directories(${COMPONENT_NAME}_interface INTERFACE ${PUBLIC_HEADER}) + target_compile_definitions(${COMPONENT_NAME}_interface INTERFACE ${PUBLIC_DEFINES}) + target_compile_options(${COMPONENT_NAME}_interface INTERFACE ${COMPONENT_PUBLIC_CCFLAGS}) + set(TARGETS_INTERFACES ${RAM_COMPONENT} ${ROM_COMPONENT}) + list(TRANSFORM TARGETS_INTERFACES APPEND "_interface") + + list(LENGTH PUBLIC_HEADER PUBLIC_HEADER_NUM) + if(NOT ${PUBLIC_HEADER_NUM} EQUAL 0) + set(ALL_PUBLIC_HEADER "${ALL_PUBLIC_HEADER}" "${PUBLIC_HEADER}" CACHE INTERNAL "" FORCE) + endif() + + if(DEFINED LOG_CUSTOM_ENABLE) + if(${LOG_CUSTOM_ENABLE} STREQUAL True) + if(NOT ${PUBLIC_HEADER_NUM} EQUAL 0) + set(ALL_HEADER_DIRS "${ALL_HEADER_DIRS}" "${PUBLIC_HEADER}" CACHE INTERNAL "" FORCE) + endif() + + list(LENGTH PRIVATE_HEADER PRIVATE_HEADER_NUM) + if(NOT ${PRIVATE_HEADER_NUM} EQUAL 0) + set(ALL_HEADER_DIRS "${ALL_HEADER_DIRS}" "${PRIVATE_HEADER}" CACHE INTERNAL "" FORCE) + endif() + + list(LENGTH PUBLIC_DEFINES PUBLIC_DEFINES_NUM) + if(NOT ${PUBLIC_DEFINES_NUM} EQUAL 0) + set(ALL_DEFINES "${ALL_DEFINES}" "${PUBLIC_DEFINES}" CACHE INTERNAL "" FORCE) + endif() + + list(LENGTH PRIVATE_DEFINES PRIVATE_DEFINES_NUM) + if(NOT ${PRIVATE_DEFINES_NUM} EQUAL 0) + set(ALL_DEFINES "${ALL_DEFINES}" "${PRIVATE_DEFINES}" CACHE INTERNAL "" FORCE) + endif() + + list(LENGTH DEFINES DEFINES_NUM) + if(NOT ${DEFINES_NUM} EQUAL 0) + set(ALL_DEFINES "${ALL_DEFINES}" "${DEFINES}" CACHE INTERNAL "" FORCE) + endif() + endif() + endif() + + set(ALL_PUBLIC_DEFINES "${ALL_PUBLIC_DEFINES}" "${PUBLIC_DEFINES}" CACHE INTERNAL "" FORCE) + set(ALL_PUBLIC_CCFLAGS "${ALL_PUBLIC_CCFLAGS}" "${COMPONENT_PUBLIC_CCFLAGS}" CACHE INTERNAL "" FORCE) + link_libs() + list(LENGTH SOURCES SOURCES_NUM) + if(NOT ${SOURCES_NUM} EQUAL 0) + build_library() + endif() + if(${BUILD_ROM_CALLBACK} AND ${COMPONENT_ON_ROM}) + reg_rom_callback() + endif() + define_this_module_and_file_id() + sdk_export_component("component") + install_file() + add_to_logdef() + main_component() + endif() + unset_var() +endmacro() diff --git a/build/cmake/build_elf_info.cmake b/build/cmake/build_elf_info.cmake new file mode 100755 index 0000000..5f47906 --- /dev/null +++ b/build/cmake/build_elf_info.cmake @@ -0,0 +1,164 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== + +set(BUILT_LDS ${CMAKE_BINARY_DIR}/linker.lds) + +if (DEFINED BUILD_LEVEL AND NOT ${BUILD_LEVEL} STREQUAL "release") + set(EXTRA_DUMP_OPT -S -l) +endif() + +if (DEFINED NHSO AND "${NHSO}" STREQUAL "True") + set(GEN_PARSE_TOOL False) +endif() + +if((NOT DEFINED DEBUG_FILES OR "lst" IN_LIST DEBUG_FILES OR "mem" IN_LIST DEBUG_FILES) AND NOT ${ROM_CHECK}) + add_custom_target(GENERAT_LST ALL + COMMAND ${CMAKE_OBJDUMP} -x ${EXTRA_DUMP_OPT} ${BIN_NAME}.elf > ${BIN_NAME}.lst + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${TARGET_NAME} + ) +endif() + +if(NOT DEFINED DEBUG_FILES OR "nm" IN_LIST DEBUG_FILES OR "${GEN_PARSE_TOOL}" STREQUAL "True") + add_custom_target(GENERAT_NM ALL + COMMAND ${CMAKE_NM} -S -n --format=sysv ${BIN_NAME}.elf > ${BIN_NAME}.nm + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${TARGET_NAME} + ) +endif() + +if(NOT DEFINED DEBUG_FILES OR "asm" IN_LIST DEBUG_FILES) + add_custom_target(GENERAT_ASM ALL + COMMAND ${CMAKE_OBJDUMP} -d -m ${ARCH_FAMILY} ${BIN_NAME}.elf > ${BIN_NAME}.asm + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${TARGET_NAME} + ) +endif() + +if("${GEN_PARSE_TOOL}" STREQUAL "True") + add_custom_target(GENERAT_INFO ALL + COMMAND ${CMAKE_OBJDUMP} -Wi ${BIN_NAME}.elf > ${BIN_NAME}.info + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${TARGET_NAME} + ) +endif() + +if((NOT DEFINED DEBUG_FILES OR "mem" IN_LIST DEBUG_FILES) AND NOT ${ROM_CHECK}) +add_custom_target(GENERAT_MEM ALL + COMMAND ${Python3_EXECUTABLE} ${ELF_TO_DU} ${ROOT_DIR} ${BIN_NAME}.elf ${CMAKE_NM} > ${BIN_NAME}.du + COMMAND ${Python3_EXECUTABLE} ${MEM_STATE} ${BIN_NAME}.lst ${BIN_NAME}.du ${BUILT_LDS} ${CHIP} > ${BIN_NAME}.mem + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS "${TARGET_NAME};GENERAT_LST" +) +if(NOT "SDK_NOT_MEM_LIMIT" IN_LIST DEFINES) + add_custom_target(GENERAT_MEM_LIMIT ALL + COMMENT "MEM_LIMIT" + COMMAND ${Python3_EXECUTABLE} ${PARSE_MAP_SIZE_INFO} ${BIN_NAME}.lst ${BIN_NAME}.map + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS "${TARGET_NAME};GENERAT_LST") + +endif() +endif() + +if(NOT DEFINED DEBUG_FILES OR "hex" IN_LIST DEBUG_FILES) +add_custom_target(GENERAT_STD_HEX ALL + # 生成 intel 标准 hex 文件 + COMMAND ${CMAKE_OBJCOPY} -O ihex ${BIN_NAME}.elf ${BIN_NAME}_std.hex + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN +) +add_custom_target(GENERAT_HEX ALL + COMMAND ${Python3_EXECUTABLE} ${GEN_HEX} ${BIN_NAME}.bin ${BIN_NAME}.hex + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN +) + +if(DEFINED ROM_COMPONENT) + add_custom_target(GENERAT_ROM_HEX ALL + COMMAND ${Python3_EXECUTABLE} ${GEN_HEX} ${BIN_NAME}_rom.bin ${BIN_NAME}_rom.hex + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN + ) +endif() +endif() + +if (DEFINED BUILD_LEVEL AND NOT ${BUILD_LEVEL} STREQUAL "release") +if("${IMAGE_ANALYSIS}" STREQUAL "True" AND ${BUILD_PLATFORM} MATCHES "linux") + add_custom_target(GENERAT_IMAGE_ANALYSIS ALL + COMMAND ${Python3_EXECUTABLE} ${IMAGE_ANALSIS_TOOL} ${TARGET_COMMAND} ${OBJDUMP_PATH} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${TARGET_NAME} + ) +endif() + +if("${CODESIZE_STATISTIC}" STREQUAL "True") + add_custom_target(GENERAT_CODESIZE_STATISTIC ALL + COMMAND ${Python3_EXECUTABLE} ${CODESIZE_STATISTIC_TOOL} ${TARGET_COMMAND} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${TARGET_NAME} + ) +endif() +endif() + +if("${GEN_ROM_INFO}" STREQUAL "True") + set(REMOTE_LIB ${ROOT_DIR}/drivers/chips/${CHIP}/remote_lib/${BUILD_TARGET_NAME}.cfg) +if (${CHIP} MATCHES "bs20|bs21|bs21a|bs21e|bs22|bs26") + set(TARGET_SYM ${ROOT_DIR}/drivers/chips/bs2x/rom/rom_config/${CORE}/${BIN_NAME}.sym) +else() + set(TARGET_SYM ${ROOT_DIR}/drivers/chips/${CHIP}/rom_config/${CORE}/${BIN_NAME}.sym) +endif() + add_custom_target(GENERAT_ROM_INFO ALL + COMMAND ${Python3_EXECUTABLE} ${GEN_ROM_INFO_TOOL} ${BIN_NAME}.elf ${REMOTE_LIB} ${TARGET_SYM} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN + ) +endif() + +if(NOT DEFINED PATCH) + set(PATCH False) +endif() + +if(NOT DEFINED PATCH_DYN_TBL) + set(PATCH_DYN_TBL False) +endif() + +if(${PATCH_DYN_TBL}) + +execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory + ${ROOT_DIR}/build/config/target_config/${CHIP}/patch_config + ${PROJECT_BINARY_DIR}/patch_config +) + +if((${PATCH} AND ${PATCH_DYN_TBL}) AND NOT ${ROM_CHECK}) + set(PATCH_CONFIG ${PROJECT_BINARY_DIR}/patch_config) + set(GET_TA_TOOL ${ROOT_DIR}/build/config/target_config/${CHIP}/script/patch_get_tbl_info.py) + add_custom_target(GET_DYN_TBL_ADDR ALL + COMMAND ${Python3_EXECUTABLE} ${GET_TA_TOOL} ${CORE} ${TARGET_COMMAND} ${BIN_NAME} ${PATCH_CONFIG} ${PROJECT_BINARY_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN + ) +endif() + +if((DEFINED ROM_COMPONENT AND ${PATCH}) AND NOT ${ROM_CHECK}) + set(PATCH_CONFIG ${PROJECT_BINARY_DIR}/patch_config) + add_custom_target(GENERAT_ROM_PATCH ALL + COMMAND ${Python3_EXECUTABLE} ${GEN_PATCH} ${BIN_NAME}.bin ${BIN_NAME}_rom.bin ${BIN_NAME}.nm ${PATCH_CONFIG} ${CORE} ${TARGET_COMMAND} ${PROJECT_BINARY_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GET_DYN_TBL_ADDR GENERAT_NM + ) +endif() + +else() + +if(((DEFINED ROM_COMPONENT AND ${PATCH}) AND NOT ${ROM_CHECK}) OR DEFINED ROM_SYM_PATH) + set(PATCH_CONFIG ${ROOT_DIR}/build/config/target_config/${CHIP}/patch_config) + add_custom_target(GENERAT_ROM_PATCH ALL + COMMAND ${Python3_EXECUTABLE} ${GEN_PATCH} ${BIN_NAME}.bin ${BIN_NAME}_rom.bin ${BIN_NAME}.nm ${PATCH_CONFIG} ${CORE} ${TARGET_COMMAND} ${PROJECT_BINARY_DIR} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN GENERAT_NM + ) +endif() + +endif() diff --git a/build/cmake/build_function.cmake b/build/cmake/build_function.cmake new file mode 100755 index 0000000..3f84c7f --- /dev/null +++ b/build/cmake/build_function.cmake @@ -0,0 +1,195 @@ +#=============================================================================== +# @brief cmake toolchains +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== +macro(return_if_not_build) + if(NOT ${COMPONENT_NAME} IN_LIST TARGET_COMPONENT) + return() + endif() +endmacro() + +macro(add_subdirectory_if_exist _path) + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_path}/CMakeLists.txt) + add_subdirectory(${_path}) + endif() +endmacro() + +macro(add_subdirectory_with_alias_if_exist _path _path_alias) + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_path}/CMakeLists.txt) + add_subdirectory(${_path} ${_path_alias}) + endif() +endmacro() + +function(add_path_with_alias_if_exist _path _name) + if(EXISTS ${_path}/CMakeLists.txt) + add_subdirectory(${_path} ${_name}) + endif() +endfunction() + +function(add_path_if_exist _path) + if(EXISTS ${_path}/CMakeLists.txt) + add_subdirectory(${_path}) + endif() +endfunction() + +function(KCONFIG_GET_PARAMS KCONFIG_PATH) + file(STRINGS ${KCONFIG_PATH} LOS_CONFIG_LIST ENCODING "UTF-8") + + foreach (CONFIG ${LOS_CONFIG_LIST}) + # CONFIG maybe: CONFIG_CC_STACKPROTECTOR_STRONG=y + + # The first: variable name + string(REGEX MATCH "[^=]+" CONFIG_VAR_NAME ${CONFIG}) + + # The second: variable value + string(REGEX MATCH "=(.+$)" CONFIG_VAR_VAL ${CONFIG}) + set(CONFIG_VAR_VAL ${CMAKE_MATCH_1}) + if(CONFIG_VAR_VAL MATCHES "^y$" OR CONFIG_VAR_VAL MATCHES "^\".*\"$") + string(REPLACE "\"" "" CONFIG_VAR_VAL ${CONFIG_VAR_VAL}) + set(${CONFIG_VAR_NAME} ${CONFIG_VAR_VAL} PARENT_SCOPE) + endif() + endforeach() +endfunction() + +macro(check_if_closed_component component_name) + set(COMPONENT_IS_CLOSED false) + if("${component_name}" IN_LIST CLOSED_COMPONENTS) + set(COMPONENT_IS_CLOSED true) + endif() + if(DEFINED OPEN_COMPONENTS AND NOT ("${component_name}" IN_LIST OPEN_COMPONENTS)) + set(COMPONENT_IS_CLOSED true) + endif() +endmacro() + +macro(add_glob_include_path INCLUDE_PATHS) + get_property(GLOB_TARGET_INCLUDE GLOBAL PROPERTY TARGET_INCLUDE) + list(APPEND GLOB_TARGET_INCLUDE "${INCLUDE_PATHS}") + list(REMOVE_DUPLICATES GLOB_TARGET_INCLUDE) + set_property(GLOBAL PROPERTY TARGET_INCLUDE ${GLOB_TARGET_INCLUDE}) +endmacro(add_glob_include_path) + +macro(add_fsm_msgdef_headers MSGDEF_HEADERS) + get_property(GLOB_MSGDEF_HEADERS GLOBAL PROPERTY TARGET_MSGDEF_HEADERS) + list(APPEND GLOB_MSGDEF_HEADERS "${MSGDEF_HEADERS}") + list(REMOVE_DUPLICATES GLOB_MSGDEF_HEADERS) + set_property(GLOBAL PROPERTY TARGET_MSGDEF_HEADERS ${GLOB_MSGDEF_HEADERS}) +endmacro() + +macro(ut_autogen_fsms FSM_FILES AUTOGEN_SOURCES AUTOGEN_INCLUDE_PATH) + set(FSM_AUTOGEN_INCLUDE_PATH) + foreach(FILE_PATH ${FSM_FILES}) + if(EXISTS ${CMAKE_SOURCE_DIR}/../../../../../../protocol/cat1/lte/${FILE_PATH}) + get_filename_component(FILE_REL_PATH ${FILE_PATH} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + get_filename_component(FILE_DIRECTORY ${FILE_REL_PATH} DIRECTORY) + string(REGEX MATCH "${CMAKE_CURRENT_SOURCE_DIR}/" MATCH_RES ${FILE_DIRECTORY}) + if(MATCH_RES STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/") + set(AUTOGEN_PATH ${CMAKE_CURRENT_SOURCE_DIR}/stub/fsm_autogen) + file(MAKE_DIRECTORY ${AUTOGEN_PATH}) + file(RELATIVE_PATH FILE_RELATIVE_PATH ${CMAKE_SOURCE_DIR} ${FILE_REL_PATH}) + set(FSM_FILE_ABSOLUTE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../protocol/cat1/lte/${FSM_FILES}) + execute_process( + COMMAND python ${CMAKE_SOURCE_DIR}/../../../../../../tools/fsmgen/fsmgen.py ${FSM_FILE_ABSOLUTE_PATH} --out_dir ${AUTOGEN_PATH} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + list(APPEND FSM_AUTOGEN_INCLUDE_PATH ${AUTOGEN_PATH}) + endif() + endif() + endforeach() + + list(REMOVE_DUPLICATES FSM_AUTOGEN_INCLUDE_PATH) + foreach(FSM_GEN_PATCH ${FSM_AUTOGEN_INCLUDE_PATH}) + aux_source_directory(${FSM_GEN_PATCH} FSM_SOURCES) + list(APPEND ${AUTOGEN_SOURCES} ${FSM_SOURCES}) + file(GLOB FSM_MSGDEF_PUB_HEADERS "${FSM_AUTOGEN_INCLUDE_PATH}/*public.h") + file(GLOB FSM_MSGDEF_PRV_HEADERS "${FSM_AUTOGEN_INCLUDE_PATH}/*private.h") + foreach(FSM_MSGDEF_PRV_HEADER ${FSM_MSGDEF_PRV_HEADERS}) + string(REPLACE "${FSM_AUTOGEN_INCLUDE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/private" RET "${FSM_MSGDEF_PRV_HEADER}") + string(REPLACE "fsm_gen_private.h" "fsm_private.h" FSM_SRC_PRV_HEADER "${RET}") + string(REPLACE "fsm_gen_private.h" "fsm.h" FSM_SRC_HEADER "${RET}") + file(GLOB FSM_SRC_PRV_HEADERS "${FSM_SRC_PRV_HEADER}") + file(GLOB FSM_SRC_HEADERS "${FSM_SRC_HEADER}") + add_fsm_msgdef_headers("${FSM_SRC_PRV_HEADERS}") + add_fsm_msgdef_headers("${FSM_SRC_HEADERS}") + endforeach() + add_fsm_msgdef_headers("${FSM_MSGDEF_PUB_HEADERS}") + add_fsm_msgdef_headers("${FSM_MSGDEF_PRV_HEADERS}") + endforeach(FSM_GEN_PATCH) + set(${AUTOGEN_INCLUDE_PATH} ${FSM_AUTOGEN_INCLUDE_PATH}) +endmacro(ut_autogen_fsms) + +macro(autogen_fsms FSM_FILES AUTOGEN_SOURCES AUTOGEN_INCLUDE_PATH) + set(FSM_AUTOGEN_INCLUDE_PATH) + foreach(FILE_PATH ${FSM_FILES}) + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${FILE_PATH}) + get_filename_component(FILE_REL_PATH ${FILE_PATH} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + get_filename_component(FILE_DIRECTORY ${FILE_REL_PATH} DIRECTORY) + string(REGEX MATCH "${CMAKE_CURRENT_SOURCE_DIR}/" MATCH_RES ${FILE_DIRECTORY}) + if(MATCH_RES STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/") + set(AUTOGEN_PATH ${CMAKE_CURRENT_BINARY_DIR}/private) + file(MAKE_DIRECTORY ${AUTOGEN_PATH}) + # message(STATUS "Autogen fsm code form ${FILE_PATH}") + file(RELATIVE_PATH FILE_RELATIVE_PATH ${CMAKE_SOURCE_DIR} ${FILE_REL_PATH}) + execute_process( + COMMAND python ${CMAKE_SOURCE_DIR}/tools/fsmgen/fsmgen.py ${FILE_RELATIVE_PATH} --out_dir ${AUTOGEN_PATH} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + list(APPEND FSM_AUTOGEN_INCLUDE_PATH ${AUTOGEN_PATH}) + endif() + endif() + endforeach() + + list(REMOVE_DUPLICATES FSM_AUTOGEN_INCLUDE_PATH) + foreach(FSM_GEN_PATCH ${FSM_AUTOGEN_INCLUDE_PATH}) + aux_source_directory(${FSM_GEN_PATCH} FSM_SOURCES) + list(APPEND ${AUTOGEN_SOURCES} ${FSM_SOURCES}) + file(GLOB FSM_MSGDEF_PUB_HEADERS "${FSM_AUTOGEN_INCLUDE_PATH}/*public.h") + file(GLOB FSM_MSGDEF_PRV_HEADERS "${FSM_AUTOGEN_INCLUDE_PATH}/*private.h") + foreach(FSM_MSGDEF_PRV_HEADER ${FSM_MSGDEF_PRV_HEADERS}) + string(REPLACE "${FSM_AUTOGEN_INCLUDE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/private" RET "${FSM_MSGDEF_PRV_HEADER}") + string(REPLACE "fsm_gen_private.h" "fsm_private.h" FSM_SRC_PRV_HEADER "${RET}") + string(REPLACE "fsm_gen_private.h" "fsm.h" FSM_SRC_HEADER "${RET}") + file(GLOB FSM_SRC_PRV_HEADERS "${FSM_SRC_PRV_HEADER}") + file(GLOB FSM_SRC_HEADERS "${FSM_SRC_HEADER}") + add_fsm_msgdef_headers("${FSM_SRC_PRV_HEADERS}") + add_fsm_msgdef_headers("${FSM_SRC_HEADERS}") + endforeach() + add_fsm_msgdef_headers("${FSM_MSGDEF_PUB_HEADERS}") + add_fsm_msgdef_headers("${FSM_MSGDEF_PRV_HEADERS}") + endforeach(FSM_GEN_PATCH) + set(${AUTOGEN_INCLUDE_PATH} ${FSM_AUTOGEN_INCLUDE_PATH}) +endmacro(autogen_fsms) + +macro(autogen_rpc_code RPC_JSON_PATH) + if(${CORE} STREQUAL "protocol_core") + set(RPC_CORE "protocol") + elseif(${CORE} STREQUAL "acore") + set(RPC_CORE "application") + endif() + if(DEFINED RPC_CORE) + string(REPLACE "_" "-" TARGET_DIR ${BUILD_TARGET_NAME}) + set(RPC_BASE_PATH ${CMAKE_SOURCE_DIR}/output/${CHIP}/${CORE}/${TARGET_DIR}/rpc_autogen) + set(PRC_INCLUDE_DIR_PATH ${RPC_BASE_PATH}/public/${RPC_CORE}) + set(PRC_INCLUDE_FILE_PATH ${PRC_INCLUDE_DIR_PATH}/rpc_auto_generated.h) + set(RPC_SOURCE_FILE_PATH ${RPC_BASE_PATH}/private/${RPC_CORE}/rpc_auto_generated_${RPC_CORE}.c) + set(RPC_OPT_FILE_PATH ${RPC_BASE_PATH}/public/${RPC_CORE}/rpc_auto_generated_call_tree.opt) + set(RPC_SCRIPT_PATH ${CMAKE_SOURCE_DIR}/tools/fsmgen/autogen/rpc/json_to_rpc_code.py) + execute_process( + COMMAND python3 ${RPC_SCRIPT_PATH} ${RPC_CORE} ${RPC_SOURCE_FILE_PATH} ${PRC_INCLUDE_FILE_PATH} ${RPC_OPT_FILE_PATH} ${RPC_JSON_PATH} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + endif() +endmacro(autogen_rpc_code) + +macro(autogen_at_json_code) + string(REPLACE "_" "-" TARGET_DIR ${BUILD_TARGET_NAME}) + set(AT_GEN_DIR ${CMAKE_SOURCE_DIR}/output/${CHIP}/${CORE}/${TARGET_DIR}/at_autogen) + set(AT_GEN_TOOL ${CMAKE_SOURCE_DIR}/tools/fsmgen/autogen/at/json_to_at_code.py) + if((DEFINED TARGET_AT_JSON_FILES) AND (DEFINED AT_GEN_DIR)) + if(NOT EXISTS ${AT_GEN_DIR}) + file(MAKE_DIRECTORY ${AT_GEN_DIR}) + endif() + foreach(json_path ${TARGET_AT_JSON_FILES}) + execute_process(COMMAND python3 ${AT_GEN_TOOL} --outdir ${AT_GEN_DIR} --inputfile ${json_path}) + endforeach() + endif() +endmacro(autogen_at_json_code) diff --git a/build/cmake/build_hso_database.cmake b/build/cmake/build_hso_database.cmake new file mode 100755 index 0000000..153c825 --- /dev/null +++ b/build/cmake/build_hso_database.cmake @@ -0,0 +1,91 @@ +#=============================================================================== +# @brief cmake component build +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== + +add_custom_target(HSO_DB + COMMENT "Generating HSO_DB ${TARGET_NAME}" +) +if(DEFINED LOG_CUSTOM_ENABLE) + if(${LOG_CUSTOM_ENABLE} STREQUAL True) + include(${CMAKE_SOURCE_DIR}/build/script/hdbxml_custom/MessageXmlGen/messagexmlgen.cmake) + endif() +endif() + +function(create_hso_db) + if(DEFINED HSO_XML_CHIP) + set(XML_CHIP ${HSO_XML_CHIP}) + else() + set(XML_CHIP ${CHIP}) + endif() + + set(XML_FILE ${ROOT_DIR}/build/config/target_config/${XML_CHIP}/hdb_config/database_template/acore/system/hdbcfg/mss_cmd_db.xml) + add_custom_target(HSO_DB_MKDIR + COMMAND ${Python3_EXECUTABLE} ${MAK_HSO_XML} mkdir ${ROOT_DIR}/ ${XML_CHIP} ${CORE} + COMMENT "HSO_DB Makedir" + ) + + if(DEFINED LOG_CUSTOM_ENABLE) + if(${LOG_CUSTOM_ENABLE} STREQUAL True) + build_xml() + endif() + endif() + + foreach(COMPONENT ${TARGET_COMPONENT}) + if (NOT DEFINED ${COMPONENT}_SOURCES) + continue() + endif() + + set(CLOSED_FLAG "False") + check_if_closed_component(${COMPONENT}) + if (${COMPONENT_IS_CLOSED}) + set(CLOSED_FLAG "True") + endif() + list(JOIN LOG_DEF_LIST "," LOG_DEF) + list(JOIN ${COMPONENT}_SOURCES "," SOURCE) + # for windows command length limit + file(WRITE "${PROJECT_BINARY_DIR}/hso_temp/${COMPONENT}_temp.txt" "${LOG_DEF}####${SOURCE}") + add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/hso_temp/${COMPONENT}.txt + # for re-run HDB + COMMAND ${CP} ${PROJECT_BINARY_DIR}/hso_temp/${COMPONENT}_temp.txt ${PROJECT_BINARY_DIR}/hso_temp/${COMPONENT}.txt + COMMAND ${Python3_EXECUTABLE} ${MAK_HSO_XML} ${ROOT_DIR}/ ${XML_CHIP} ${CORE} ${ARCH} ${${COMPONENT}_AUTO_DEF} ${${COMPONENT}_MODULE_NAME} ${CLOSED_FLAG} ${PROJECT_BINARY_DIR}/hso_temp/${COMPONENT}.txt + COMMENT "Building HSO_DB_${COMPONENT}" + DEPENDS "${${COMPONENT}_SOURCES}" ${LOG_DEF_LIST} HSO_DB_MKDIR + ) + add_custom_target(HSO_DB_${COMPONENT} + DEPENDS ${PROJECT_BINARY_DIR}/hso_temp/${COMPONENT}.txt + ) + add_dependencies(HSO_DB HSO_DB_${COMPONENT}) + endforeach () + if(NOT DEFINED HSO_ENABLE_BT) + set(HSO_ENABLE_BT FALSE) + endif() + if(${CORE} STREQUAL "bt_core" OR ${HSO_ENABLE_BT} STREQUAL "True") + add_custom_target(HSO_DB_BT_STATUS + COMMAND ${Python3_EXECUTABLE} ${BT_STATUS_HSO_XML} ${ROOT_DIR}/ ${XML_CHIP} + COMMAND ${Python3_EXECUTABLE} ${OTA_MSG_HSO_XML} ${ROOT_DIR}/ ${XML_CHIP} + ) + add_dependencies(HSO_DB HSO_DB_BT_STATUS) + endif() + + add_custom_command(TARGET HSO_DB POST_BUILD + COMMENT "Merge HSO_XML & Create HSO_DB" + COMMAND ${Python3_EXECUTABLE} ${HSO_XML_PRE_PROCESS} ${ROOT_DIR}/ ${XML_CHIP} ${CORE} + COMMAND ${Python3_EXECUTABLE} ${HSO_XML_MERGE} ${ROOT_DIR}/ ${XML_CHIP} ${CORE} "${HSO_ENABLE_BT}" + COMMAND ${Python3_EXECUTABLE} ${HSO_XML_DB_CREATE} ${ROOT_DIR}/ ${XML_CHIP} + ) + if(NOT DEFINED GEN_PARSE_TOOL) + set(HSO_ENABLE_BT FALSE) + endif() + + if("${GEN_PARSE_TOOL}" STREQUAL "True") + set(INFO_FILE ${PROJECT_BINARY_DIR}/${BIN_NAME}.info) + set(NM_FILE ${PROJECT_BINARY_DIR}/${BIN_NAME}.nm) + set(PARSE_TOOL_DIR "${PROJECT_BINARY_DIR}/parse_tool") + add_custom_command(TARGET HSO_DB POST_BUILD + COMMAND ${Python3_EXECUTABLE} ${HSO_PARSE_MAIN} ${PARSE_TOOL_DIR} ${INFO_FILE} ${NM_FILE} ${XML_FILE} + COMMAND ${CP_PY} ${HSO_PARSE_DIR}/ ${PARSE_TOOL_DIR} "none" *.py + ) + endif() +endfunction(create_hso_db) diff --git a/build/cmake/build_linker.cmake b/build/cmake/build_linker.cmake new file mode 100755 index 0000000..f01a014 --- /dev/null +++ b/build/cmake/build_linker.cmake @@ -0,0 +1,84 @@ +#=============================================================================== +# @brief cmake deal with link script +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== + +if("${LINK_SCRIPT}" STREQUAL "") + MESSAGE(FATAL_ERROR "linkscript is not found!") +endif() + +function(auto_gen_lds macro_name lib_list) + file(APPEND ${CMAKE_BINARY_DIR}/auto_gen_libfunc.lds "#define ${macro_name}(func) \\\n") + set(LIB_FUNC "${${lib_list}}") + list(TRANSFORM LIB_FUNC PREPEND " func(*lib") + list(TRANSFORM LIB_FUNC APPEND ".a:*.o) \\\n") + file(APPEND ${CMAKE_BINARY_DIR}/auto_gen_libfunc.lds ${LIB_FUNC} "\n") +endfunction() + +# 添加用于处理链接脚本用的编译宏 +set(LDS_DEFINES ${DEFINES}) +list(TRANSFORM LDS_DEFINES PREPEND "-D") + +# 添加用于处理链接脚本用的编译头文件 +if(DEFINED LDS_HEADER) + list(REMOVE_ITEM LDS_HEADER "") + list(TRANSFORM LDS_HEADER PREPEND "-I") +else() + set(LDS_HEADER ${ALL_PUBLIC_HEADER}) + list(REMOVE_DUPLICATES LDS_HEADER) + list(REMOVE_ITEM LDS_HEADER "") + list(TRANSFORM LDS_HEADER PREPEND "-I") +endif() +list(APPEND LDS_HEADER -I${CMAKE_BINARY_DIR}) +if(DEFINED ROM_RAM_CHECK) + list(APPEND LDSDEFINES -DROM_BIN_CHECK) +endif() +list(TRANSFORM LDS_HEADER PREPEND "\"") +list(TRANSFORM LDS_HEADER APPEND "\"") +string(JOIN " " LDS_HEADER_STR ${LDS_HEADER}) +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/linker_header.srp "${LDS_HEADER_STR}") +auto_gen_lds("LIB_RAM_FUNC" RAM_COMPONENT) +auto_gen_lds("LIB_ROM_FUNC" ROM_COMPONENT) +auto_gen_lds("LIB_LOS_FUNC" LOS_LIB) + +if(DEFINED SDK_OUTPUT_PATH) + string(REPLACE "${PROJECT_SOURCE_DIR}" "${SDK_OUTPUT_PATH}" dest ${LINK_SCRIPT}) + get_filename_component(dest ${dest} DIRECTORY) + install(FILES ${LINK_SCRIPT} DESTINATION ${dest}) + install_sdk(${LINK_SCRIPT} "*.prelds") +endif() + +if(NOT DEFINED ROM_CHECK) + set(ROM_CHECK False) +endif() + +if(${ROM_CHECK}) + list(APPEND LDS_DEFINES "-DROM_CHECK") +endif() + +add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD + COMMAND ${CMAKE_C_COMPILER} -P -xc -E -o linker.lds @${CMAKE_CURRENT_BINARY_DIR}/linker_header.srp ${LDS_DEFINES} ${LINK_SCRIPT} + COMMENT "Generating ${LINK_SCRIPT} -> ${CMAKE_BINARY_DIR}/linker.lds" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + VERBATIM +) + +target_link_directories(${TARGET_NAME} + PRIVATE + ${LIB_GCC} + ${LIB_C} + ${LIB_CXX} +) + +target_link_libraries(${TARGET_NAME} +PRIVATE + -Wl,--start-group "${STD_LIBS}" -Wl,--end-group +) + +target_link_options(${TARGET_NAME} + PRIVATE + ${LINKFLAGS} + -Wl,-T${CMAKE_BINARY_DIR}/linker.lds -nostartfiles + -Wl,--gc-sections -Wl,-Map=${CMAKE_BINARY_DIR}/${BIN_NAME}.map + -Wl,--print-memory-usage +) diff --git a/build/cmake/build_nv_bin.cmake b/build/cmake/build_nv_bin.cmake new file mode 100755 index 0000000..f395fd4 --- /dev/null +++ b/build/cmake/build_nv_bin.cmake @@ -0,0 +1,71 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + +if(${NV_UPDATE}) + add_custom_target(GENERAT_NVBIN ALL + COMMAND ${Python3_EXECUTABLE} ${ROOT_DIR}/build/config/target_config/${CHIP}/build_nvbin.py ${TARGET_NAME} + COMMENT "update nv bin" + WORKING_DIRECTORY ${ROOT_DIR} + DEPENDS GENERAT_BIN + ) +endif() + +if(NOT ${NV_CFG} EQUAL "") + set(NV_CFG_JSON ${PROJECT_BINARY_DIR}/nv_config/build_nv_config.json) + set(OUT_BIN_DIR ${ROOT_DIR}/interim_binary/${CHIP}/bin/nv/${PKG_TARGET_NAME}) + if (NOT EXISTS ${OUT_BIN_DIR}) + file(MAKE_DIRECTORY ${OUT_BIN_DIR}) + endif() + set(OUT_BIN_NAME ${CHIP}_all_nv.bin) + set(BUILD_TEMP_PATH ${PROJECT_BINARY_DIR}/nv_config) + set(NV_TARGET_JSON_PATH ${ROOT_DIR}/middleware/chips/${CHIP}/nv/nv_config/nv_target.json) + set(NV_RELATIVE_PATH ${PROJECT_BINARY_DIR}/nv_config) + set(NV_DEFAULT_CFG_DIR ${ROOT_DIR}/middleware/chips/${CHIP}/nv/nv_config/${NV_CFG}/cfg) + set(DATABASE_TXT_FILE ${PROJECT_BINARY_DIR}/nv_config) + + + if (NOT EXISTS ${NV_CFG_JSON}) + file(WRITE ${NV_CFG_JSON} "{\"OUT_BIN_DIR\":\"${OUT_BIN_DIR}\", \ + \"OUT_BIN_NAME\":\"${OUT_BIN_NAME}\", \"BUILD_TEMP_PATH\":\"${BUILD_TEMP_PATH}\", \ + \"NV_TARGET_JSON_PATH\":\"${NV_TARGET_JSON_PATH}\", \"NV_RELATIVE_PATH\":\"${NV_RELATIVE_PATH}\", \ + \"NV_DEFAULT_CFG_DIR\":\"${NV_DEFAULT_CFG_DIR}\", \"DATABASE_TXT_FILE\":\"${DATABASE_TXT_FILE}\"}") + endif() + + set(TARGET_INCLUDE + -I${ROOT_DIR}/include + -I${ROOT_DIR}/middleware/utils/common_headers/native + -I${ROOT_DIR}/middleware/chips/${CHIP}/nv/nv_config/${NV_CFG}/include + ) + + set(TARGET_DEFINES -DCONFIG_NV_SUPPORT_SINGLE_CORE_SYSTEM) + + set(GEN_TARGET_DIR ${PROJECT_BINARY_DIR}/nv_config/etypes) + if (NOT EXISTS ${GEN_TARGET_DIR}) + file(MAKE_DIRECTORY ${GEN_TARGET_DIR}) + endif() + set(GEN_TARGET_SRC ${GEN_TARGET_DIR}/${CORE}.c) + set(PRECOMPILE_TARGET ${GEN_TARGET_DIR}/${CORE}.etypes) + + add_custom_target(GENERAT_NV_INFO ALL + COMMAND ${Python3_EXECUTABLE} ${BUILD_NV_GEN_UTILS} NV include ${GEN_TARGET_SRC} + COMMAND ${CMAKE_C_COMPILER} -o ${PRECOMPILE_TARGET} ${TARGET_INCLUDE} ${TARGET_DEFINES} -E ${GEN_TARGET_SRC} + WORKING_DIRECTORY ${ROOT_DIR}/middleware/chips/${CHIP}/nv/nv_config/${NV_CFG} + DEPENDS GENERAT_BIN + ) + + if (${NV_CRC16}) + set(CRC_FLAGS True) + else() + set(CRC_FLAGS False) + endif() + + add_custom_target(GENERAT_NVBIN ALL + COMMAND ${Python3_EXECUTABLE} ${BUILD_NV_TOOL} ${NV_CFG_JSON} ${CORE} ${CRC_FLAGS} && + ${CP} ${OUT_BIN_DIR}/${OUT_BIN_NAME} ${PROJECT_BINARY_DIR}/${OUT_BIN_NAME} + COMMENT "update nv bin" + WORKING_DIRECTORY ${ROOT_DIR} + DEPENDS GENERAT_NV_INFO + ) +endif() diff --git a/build/cmake/build_partition_bin.cmake b/build/cmake/build_partition_bin.cmake new file mode 100755 index 0000000..ab417fc --- /dev/null +++ b/build/cmake/build_partition_bin.cmake @@ -0,0 +1,19 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + +if(NOT "${SECTOR_CFG}" STREQUAL "") + SET(SECTOR_JSON ${ROOT_DIR}/build/config/target_config/${CHIP}/flash_sector_config/${SECTOR_CFG}.json) + SET(SECTOR_BIN_PATH ${ROOT_DIR}/interim_binary/${CHIP}/bin/partition/${PKG_TARGET_NAME}) + if (NOT EXISTS ${SECTOR_BIN_PATH}) + file(MAKE_DIRECTORY ${SECTOR_BIN_PATH}) + endif() + add_custom_target(GENERAT_PARTITION ALL + COMMAND ${Python3_EXECUTABLE} ${ROOT_DIR}/build/script/param_packet.py ${SECTOR_JSON} ${SECTOR_BIN_PATH}/partition.bin && + ${CP} ${SECTOR_BIN_PATH}/partition.bin ${PROJECT_BINARY_DIR}/partition.bin + COMMENT "update partition bin" + WORKING_DIRECTORY ${ROOT_DIR} + DEPENDS GENERAT_BIN + ) +endif() diff --git a/build/cmake/build_rom_callback.cmake b/build/cmake/build_rom_callback.cmake new file mode 100755 index 0000000..1920314 --- /dev/null +++ b/build/cmake/build_rom_callback.cmake @@ -0,0 +1,43 @@ +if(NOT DEFINED BUILD_ROM_CALLBACK) + set(BUILD_ROM_CALLBACK False) +endif() +set(OBJ_TEMP_DIR "${PROJECT_BINARY_DIR}/obj_tmp") + +macro(reg_rom_callback) + if(NOT TARGET ${COMPONENT_NAME}) + set(ROM_LIB ${LIBS}) + set(DEPEND_TARGET) + else() + get_target_property(ORI_LIB_DIR ${COMPONENT_NAME} BINARY_DIR) + get_target_property(CUSTOM_LIB_DIR ${COMPONENT_NAME} ARCHIVE_OUTPUT_DIRECTORY) + if(CUSTOM_LIB_DIR) + set(ROM_LIB ${CUSTOM_LIB_DIR}/lib${COMPONENT_NAME}.a) + else() + set(ROM_LIB ${ORI_LIB_DIR}/lib${COMPONENT_NAME}.a) + endif() + set(DEPEND_TARGET ${COMPONENT_NAME}) + endif() + + add_custom_target(GEN_ROM_CB_${COMPONENT_NAME} ALL + WORKING_DIRECTORY ${OBJ_TEMP_DIR} + COMMAND echo "${ROM_LIB}" + COMMAND ${CP} ${ROM_LIB} ${OBJ_TEMP_DIR} + COMMAND ${CMAKE_AR} -x lib${COMPONENT_NAME}.a + DEPENDS ${DEPEND_TARGET} + ) +endmacro() + +function(build_rom_callback) + execute_process( + COMMAND ${MKDIR} ${OBJ_TEMP_DIR} + ) + add_custom_target(BUILD_ROM_CALLBACK ALL + COMMAND ${CMAKE_LINKER} -r ${OBJ_TEMP_DIR}/*.o* -o ${OBJ_TEMP_DIR}/rom_bin.o + COMMAND ${CMAKE_NM} -u ${OBJ_TEMP_DIR}/rom_bin.o > rom_bin_raw.undef + COMMAND ${CMAKE_READELF} -W -r ${OBJ_TEMP_DIR}/rom_bin.o > rom_bin.rel + COMMAND ${CMAKE_READELF} -W -s ${OBJ_TEMP_DIR}/rom_bin.o > rom_symbol.list + COMMAND ${CMAKE_READELF} -W -s ${TARGET_NAME}.elf > image_symbol.list + DEPENDS ${TARGET_NAME} + ) + +endfunction(build_rom_callback) diff --git a/build/cmake/build_script.cmake b/build/cmake/build_script.cmake new file mode 100755 index 0000000..90795a4 --- /dev/null +++ b/build/cmake/build_script.cmake @@ -0,0 +1,56 @@ +#=============================================================================== +# @brief cmake script path +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== + +set(SCRIPT_DIR "${ROOT_DIR}/build/script") + +set(PRO_GEN ${SCRIPT_DIR}/sdk_generator/project_generator.py) +set(BUILD_UTILS ${SCRIPT_DIR}/utils/build_utils.py) +set(ELF_TO_DU ${SCRIPT_DIR}/utils/elftodu.py) +set(MEM_STATE ${SCRIPT_DIR}/utils/mem_stats.py) +set(PARSE_MAP_SIZE_INFO ${SCRIPT_DIR}/utils/parse_map_size_info.py) +set(GEN_HEX ${SCRIPT_DIR}/utils/create_hex.py) +set(GEN_PATCH ${SCRIPT_DIR}/patch/patch_${ARCH_FAMILY}.py) + +# HSO script +set(HDB_SCRIPT_DIR ${SCRIPT_DIR}/hdbxml) +set(MAK_HSO_XML ${HDB_SCRIPT_DIR}/mk_hso_prim_xml.py) +set(BT_STATUS_HSO_XML ${HDB_SCRIPT_DIR}/bt_status_to_hso_prim_xml.py) +set(OTA_MSG_HSO_XML ${HDB_SCRIPT_DIR}/ota_msg_to_hso_prim_xml.py) +set(HSO_XML_MERGE ${HDB_SCRIPT_DIR}/hso_prim_xml_merge.py) +set(HSO_XML_DB_CREATE ${HDB_SCRIPT_DIR}/database_create.py) +set(HSO_XML_PRE_PROCESS ${HDB_SCRIPT_DIR}/process_pregenerated_xml.py) + +# PARSE script +set(OUTPUT_DIR "${ROOT_DIR}/output") +set(HSO_PARSE_DIR ${SCRIPT_DIR}/parse_tool) +set(HSO_PARSE_MAIN ${HSO_PARSE_DIR}/parse_main_phase1.py) + +# sign tool +set(SIGN_TOOL ${ROOT_DIR}/tools/bin/sign_tool/sign_tool_pltuni) + +# concat tool +set(CONCAT_TOOL ${ROOT_DIR}/build/script/concat_bin.py) + +# build nv tool +set(BUILD_NV_TOOL ${ROOT_DIR}/build/script/build_nvbin.py) +set(BUILD_NV_GEN_UTILS ${ROOT_DIR}/build/script/nv/generate_utils.py) + +# sec tool +if(${BUILD_PLATFORM} MATCHES "linux") +set(SEC_OBJCPY_TOOL ${ROOT_DIR}/tools/bin/sec_tool/linux/riscv32-linux-musl-objcopy) +set(SEC_TOOL_DIR ${ROOT_DIR}/tools/bin/sec_tool/linux) +elseif(${BUILD_PLATFORM} MATCHES "windows") +set(SEC_OBJCPY_TOOL ${ROOT_DIR}/tools/bin/sec_tool/win/riscv32-linux-musl-objcopy.exe) +set(SEC_TOOL_DIR ${ROOT_DIR}/tools/bin/sec_tool/win) +endif() + +# rom info gen script +set(GEN_ROM_INFO_TOOL ${ROOT_DIR}/tools/bin/remote_lib_tool/remote_lib_sym2addr.py) + +# IMAGE ANALYSIS script +set(IMAGE_ANALSIS_TOOL ${SCRIPT_DIR}/image_analysis/build_data_analyzer_allinone.py) + +# CODESIZE_STATISTIC script +set(CODESIZE_STATISTIC_TOOL ${SCRIPT_DIR}/codesize_statistic.py) diff --git a/build/cmake/build_sdk.cmake b/build/cmake/build_sdk.cmake new file mode 100755 index 0000000..3a2d241 --- /dev/null +++ b/build/cmake/build_sdk.cmake @@ -0,0 +1,241 @@ +#=============================================================================== +# @brief cmake sdk build +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== + +# copy file or dir to the dest path in sdk +function(install_dest_sdk src sdk_dest partern) + if (NOT DEFINED SDK_OUTPUT_PATH) + return() + endif() + string(REPLACE "*" "all" _partern ${partern}) + string(REPLACE "/" "_" _name ${src}_${_partern}) + string(REPLACE "@" "_" _name ${_name}) + if(TARGET COPY${_name}) + return() + endif() + string(REPLACE "${ROOT_DIR}" "${SDK_OUTPUT_PATH}" dest ${sdk_dest}) + add_custom_target(COPY${_name} ALL + COMMENT "--Installing ${src} => ${dest}" + COMMAND ${Python3_EXECUTABLE} ${BUILD_UTILS} copy "${src}" "${dest}" ".srcrelease" '${partern}' + ) + add_dependencies(COPY${_name} ${TARGET_NAME}) +endfunction() + +# copy file or dir to it's sdk path +function(install_sdk src partern) + if (NOT DEFINED SDK_OUTPUT_PATH) + return() + endif() + string(REPLACE "/" "_" _name ${src}) + string(REPLACE "@" "_" _name ${_name}) + if(TARGET COPY${_name}) + return() + endif() + string(REPLACE "${ROOT_DIR}" "${SDK_OUTPUT_PATH}" dest ${src}) + add_custom_target(COPY${_name} ALL + COMMENT "--Installing ${src} => ${dest}" + COMMAND ${Python3_EXECUTABLE} ${BUILD_UTILS} copy "${src}" "${dest}" ".srcrelease" '${partern}' + ) + add_dependencies(COPY${_name} ${TARGET_NAME}) +endfunction() + +function(install_sdk_by_sh src partern) + if (NOT DEFINED SDK_OUTPUT_PATH) + return() + endif() + return_if_not_build() + string(REPLACE "*" "all" _partern ${partern}) + string(REPLACE "/" "_" _name ${src}_${_partern}) + string(REPLACE "@" "_" _name ${_name}) + if(TARGET COPY${_name}) + return() + endif() + string(REPLACE "${ROOT_DIR}" "${SDK_OUTPUT_PATH}" dest ${src}) + add_custom_target(COPY${_name} ALL + COMMENT "--Installing ${src} => ${dest}" + COMMAND mkdir -p "${dest}" + COMMAND cp -rf "${src}/${partern}" "${dest}" || : + ) + add_dependencies(COPY${_name} ${TARGET_NAME}) +endfunction() + +macro(install_lib_gen) + if (DEFINED SDK_OUTPUT_PATH AND DEFINED LIB_GEN_NAME AND ${COMPONENT_NAME} IN_LIST SDK_LIBGEN_COMPONENTS) + set(LIB_OUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_GEN_NAME}) + string(REPLACE "${ROOT_DIR}" "${SDK_OUTPUT_PATH}" LIB_OUT_PATH ${LIB_OUT_PATH}) + endif() +endmacro() + +macro(export_component_info) +file(WRITE ${PROJECT_BINARY_DIR}/component_info/${COMPONENT_NAME} "SOURCES: ${SOURCES}\n") +file(APPEND ${PROJECT_BINARY_DIR}/component_info/${COMPONENT_NAME} "HEADER: ${PRIVATE_HEADER}\n") +file(APPEND ${PROJECT_BINARY_DIR}/component_info/${COMPONENT_NAME} "DEFINES: ${PRIVATE_DEFINES}\n") +file(APPEND ${PROJECT_BINARY_DIR}/component_info/${COMPONENT_NAME} "COMPONENT_FLAGS: ${COMPONENT_FLAGS}\n") +endmacro() + +macro(export_public_info) +file(WRITE ${PROJECT_BINARY_DIR}/component_info/PUBLIC "PUBLIC_HEADER: ${ALL_PUBLIC_HEADER}\n") +file(APPEND ${PROJECT_BINARY_DIR}/component_info/PUBLIC "PUBLIC_DEFINES: ${ALL_PUBLIC_DEFINES}\n") +endmacro() + +macro(add_tooltrain) +set(TOOLCHAIN_FILE ${PROJECT_BINARY_DIR}/toolchains/${TARGET_NAME}.json) +file(WRITE ${TOOLCHAIN_FILE} +"{ + \"CC\": \"${CMAKE_C_COMPILER}\", + \"CXX\": \"${CMAKE_CXX_COMPILER}\", + \"AS\": \"${CMAKE_ASM_COMPILER}\", + \"LD\": \"${CMAKE_LINKER}\", + \"AR\": \"${CMAKE_AR}\", + \"RANLIB\": \"${CMAKE_RANLIB}\", + \"STRIP\": \"${CMAKE_STRIP}\", + \"NM\": \"${CMAKE_NM}\", + \"OBJCOPY\": \"${CMAKE_OBJCOPY}\", + \"READELF\": \"${CMAKE_READELF}\", + \"OBJDUMP\": \"${CMAKE_OBJDUMP}\" +}") +endmacro(add_tooltrain) + +macro(sdk_export_component type) +if (DEFINED SDK_OUTPUT_PATH) + set(COMPONENT_INFO ${PROJECT_BINARY_DIR}/component_info/info.json) + if(${type} STREQUAL "start") + set(START_SYMBOL "" CACHE INTERNAL "" FORCE) + file(WRITE ${COMPONENT_INFO} "{\n") + file(APPEND ${COMPONENT_INFO} + "\"COMPONENTS\":{") + elseif(${type} STREQUAL "end") + set(PUBLIC_INCLUDES) + foreach(pub_header ${ALL_PUBLIC_HEADER}) + get_filename_component(header ${pub_header} ABSOLUTE) + if (NOT ${header} IN_LIST PUBLIC_INCLUDES) + set(PUBLIC_INCLUDES ${PUBLIC_INCLUDES} ${header}) + endif() + endforeach() + list(REMOVE_DUPLICATES ALL_PUBLIC_DEFINES) + list(REMOVE_DUPLICATES ALL_PUBLIC_CCFLAGS) + list(REMOVE_DUPLICATES LOG_DEF_LIST) + set(STD_LIB_DIR ${LIB_GCC} ${LIB_C} ${LIB_CXX}) + file(APPEND ${COMPONENT_INFO} "},") + file(APPEND ${COMPONENT_INFO} "\"PUBLIC_INCLUDES\": \"${PUBLIC_INCLUDES}\",\n") + file(APPEND ${COMPONENT_INFO} "\"PUBLIC_DEFINES\": \"${ALL_PUBLIC_DEFINES}\",\n") + file(APPEND ${COMPONENT_INFO} "\"PUBLIC_CCFLAGS\": \"${ALL_PUBLIC_CCFLAGS}\",\n") + file(APPEND ${COMPONENT_INFO} "\"BIN_NAME\": \"${BIN_NAME}\",\n") + file(APPEND ${COMPONENT_INFO} "\"LINKFLAGS\": \"${LINKFLAGS}\",\n") + file(APPEND ${COMPONENT_INFO} "\"STD_LIB_DIR\": \"${STD_LIB_DIR}\",\n") + file(APPEND ${COMPONENT_INFO} "\"STD_LIBS\": \"${STD_LIBS}\",\n") + file(APPEND ${COMPONENT_INFO} "\"ARCH_FAMILY\": \"${ARCH_FAMILY}\",\n") + file(APPEND ${COMPONENT_INFO} "\"LINK_SCRIPT\": \"${LINK_SCRIPT}\",\n") + file(APPEND ${COMPONENT_INFO} "\"KERNEL\": \"${OS}\",\n") + file(APPEND ${COMPONENT_INFO} "\"LOS_ROOT\": \"${LOS_ROOT}\",\n") + file(APPEND ${COMPONENT_INFO} "\"LOS_PUB_CCFLAGS\": \"${LOS_PUB_CCFLAGS}\",\n") + file(APPEND ${COMPONENT_INFO} "\"LOG_DEF_LIST\": \"${LOG_DEF_LIST}\"\n") + file(APPEND ${COMPONENT_INFO} "}") + elseif(${type} STREQUAL "third_party") + if(DEFINED LIB_DIR) + set(LINK_LIB_DIR ${LIB_DIR}) + else() + set(LINK_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + file(APPEND ${COMPONENT_INFO} + "${START_SYMBOL} + \"${COMPONENT_NAME}\":{ + \"SOURCES\": \"${SOURCES}\", + \"THIRD_PARTY\": \"true\", + \"WHOLE_LINK\": \"${WHOLE_ARCHIV}\", + \"COMPONENT_CUSTOM_INCLUDE\": \"${COMPONENT_CUSTOM_INCLUDE}\", + \"LIB_DIR\":\"${LINK_LIB_DIR}\", + \"COMPONENT_CUSTOM_CCFLAGS\":\"${COMPONENT_CUSTOM_CCFLAGS}\", + \"COMPONENT_CUSTOM_DEFINES\":\"${COMPONENT_CUSTOM_DEFINES}\", + \"LIBS\":\"${LIBS}\" + } + ") + set(START_SYMBOL "," CACHE INTERNAL "" FORCE) + else() + if(DEFINED LIB_DIR) + set(LINK_LIB_DIR ${LIB_DIR}) + else() + check_if_closed_component(${COMPONENT_NAME}) + if (${COMPONENT_IS_CLOSED}) + set(LINK_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_COMMAND}) + else() + set(LINK_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + endif() + + check_if_closed_component(${COMPONENT_NAME}) + if (${COMPONENT_IS_CLOSED}) + file(APPEND ${COMPONENT_INFO} + "${START_SYMBOL} + \"${COMPONENT_NAME}\":{ + \"SOURCES\": \"\", + \"PRIVATE_INCLUDE\": \"\", + \"PRIVATE_DEFINES\": \"\", + \"PRIVATE_CCFLAGS\": \"\", + \"WHOLE_LINK\": \"${WHOLE_ARCHIV}\", + \"LIB_DIR\":\"${LINK_LIB_DIR}\", + \"LIBS\":\"${LIBS}\", + \"MODULE_NAME\":\"${${COMPONENT_NAME}_MODULE_NAME}\", + \"AUTO_DEF\":\"${${COMPONENT_NAME}_AUTO_DEF}\" + } + ") + else() + file(APPEND ${COMPONENT_INFO} + "${START_SYMBOL} + \"${COMPONENT_NAME}\":{ + \"SOURCES\": \"${SOURCES}\", + \"PRIVATE_INCLUDE\": \"${PRIVATE_HEADER}\", + \"PRIVATE_DEFINES\": \"${PRIVATE_DEFINES}\", + \"PRIVATE_CCFLAGS\": \"${COMPONENT_CCFLAGS}\", + \"WHOLE_LINK\": \"${WHOLE_ARCHIV}\", + \"LIB_DIR\":\"${LINK_LIB_DIR}\", + \"LIBS\":\"${LIBS}\", + \"MODULE_NAME\":\"${${COMPONENT_NAME}_MODULE_NAME}\", + \"AUTO_DEF\":\"${${COMPONENT_NAME}_AUTO_DEF}\" + } + ") + endif() + set(START_SYMBOL "," CACHE INTERNAL "" FORCE) + endif() +endif() +endmacro() + +function(generate_project_file) + if (NOT DEFINED SDK_OUTPUT_PATH) + return() + endif() + set(COMPONENT_INFO ${PROJECT_BINARY_DIR}/component_info/info.json) + add_tooltrain() + set(CC_JSON "${PROJECT_BINARY_DIR}/compile_commands.json") + if("${SDK_PROJECT_FILE_DIR}" STREQUAL "" ) + set(SDK_PROJECT_FILE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + string(REPLACE "${PROJECT_SOURCE_DIR}" "${SDK_OUTPUT_PATH}" SDK_CURRENT_DIR ${SDK_PROJECT_FILE_DIR}) + string(REPLACE "${PROJECT_SOURCE_DIR}" "${SDK_OUTPUT_PATH}" SDK_CURRENT_COMPILER_DIR ${COMPILER_ROOT}) + list(JOIN SDK_TYPE "," SDK_TYPE_LIST) + + add_custom_target(GEN_PROJECT ALL + COMMAND ${Python3_EXECUTABLE} ${PRO_GEN} "${SDK_TYPE_LIST}" "${MAIN_COMPONENT}" "${CC_JSON}" "${SDK_CURRENT_DIR}" "${PROJECT_SOURCE_DIR}" "${SDK_OUTPUT_PATH}" "${CHIP},${CORE},${BOARD},${ARCH},${OS},${PKG_TARGET_NAME}" "${TOOLCHAIN_FILE}" "${COMPONENT_INFO}" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Generating project file..." + ) + + add_dependencies(GEN_PROJECT "${TARGET_NAME}") + if(NOT EXISTS ${SDK_CURRENT_COMPILER_DIR}) + get_filename_component(SDK_CURRENT_COMPILER_DIR_ABS "${SDK_CURRENT_COMPILER_DIR}/.." ABSOLUTE) + add_custom_target(GEN_COMPILER_LN ALL + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMAND mkdir -p ${SDK_CURRENT_COMPILER_DIR_ABS} + COMMAND ln -s ${COMPILER_ROOT} ${SDK_CURRENT_COMPILER_DIR} + ) + if(DEFINED COMPILER_ROOT_WIN AND EXISTS ${COMPILER_ROOT_WIN}) + add_custom_target(GEN_COMPILER_WIN_LN ALL + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMAND ln -s ${COMPILER_ROOT_WIN} ${SDK_CURRENT_COMPILER_DIR_ABS} + DEPENDS GEN_COMPILER_LN + ) + endif() + + endif() +endfunction(generate_project_file) diff --git a/build/cmake/build_sdk_lib.cmake b/build/cmake/build_sdk_lib.cmake new file mode 100755 index 0000000..f0b9d62 --- /dev/null +++ b/build/cmake/build_sdk_lib.cmake @@ -0,0 +1,41 @@ +#=============================================================================== +# @brief cmake sdk build +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +#=============================================================================== + + +if ("${GEN_SEC_BIN}" STREQUAL "True") + if (NOT EXISTS ${COMPILER_ROOT}/lib/sec) + file(MAKE_DIRECTORY ${COMPILER_ROOT}/lib/sec) + endif() + if (NOT EXISTS ${COMPILER_ROOT}_win/lib/sec) + file(MAKE_DIRECTORY ${COMPILER_ROOT}_win/lib/sec) + endif() + # tools libs + execute_process(COMMAND ${CP} ${ROOT_DIR}/tools/bin/sec_tool/lib/sec/${IMAGE_VERSION}/libsec_image.so ${ROOT_DIR}/tools/bin/sec_tool/lib/sec/libsec_image.so) + execute_process(COMMAND ${CP} ${ROOT_DIR}/tools/bin/sec_tool/lib/sec/${IMAGE_VERSION}/libsec_image.pyd ${ROOT_DIR}/tools/bin/sec_tool/lib/sec/libsec_image.pyd) + execute_process(COMMAND ${CP} ${ROOT_DIR}/tools/bin/sec_tool/lib/sec/${IMAGE_VERSION}/libsec_image.so ${COMPILER_ROOT}/lib/sec/libsec_image.so) + execute_process(COMMAND ${CP} ${ROOT_DIR}/tools/bin/sec_tool/lib/sec/${IMAGE_VERSION}/libsec_image.pyd ${COMPILER_ROOT}_win/lib/sec/libsec_image.pyd) + # linux + execute_process(COMMAND ${CP} ${ROOT_DIR}/tools/bin/sec_tool/linux/riscv32-linux-musl-objcopy ${COMPILER_ROOT}/bin/riscv32-linux-musl-objcopy) + execute_process(COMMAND ${CP} ${ROOT_DIR}/tools/bin/sec_tool/linux/riscv32-linux-secmain ${COMPILER_ROOT}/bin/riscv32-linux-secmain) + + if(${CORE} STREQUAL "acore") + # win: only acore will build win. + execute_process(COMMAND ${CP} ${ROOT_DIR}/tools/bin/sec_tool/win/riscv32-linux-musl-objcopy.exe ${COMPILER_ROOT}_win/bin/riscv32-linux-musl-objcopy.exe) + execute_process(COMMAND ${CP} ${ROOT_DIR}/tools/bin/sec_tool/win/riscv32-linux-secmain.exe ${COMPILER_ROOT}_win/bin/riscv32-linux-secmain.exe) + # image info + if (EXISTS ${ROOT_DIR}/middleware/chips/${CHIP}/image_info/${IMAGE_VERSION}/libapp_info_nofp.a) + execute_process(COMMAND ${CP} ${ROOT_DIR}/middleware/chips/${CHIP}/image_info/${IMAGE_VERSION}/libapp_info_nofp.a ${ROOT_DIR}/middleware/chips/${CHIP}/image_info/libapp_info_nofp.a) + endif() + + if (EXISTS ${ROOT_DIR}/middleware/chips/${CHIP}/image_info/${IMAGE_VERSION}/libimage_info.a) + execute_process(COMMAND ${CP} ${ROOT_DIR}/middleware/chips/${CHIP}/image_info/${IMAGE_VERSION}/libimage_info.a ${ROOT_DIR}/middleware/chips/${CHIP}/image_info/libimage_info.a) + endif() + + elseif(${CORE} STREQUAL "bt_core") + if (EXISTS ${ROOT_DIR}/application/${CHIP}/${CHIP}_bgle/common/lib/image_info/${IMAGE_VERSION}/libimage_info.a) + execute_process(COMMAND ${CP} ${ROOT_DIR}/application/${CHIP}/${CHIP}_bgle/common/lib/image_info/${IMAGE_VERSION}/libimage_info.a ${ROOT_DIR}/application/${CHIP}/${CHIP}_bgle/common/lib/image_info/libimage_info.a) + endif() + endif() +endif() diff --git a/build/cmake/build_sign.cmake b/build/cmake/build_sign.cmake new file mode 100755 index 0000000..1d620e8 --- /dev/null +++ b/build/cmake/build_sign.cmake @@ -0,0 +1,158 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. +#=============================================================================== + +if (${TARGET_NAME} STREQUAL "flashboot") +if (EXISTS ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/${BUILD_TARGET_NAME}.cfg) + if (NOT ${SEC_BOOT} STREQUAL "") + add_custom_target(CONCAT_BIN ALL + COMMAND ${Python3_EXECUTABLE} ${CONCAT_TOOL} ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${SEC_BOOT}/sec_boot.bin ${PROJECT_BINARY_DIR}/flashboot.bin ${SEC_BOOT_SIZE} ${PROJECT_BINARY_DIR}/flashboot.bin + COMMENT "concat bin" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN + ) + endif() + add_custom_target(GENERAT_SIGNBIN ALL + COMMAND ${SIGN_TOOL} 0 ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/${BUILD_TARGET_NAME}.cfg 1>nul 2>nul && + ${CP} ${PROJECT_BINARY_DIR}/flashboot_sign_a.bin ${PROJECT_BINARY_DIR}/flashboot_sign_b.bin + COMMENT "sign file:gen boot sign file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN + ) + if (NOT ${SEC_BOOT} STREQUAL "") + add_dependencies(GENERAT_SIGNBIN CONCAT_BIN) + endif() + if (${UPDATE_BIN}) + string(REPLACE "_" "-" TARGET_DIR ${BUILD_TARGET_NAME}) + if (NOT EXISTS ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin) + file(MAKE_DIRECTORY ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin) + endif() + if (NOT EXISTS ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}) + file(MAKE_DIRECTORY ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}) + endif() + add_custom_target(COPY_SIGNBIN ALL + COMMAND ${CP} ${ROOT_DIR}/output/${CHIP}/acore/${TARGET_DIR}/flashboot_sign_a.bin ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}/flashboot_sign_a.bin && + ${CP} ${ROOT_DIR}/output/${CHIP}/acore/${TARGET_DIR}/flashboot_sign_a.bin ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}/flashboot_sign_b.bin + COMMENT "copy bin file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_SIGNBIN + ) + endif() +endif() +elseif (${TARGET_NAME} STREQUAL "loaderboot") +if (EXISTS ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/${BUILD_TARGET_NAME}.cfg) + add_custom_target(GENERAT_SIGNBIN ALL + COMMAND ${SIGN_TOOL} 0 ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/${BUILD_TARGET_NAME}.cfg 1>nul 2>nul + COMMENT "sign file:gen boot sign file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN + ) + if (${UPDATE_BIN}) + string(REPLACE "_" "-" TARGET_DIR ${BUILD_TARGET_NAME}) + if (NOT EXISTS ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin) + file(MAKE_DIRECTORY ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin) + endif() + if (NOT EXISTS ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}) + file(MAKE_DIRECTORY ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}) + endif() + add_custom_target(COPY_SIGNBIN ALL + COMMAND ${CP} ${ROOT_DIR}/output/${CHIP}/acore/${TARGET_DIR}/loaderboot_sign.bin ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}/loaderboot_sign.bin + COMMENT "copy bin file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_SIGNBIN + ) + endif() +endif() +elseif (${TARGET_NAME} MATCHES "application*" OR ${TARGET_NAME} STREQUAL "ate_debug" OR ${TARGET_NAME} STREQUAL "ate" OR + ${TARGET_NAME} MATCHES "protocol*" ) +if (EXISTS ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/${BUILD_TARGET_NAME}.cfg) +add_custom_target(GENERAT_SIGNBIN ALL + COMMAND ${SIGN_TOOL} 0 ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/${BUILD_TARGET_NAME}.cfg 1>nul 2>nul + COMMENT "sign file:gen boot sign file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN +) +endif() +elseif (${TARGET_NAME} MATCHES "control_ws53*") +if (EXISTS ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/${BUILD_TARGET_NAME}.cfg) +add_custom_target(GENERAT_SIGNBIN ALL + COMMAND ${SIGN_TOOL} 0 ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/${BUILD_TARGET_NAME}.cfg + COMMENT "sign file:gen boot sign file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN +) +endif() +endif() +if (${CHIP} STREQUAL "ws63") +add_custom_target(WS63_GENERAT_SIGNBIN ALL + COMMAND ${Python3_EXECUTABLE} ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/params_and_bin_sign.py ${TARGET_NAME} + COMMENT "ws63 image sign" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN +) + +if(TARGET GENERAT_ROM_PATCH) + add_dependencies(WS63_GENERAT_SIGNBIN GENERAT_ROM_PATCH) +endif() +endif() + +if (${CHIP} STREQUAL "ws53") +add_custom_target(WS53_GENERAT_SIGNBIN ALL + COMMAND sh ${ROOT_DIR}/build/config/target_config/${CHIP}/sign_config/params_and_bin_sign.sh + COMMENT "ws53 image sign" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN +) + +if(TARGET GENERAT_ROM_PATCH) + add_dependencies(WS53_GENERAT_SIGNBIN GENERAT_ROM_PATCH) +endif() +endif() + +if(TARGET GENERAT_ROM_PATCH AND TARGET GENERAT_SIGNBIN) + add_dependencies(GENERAT_SIGNBIN GENERAT_ROM_PATCH) +endif() + +if (${TARGET_NAME} STREQUAL "sec_boot") + if (${UPDATE_BIN}) + string(REPLACE "_" "-" TARGET_DIR ${BUILD_TARGET_NAME}) + if (NOT EXISTS ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin) + file(MAKE_DIRECTORY ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin) + endif() + if (NOT EXISTS ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}) + file(MAKE_DIRECTORY ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}) + endif() + add_custom_target(COPY_SEC_BOOTBIN ALL + COMMAND ${CP} ${ROOT_DIR}/output/${CHIP}/acore/${TARGET_DIR}/sec_boot.bin ${ROOT_DIR}/interim_binary/${CHIP}/bin/boot_bin/${TARGET_DIR}/sec_boot.bin + COMMENT "copy bin file" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN + ) + endif() +endif() + +if(${GEN_SEC_BIN} AND ${GEN_SEC_BIN} STREQUAL "True") + if(${CORE} STREQUAL "acore") + if (TARGET GENERAT_SIGNBIN) + add_custom_target(GENERAT_SEC_IMAGE ALL + COMMAND ${CMAKE_OBJCOPY} --enable_sec ${PROJECT_BINARY_DIR}/${BIN_NAME}_sign.bin + WORKING_DIRECTORY ${COMPILER_ROOT}/bin + DEPENDS GENERAT_SIGNBIN + ) + else() + add_custom_target(GENERAT_SEC_IMAGE ALL + COMMAND ${CMAKE_OBJCOPY} --enable_sec ${PROJECT_BINARY_DIR}/${BIN_NAME}.bin + WORKING_DIRECTORY ${COMPILER_ROOT}/bin + DEPENDS GENERAT_BIN + ) + endif() + elseif(${CORE} STREQUAL "bt_core") + add_custom_target(GENERAT_SEC_IMAGE ALL + COMMAND ${SEC_OBJCPY_TOOL} --enable_sec ${PROJECT_BINARY_DIR}/${BIN_NAME}.bin + WORKING_DIRECTORY ${SEC_TOOL_DIR} + DEPENDS GENERAT_ROM_PATCH + ) + endif() +endif() + diff --git a/build/cmake/build_ssb.cmake b/build/cmake/build_ssb.cmake new file mode 100755 index 0000000..2124133 --- /dev/null +++ b/build/cmake/build_ssb.cmake @@ -0,0 +1,15 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== + +if(DEFINED APPLICATION) +if(${APPLICATION} STREQUAL "ssb") +add_custom_target(ADD_SHA_TO_SSB ALL + COMMAND ${Python3_EXECUTABLE} ${BUILD_UTILS} add_len_and_sha256_info_to_ssb ${TARGET_NAME}.bin ${CHIP} + COMMENT "add ssb length and sha256 info into ssb.bin" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS GENERAT_BIN +) +endif() +endif() diff --git a/build/cmake/global_variable.cmake b/build/cmake/global_variable.cmake new file mode 100755 index 0000000..559b79b --- /dev/null +++ b/build/cmake/global_variable.cmake @@ -0,0 +1,19 @@ +#=============================================================================== +# @brief cmake global variable init +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +#=============================================================================== + +set(ALL_PUBLIC_HEADER "" CACHE INTERNAL "" FORCE) +set(ALL_HEADER "" CACHE INTERNAL "" FORCE) +set(ALL_PUBLIC_DEFINES ${DEFINES} CACHE INTERNAL "" FORCE) +set(ALL_PUBLIC_CCFLAGS "${CCFLAGS}" CACHE INTERNAL "" FORCE) +set(ALL_SOURCES "" CACHE INTERNAL "" FORCE) +set(LOS_LIB "" CACHE INTERNAL "" FORCE) +set(LINKER_DIR "" CACHE INTERNAL "" FORCE) +set(SDK_PROJECT_FILE_DIR "" CACHE INTERNAL "" FORCE) +set(LOG_DEF_LIST "" CACHE INTERNAL "" FORCE) +set(WSTP_HEADER_LIST "" CACHE INTERNAL "" FORCE) +set(PLAT_SRC_LIST "" CACHE INTERNAL "" FORCE) +set(WSTP_SRC_LIST "" CACHE INTERNAL "" FORCE) +set(TEST_HAED_LIST "" CACHE INTERNAL "" FORCE) +set(BTH_SDK_LIST "" CACHE INTERNAL "" FORCE) \ No newline at end of file diff --git a/build/cmake/open_source.cmake b/build/cmake/open_source.cmake new file mode 100755 index 0000000..7ff5695 --- /dev/null +++ b/build/cmake/open_source.cmake @@ -0,0 +1,8 @@ +include(${CMAKE_DIR}/open_source/gmssl.cmake) +include(${CMAKE_DIR}/open_source/mbedtls.cmake) +include(${CMAKE_DIR}/open_source/hitls.cmake) +include(${CMAKE_DIR}/open_source/littlefs.cmake) +include(${CMAKE_DIR}/open_source/libcoap.cmake) +if (EXISTS ${ROOT_DIR}/protocol/wifi/CMakeLists.txt) +include(${CMAKE_DIR}/open_source/wpa_supplicant.cmake) +endif() \ No newline at end of file diff --git a/build/config/target_config/common_config.py b/build/config/target_config/common_config.py new file mode 100755 index 0000000..c0cf7b5 --- /dev/null +++ b/build/config/target_config/common_config.py @@ -0,0 +1,511 @@ +#!/usr/bin/env python3 +# encoding=utf-8 +# ============================================================================ +# @brief common config of build system +# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2022. All rights reserved. +# ============================================================================ + + +component_set = { + 'boot_rom': ['hw_sec', 'non_os_libc', 'non_os_isr', 'non_os_osal'], + 'libra_public': ['libra_device'], + 'std_common_lib': [ + "app_version", "build_version", "testsuite", "common_headers", "connectivity", + "cpu_load", "cpu_utils", "irmalloc", "lib_utils", "dfx_log", "dfx_log_reader", + "dfx_panic", "dfx_preserve", + ], + "ssb_libs": ["codeloader_ssb", "lib_utils", "jlink_load", "algorithm"], + 'boot_common_lib': [ + "bootloader", "codeloader", "build_version", "common_headers", 'app_version', + "cpu_utils", "irmalloc", "dfx_panic", "dfx_preserve", 'error_code', + ], + 'sec': ['hal_sec_common', 'hal_sec_sha', 'hal_sec_trng2', 'hal_sectors', + 'sec_common', 'sec_rsa', 'sec_sha', 'sec_trng', "sec_port", "sec_rsa_port",], + 'security': ['hal_hash', 'hash', 'hash_port', 'hal_trng', 'trng', 'trng_port', 'hal_pke', + 'pke', 'pke_port', 'hal_cipher', 'cipher', 'cipher_port', 'hal_km', 'km', 'km_port'], + 'mem': ['memory_core'], + 'mem_monitor': ['mem_monitor', 'hal_mem_monitor', 'mem_monitor_port'], + 'cpu': ['hal_cpu_core', 'reboot', 'hal_reg_config', 'hal_reboot', 'reboot_port'], + 'can': ['can', 'hal_can', 'can_port'], + 'watchdog': ['watchdog', 'hal_watchdog', 'watchdog_port'], + 'reboot_set':['reboot', 'hal_reboot', 'reboot_port'], + 'uart': ['hal_uart', 'uart', 'uart_port'], + 'xip_os': ['hal_xip', 'xip_port'], + 'xip_nonos': ['hal_xip', 'xip_port'], + 'adc': ['hal_adc', 'adc', 'adc_port'], + 'ipc': ['hal_ipc_old', 'ipc_old'], + 'spi_os': ['hal_spi', 'spi_cmsis'], + 'spi_nonos': ['hal_spi', 'spi_nonos'], + 'sfc_flash_old': ['sfc_old', 'hal_sfc_old'], + 'sfc_flash': ['sfc', 'hal_sfc'], + 'dma': ['hal_dma_v100', 'dma', 'dma_port'], + 'dmav151': ['hal_dma_v151', 'dma', 'dma_port'], + 'dmav120': ['hal_dma_v120', 'dma', 'dma_port'], + 'button': ['button', 'button_port'], + 'epmu': ['epmu', 'epmu_port'], + 'spi': ['spi', 'hal_spi', 'spi_porting'], + 'lpc': ['hal_lpc', 'lpc'], + 'otp': ['hal_otp', 'otp'], + 'i2c': ['hal_i2c', 'i2c', 'i2c_porting'], + 'pwm': ['hal_pwm', 'pwm', "pwm_port",], + 'mmc': ['hal_mmc', 'mmc'], + 'gpio_v150': ['hal_gpio_v150', 'gpio', "gpio_port"], + 'gpio_v100': ['hal_gpio_v100', 'gpio', "gpio_port"], + 'qspi': ['hal_qspi', 'qspi'], + 'hso_log': ["dfx_log", "dfx_log_reader"], + 'qdec' : ['hal_qdec', 'qdec', "qdec_port"], + 'keyscan' : ['hal_keyscan', 'keyscan', "keyscan_port"], + 'usb' : ["usb", "hal_usb", "usb_port"], + 'usb_unified' : ['usb_unified', 'usb_unified_open', 'usb_unified_port'], + 'pdm' : ['pdm', 'hal_pdm', "pdm_porting", "test_pdm"], + 'embed_flash' : ['eflash', 'hal_eflash', 'eflash_port'], + 'i2s' : ["i2s"], + 'flash' : ["flash", "flash_porting"], + 'sio_v150' : ['hal_sio', 'sio_port'], + 'sio_v151' : ['hal_sio', 'sio_port'], + 'cpu_trace': ['hal_cpu_trace', 'cpu_trace'], + 'sdio_slave': ['sdio', 'hal_sdio', 'sdio_port'], + 'time_set': ['systick', 'tcxo', 'drv_timer', 'hal_systick', 'hal_tcxo', 'hal_timer', 'rtc_unified', 'hal_rtc_unified', 'rtc_unified_port', 'timer_port', 'systick_port', 'tcxo_port'], + 'systick_set':['systick', 'hal_systick', 'systick_port'], + 'tcxo_set':['tcxo', 'hal_tcxo', 'tcxo_port'], + 'rtc_unified': ['rtc_unified', 'hal_rtc_unified', 'rtc_unified_port'], + 'local_stdlib': ['c', 'm', 'posix'], + 'audio': ['audio_api', 'audio_core', 'audio_drv', 'audio_sample', 'audio_vendor'], + 'bgh': ['bt_host_brandy_service', 'bt_host_brandy_sample', 'bt_host_sdk'], + 'bgh-master': ['bt_app', 'bth_sample', 'bth_sdk', 'bg_common', 'bth_audio_manager_wrapper'], + 'bgh_audio': ['bt_host_audio_manager_wrapper'], + 'media': ['audio_capture', 'audio_manager', 'audio_service', 'audio_stream', 'audio_utils', + 'media_sample_wrapper', 'player', 'media_common', 'audio_bluetooth_port', 'audio_hw', + 'audio_primary_port','format_hw', 'hmf_demuxer', 'media_hal_common', 'plugin_demuxer_hmf', + 'plugin_demuxer_mjpeg', 'plugin_protocol_https', 'audio_port_common', 'codec_hw', 'codec_plugin_vdec', + 'camera_codec_hw', 'hdi_camera_intf', 'plugin_demuxer_raw', 'audio_modem_port'], + 'media_melody': ['audio_manager', 'audio_service', 'audio_stream', 'audio_utils', + 'media_common', 'audio_bluetooth_port', 'audio_hw', + 'audio_primary_port', 'media_hal_common', 'audio_port_common', 'haid_manager', 'tone_player', 'tws_manager'], + 'media_mini': ['audio_capture', 'audio_manager', 'audio_service', 'audio_stream', 'audio_utils', + 'media_sample_wrapper', 'player', 'media_common', 'audio_bluetooth_port', 'audio_hw', + 'audio_primary_port','format_hw', 'hmf_demuxer', 'media_hal_common', 'plugin_demuxer_hmf', + 'plugin_demuxer_mjpeg', 'plugin_protocol_https', 'audio_port_common', 'plugin_demuxer_raw'], + 'media_target4': ['audio_manager', 'audio_service', 'audio_stream', 'audio_utils', 'media_common', 'audio_hw', + 'audio_primary_port', 'audio_bluetooth_port', 'audio_modem_port', 'media_hal_common', + 'audio_port_common', 'media_sample_wrapper'], + 'gpu': ['gfx_rm', 'gpu'], + 'gpu_test': ['test_gpu'], + 'graphic_uikit': ['cjson_static', 'display_gfx', 'display_gralloc', 'display_layer', 'graphic_input', 'graphic_service', + 'freetype_static', 'graphic_ui', 'graphic_utils', 'qrcodegen', 'icu4c', 'harfbuzz', 'uikit_ext'], + 'graphic_lvgl': ['display_gfx', 'display_gralloc', 'display_layer', 'graphic_input', 'freetype_static', + 'lvgl', 'lvgl_sample', 'lvgl_demos', 'lvgl_proprietary', 'lvgl_service'], + 'graphic_lvgl_mini': ['display_gfx', 'display_gralloc', 'display_layer', 'graphic_input', 'freetype_static', + 'lvgl', 'lvgl_sample', 'lvgl_demos', 'lvgl_proprietary_mini', 'lvgl_service'], + 'graphic_test': ['uikit_test'], + 'calendar': ['calendar', 'hal_calendar', 'calendar_port'], + 'update_app': ['update_common', 'update_storage', 'update_local', 'update_storage_brandy', 'update_common_brandy', 'lzma_21.07'], + 'update_recovery': ['update_common', 'update_local', 'update_common_brandy', 'lzma_21.07'], + 'pinctrl': ['pinctrl', 'hal_pinctrl', 'port_pinctrl'], + 'pmp_set': ['pmp', 'hal_pmp', 'pmp_port'], + 'mips': ['mips', 'hal_mips'], + 'dfx_set': ['dfx_diag', "diag_dfx_cmd", 'dfx_panic', 'dfx_preserve', 'dfx_log', 'dfx_log_reader', 'dfx_exception', 'log_file', 'soc_log'], + 'app_ux': ['ux_audio', 'ux_bt', 'ux_commu', 'ux_sensor', 'ux_spp', 'ux_cmn_header', 'ux_common'], + 'pm_set': ['pm', 'pm_porting', 'pm_sleep', 'pm_sleep_porting', 'pm_veto', 'pm_veto_porting', 'pm_dev', 'pm_dev_porting', 'pm_fsm', 'pm_fsm_porting'], + 'pm_pmu_set': ['pm_pmu', 'pm_pmu_porting'], + 'pm_clock_set': ['pm_clock', 'pm_clock_porting'], + 'ux_manager': ['fsm_box', 'fsm_master', 'fsm_pairing', 'ux_event', 'ux_earphone', 'ux_timer', 'ux_tone_config', 'ux_tone_service', 'ux_led_porting', 'ux_led_config', + 'ux_led_frame', 'ux_master', 'at_ux_manager', 'at_ux_register', 'ux_voiceassistant', 'ux_feature'], + 'ux_module': ['ux_box', 'ux_button', 'ux_pairing', 'ux_touchpad', 'ux_charge'], + 'security_unified': ['hal_security_unified', 'drv_security_unified', 'security_unified_port'], + 'efuse_v151': ['efuse_port', 'hal_efuse_v151', 'efuse'], + 'efuse_v120': ['efuse', 'hal_efuse_v120', 'efuse_porting'], + 'efuse_v100': ['efuse', 'hal_efuse_v100', 'efuse_porting'], + 'efuse_v130': ['efuse', 'hal_efuse_v130', 'efuse_port'], + 'codec_set': ['l2hc_dec_16k', 'l2hc_dec_48k_10ms', 'l2hc_dec_48k_5ms', + 'opus_dec_half_itcm', 'opus_dec_half_flash', 'opus_dec_all_itcm', 'opus_dec_all_flash', + 'opus_enc_half_itcm', 'opus_enc_half_flash', 'opus_enc_all_itcm', 'opus_enc_all_flash', + 'opus_enc_2.5ms_itcm', 'opus_enc_2.5ms_flash', 'l2hc_enc_16k', 'l2hc_enc_48k_10ms','l2hc_enc_48k_5ms', + 'sbc_dec_half_itcm', 'sbc_dec_half_flash', 'sbc_dec_all_itcm', 'sbc_dec_all_flash', + 'sbc_enc_half_itcm', 'sbc_enc_half_flash', 'sbc_enc_all_itcm', 'sbc_enc_all_flash'], + 'ohos_set' : ['bootstrap', 'samgr', 'ams', 'bms', 'bms_sign_mode', 'ace', 'ace_adapt', 'permission', 'appverify', 'jerryscript','js_player', 'js_audio_captuer','i18n', 'resmgr', 'syspara'], + 'wearable_set' : ['nativeabilityfwk', 'nativelauncher', 'ai_voice_service', 'ai_voice_engine_hal', 'ai_voice_audio_stream_wrapper', 'ohos_deps', + 'broadcast', 'msg_center', 'msg_center_adapt', 'ohos_startup'], +} + +defines_set = { + 'libsec_defines': [ + "SECUREC_HAVE_WCTOMB=0", "SECUREC_HAVE_MBTOWC=0", + "SECUREC_ENABLE_SCANF_FLOAT=0", "SECUREC_ENABLE_SPRINTF_FLOAT=0"], + 'chip_defines': [ + "BS25_CHIP_FPGA=0", "BS25_CHIP_V100=0", "BRANDY_CHIP_FPGA=0", "BRANDY_CHIP_V100=0", "SOCMN1_CHIP_FPGA=0", + "SOCMN1_CHIP_V100=0", "SOCMN1_CHIP_V200=0", "LIBRA_CHIP_CS=0", "LIBRA_CHIP_FPGA=0", "SW39_CHIP_FPGA=0", + "TARGET_CHIP_BS25=0", "TARGET_CHIP_BRANDY=0", "TARGET_CHIP_SOCMN1=0", "TARGET_CHIP_SW39=0", + "TARGET_CHIP_LIBRA=0", "CHIP=1", "CHIP_VERSION=1", "CHIP_WS63=0", "SW21_CHIP_FPGA=0", + "TARGET_CHIP_SW21=0", "CHIP_WS53=0", "CONFIG_UART_SUPPORT_TX", "CONFIG_UART_SUPPORT_RX", + "CHIP_BS20=0", "CHIP_BS21=0", "CHIP_BS21A=0", "CHIP_BS21E=0", "CHIP_BS22=0", "CHIP_BS26=0", + ], + 'version_defines': [], + 'libepmu_defines':['EPMU_BUCK_LDO_EN', 'EPMU_RTC_EN', 'EPMU_PWR_KEY_EN', 'EPMU_GPIO_EN', 'EPMU_WDT_EN', 'EPMU_EXTEND_EN'], +} + +common_ccflags = [ + '-std=gnu99', + '-Wall', + '-Werror', + '-Wextra', + '-Winit-self', + '-Wpointer-arith', + '-Wstrict-prototypes', + '-Wno-type-limits', + '-fno-strict-aliasing', + '-Os', + '-fno-unwind-tables', +] + +common_linkflags = [ + '-Wl,--gc-section', + '-nostdlib', + '-static', +] + +arch_config = { + 'riscv70': { + 'ccflags': [ + '--target=riscv32', + '-march=rv32imfcxlinxma_xlinxmb_xlinxmc', + '-mabi=ilp32f', + '-ffunction-sections', + '-fdata-sections', + '-fno-common', + '-fsigned-char', + '-fstack-protector-strong', + '-mllvm', + '-allow-unalign-ldst=false', + "-Wno-error=out-of-line-declaration", + "-Wno-error=uninitialized", + "-Wno-error=int-conversion", + "-Wno-error=enum-conversion", + "-Wno-error=long-long", + "-Wno-unused-variable", + "-Wno-error=unused-variable", + "-Wno-error=unused-value", + "-Wno-error=unused-function", + "-Wno-error=sign-compare", + "-Wno-error=unused-parameter", + "-Wno-error=tautological-compare", + "-Wno-error=bad-function-cast", + "-Wno-error=incompatible-pointer-types", + "-Wno-error=implicit-function-declaration", + "-Wno-missing-braces", + "-Wno-main-return-type", + "-Wno-unused-command-line-argument", + "-Wno-undef", + '-g', + ], + 'linkflags': [ + '-Wl,--gc-section,--cref,-M', + '-static', + '-nostdlib', + '--target=riscv32', + ], + 'rom_ccflags': [ + '--target=riscv32', + '-march=rv32imfcxlinxma_xlinxmb_xlinxmc', + '-mabi=ilp32f', + '-ffunction-sections', + '-fdata-sections', + '-fno-common', + '-fsigned-char', + '-Wno-error=main' + "-Wno-error=out-of-line-declaration", + "-Wno-error=uninitialized", + "-Wno-error=int-conversion", + "-Wno-error=enum-conversion", + "-Wno-error=long-long", + "-Wno-unused-variable", + "-Wno-error=unused-variable", + "-Wno-error=unused-value", + "-Wno-error=unused-function", + "-Wno-error=sign-compare", + "-Wno-error=unused-parameter", + "-Wno-error=tautological-compare", + "-Wno-error=bad-function-cast", + "-Wno-error=incompatible-pointer-types", + "-Wno-error=implicit-function-declaration", + "-Wno-missing-braces", + "-Wno-main-return-type", + "-Wno-unused-command-line-argument", + "-Wno-undef", + "-g" + ], + 'std_libs': [ + ] + }, + + 'riscv32': { + 'ccflags': [ + '--target=riscv32', + '-march=rv32imc_xlinxma_xlinxmb_xlinxmc_xlinxmd', + '-mabi=ilp32', + '-ffunction-sections', + '-fdata-sections', + '-fno-common', + '-fsigned-char', + '-fstack-protector-strong', + '-mllvm', + '-allow-unalign-ldst=false', + "-Wno-error=out-of-line-declaration", + "-Wno-error=uninitialized", + "-Wno-error=int-conversion", + "-Wno-error=enum-conversion", + "-Wno-error=long-long", + "-Wno-unused-variable", + "-Wno-error=unused-variable", + "-Wno-error=unused-value", + "-Wno-error=unused-function", + "-Wno-error=sign-compare", + "-Wno-error=unused-parameter", + "-Wno-error=tautological-compare", + "-Wno-error=bad-function-cast", + "-Wno-error=incompatible-pointer-types", + "-Wno-error=implicit-function-declaration", + "-Wno-missing-braces", + "-Wno-main-return-type", + "-Wno-unused-command-line-argument", + "-Wno-undef", + '-g', + ], + 'linkflags': [ + '-Wl,--gc-section,--cref,-M', + '-static', + '-nostdlib', + '--target=riscv32', + ], + 'rom_ccflags': [ + '--target=riscv32', + '-march=rv32imc_xlinxma_xlinxmb_xlinxmc_xlinxmd', + '-mabi=ilp32', + '-ffunction-sections', + '-fdata-sections', + '-fno-common', + '-fsigned-char', + '-Wno-error=main' + "-Wno-error=out-of-line-declaration", + "-Wno-error=uninitialized", + "-Wno-error=int-conversion", + "-Wno-error=enum-conversion", + "-Wno-error=long-long", + "-Wno-unused-variable", + "-Wno-error=unused-variable", + "-Wno-error=unused-value", + "-Wno-error=unused-function", + "-Wno-error=sign-compare", + "-Wno-error=unused-parameter", + "-Wno-error=tautological-compare", + "-Wno-error=bad-function-cast", + "-Wno-error=incompatible-pointer-types", + "-Wno-error=implicit-function-declaration", + "-Wno-missing-braces", + "-Wno-main-return-type", + "-Wno-unused-command-line-argument", + "-Wno-undef", + "-g" + ], + 'std_libs': [ + ] + }, + 'cortex_m7':{ + 'ccflags': [ + '-fomit-frame-pointer', + '-ffreestanding', + '-fdata-sections', + '-ffunction-sections', + '-specs=nano.specs', + '-nostdlib', + '-pipe', + '-mno-unaligned-access', + "-fdebug-types-section", + '-Wtrampolines', + '-Wlogical-op', + '-funsigned-char', + '-Wformat=2', + '-Wdate-time', + #'-Wshadow', + '-Wno-return-local-addr', + #'-Wconversion', + #'-Wcast-align', + '-Wfloat-equal', + #'-Wswitch-default', + '-Wvla', + '-Wjump-misses-init', + '-march=armv7-m', + '-mfpu=fpv5-d16', + '-mthumb', + '--specs=nosys.specs', + '-Wno-incompatible-pointer-types', + '-Wno-sign-compare', + "-Wno-error=enum-conversion", + + "-Wno-error=uninitialized", + "-Wno-error=int-conversion", + "-Wno-error=long-long", + "-Wno-unused-variable", + "-Wno-error=unused-variable", + "-Wno-error=unused-value", + "-Wno-error=unused-function", + "-Wno-error=sign-compare", + "-Wno-error=unused-parameter", + "-Wno-error=tautological-compare", + "-Wno-error=bad-function-cast", + "-Wno-error=cast-function-type", + "-Wno-error=discarded-qualifiers", + "-Wno-error=missing-field-initializers", + "-Wno-error=incompatible-pointer-types", + "-Wno-error=implicit-function-declaration", + "-Wno-missing-braces", + '-Wno-implicit-function-declaration' + ], + 'linkflags': [ + '-Wl,--gc-section,--cref,--relax,-M', + '-mthumb', + '-flto=16', + '-march=armv7-m', + '-nostdlib' + ], + 'rom_ccflags': [ + '-fomit-frame-pointer', + '-ffreestanding', + '-fdata-sections', + '-ffunction-sections', + '-specs=nano.specs', + '-nostdlib', + '-pipe', + '-mno-unaligned-access', + '-mthumb', + "-fdebug-types-section", + '-Wtrampolines', + '-Wlogical-op', + '-Wjump-misses-init', + '-march=armv7-m', + '-fno-inline-functions-called-once', + '-fno-inline-small-functions', + '--specs=nosys.specs', + ], + 'std_libs': [ + ] + }, + 'riscv31': { + 'ccflags': [ + '-ffreestanding', + '-fdata-sections', + '-Wno-implicit-fallthrough', + '-ffunction-sections', + '-nostdlib', + '-pipe', + '-mabi=ilp32', + '-march=rv32imc', + '-fno-tree-scev-cprop', + '-fno-common', + '-mpush-pop', + '-msmall-data-limit=0', + '-fno-ipa-ra', + '-Wtrampolines', + '-Wlogical-op', + '-Wjump-misses-init', + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-fimm-compare", + "-femit-muliadd", + "-fmerge-immshf", + "-femit-uxtb-uxth", + "-femit-lli", + "-femit-clz", + "-fldm-stm-optimize", + '-g', + ], + 'linkflags': [ + "-Wl,--enjal16", + "-nostdlib", + "-g", + ], + 'rom_ccflags': [ + '-ffreestanding', + '-fdata-sections', + '-Wno-implicit-fallthrough', + '-ffunction-sections', + '-nostdlib', + '-pipe', + '-mabi=ilp32', + '-march=rv32imc', + '-fno-tree-scev-cprop', + '-fno-common', + '-mpush-pop', + '-msmall-data-limit=0', + '-fno-ipa-ra', + '-Wtrampolines', + '-Wlogical-op', + '-Wjump-misses-init', + "-Wa,-enable-c-lbu-sb", + "-Wa,-enable-c-lhu-sh", + "-fimm-compare", + "-femit-muliadd", + "-fmerge-immshf", + "-femit-uxtb-uxth", + "-femit-lli", + "-femit-clz", + "-fldm-stm-optimize", + "-g", + ], + 'std_libs': [ + 'gcc', 'm', 'c' + ] + }, +} + +arch_family = { + "arm": [ + "cortex_m7", "cortex_m3" + ], + "riscv": [ + "riscv70", "riscv31", "riscv32" + ], +} + + +class CommonConfig: + def __init__(self, arch): + self.arch_config = arch_config[arch] + self.arch_family = '' + for arch_family_name in arch_family: + if arch in arch_family[arch_family_name]: + self.arch_family = arch_family_name + if not self.arch_family: + raise Exception(f"{arch} is not found in arch_family, please add it") + + def get_ram_ccflags(self): + temp = [] + temp.extend(common_ccflags) + temp.extend(self.arch_config['ccflags']) + return temp + + def get_rom_ccflags(self): + return common_ccflags + self.arch_config['rom_ccflags'] + + def get_definse(self, set_name): + try: + return defines_set[set_name] + except KeyError: + print(f"{set_name} is not in defines_set!!") + raise + + def get_linkflags(self): + return common_linkflags + self.arch_config['linkflags'] + + def get_std_libs(self): + return self.arch_config['std_libs'] + + def get_arch_family(self): + return self.arch_family + + def get_component_set(self, set_name): + try: + return component_set[set_name] + except KeyError: + print(f"{set_name} is not in component_set!!") + raise diff --git a/build/config/target_config/ws63/__pycache__/config.cpython-39.pyc b/build/config/target_config/ws63/__pycache__/config.cpython-39.pyc new file mode 100644 index 0000000..224c416 Binary files /dev/null and b/build/config/target_config/ws63/__pycache__/config.cpython-39.pyc differ diff --git a/build/config/target_config/ws63/__pycache__/target_config.cpython-39.pyc b/build/config/target_config/ws63/__pycache__/target_config.cpython-39.pyc new file mode 100644 index 0000000..387009b Binary files /dev/null and b/build/config/target_config/ws63/__pycache__/target_config.cpython-39.pyc differ diff --git a/build/config/target_config/ws63/build_nvbin.py b/build/config/target_config/ws63/build_nvbin.py new file mode 100755 index 0000000..f8bf444 --- /dev/null +++ b/build/config/target_config/ws63/build_nvbin.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# encoding=utf-8 +# ============================================================================ +# @brief Build nvbin +# Copyright HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +# ============================================================================ + +import os +import sys +file_dir = os.path.dirname(os.path.realpath(__file__)) +g_root = os.path.realpath(os.path.join(file_dir, "..", "..", "..", "..")) +sys.path.append(os.path.join(g_root, 'build', 'script', 'nv')) +from nv_binary import nv_begin + + +if __name__ == '__main__': + #配置文件路径 + nv_config_json = os.path.join(g_root, "build", "config", "target_config", "ws63", "nv_bin_cfg", "mk_nv_bin_cfg.json") + #输出路径 + nv_output_path = os.path.join(g_root, "output", "ws63", "acore", "nv_bin") + + if not os.path.exists(nv_output_path): + os.makedirs(nv_output_path) + + targets = ["acore"] + if len(sys.argv) >= 2: + target_name = sys.argv[1] + if target_name == 'ws63-liteos-perf': + nv_config_json = os.path.join(g_root, "build", "config", "target_config", "ws63", "nv_bin_cfg", + "mk_nv_bin_cfg_perf.json") + nv_begin(nv_config_json, targets, 1, True) diff --git a/build/config/target_config/ws63/build_ws63_update.py b/build/config/target_config/ws63/build_ws63_update.py new file mode 100755 index 0000000..ffff6c8 --- /dev/null +++ b/build/config/target_config/ws63/build_ws63_update.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 +# encoding=utf-8 +# ============================================================================ +# @brief Build Update Pkg File +# Copyright HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved. +# ============================================================================ + +import os +import sys +import argparse +import shutil +import subprocess + +file_dir = os.path.dirname(os.path.realpath(__file__)) +g_root = os.path.realpath(os.path.join(file_dir, "..", "..", "..", "..")) +sys.path.append(os.path.join(g_root, 'build', 'script')) +from build_upg_pkg import begin + +sys.path.append(os.path.join(g_root, "build", "config")) +sys.path.remove(os.path.join(g_root, 'build', 'config', "target_config", "ws63")) +from enviroment import TargetEnvironment + +from utils.indie_upgrade_utils import check_indie_upg_match + +class upg_base_info: + def __init__(self): + self.root_path = g_root + # 升级包结构配置文件 + self.fota_format_path = os.path.join(self.root_path, "build", "config", "target_config", "ws63", "fota") + # 产品升级配置文件 + self.fota_cfg = os.path.join(self.root_path, "build", "config", "target_config", "ws63", "fota", "fota.cfg") + # 产品镜像输出路径 + self.output = os.path.join(self.root_path, "output", "ws63") + # 产品升级镜像包输出路径 + self.upg_output = os.path.join(self.output, "upgrade") + # 产品签名加密前原始镜像 + self.upg_pkt = os.path.join(self.upg_output, "ota_pktbin") + self.upg_pkt_zip = os.path.join(self.upg_output, "ota_pktbin.zip") + # 产品升级制作临时文件输出路径 + self.temp_dir = os.path.join(self.upg_output, "temp_dir") + + # 产品镜像路径 + self.flashboot = os.path.join(self.root_path, "output", "ws63", "acore","boot_bin", "flashboot_sign.bin") + self.app_bin = os.path.join(self.output, "acore", "ws63-liteos-app", "ws63-liteos-app-sign.bin") + self.app_iot_bin = os.path.join(self.output, "acore", "ws63-liteos-app-iot", "ws63-liteos-app-iot-sign.bin") + self.app_iot_check = os.path.join(self.output, "acore", "ws63-liteos-app-iot", "ws63-liteos-app-iot-check.json") + self.hilink_bin = os.path.join(self.output, "acore", "ws63-liteos-hilink", "ws63-liteos-hilink-sign.bin") + self.hilink_check = os.path.join(self.output, "acore", "ws63-liteos-hilink", "ws63-liteos-hilink-check.json") + self.test_bin = os.path.join(self.output, "acore", "ws63-liteos-testsuite", "ws63-liteos-testsuite-sign.bin") + self.nv_bin = os.path.join(self.output, "acore", "nv_bin", "ws63_all_nv.bin") + + # 签名加密前原始镜像 + self.src_boot = os.path.join(self.root_path, "output", "ws63", "acore", "boot_bin", "flashboot.bin") + self.src_app = os.path.join(self.output, "acore", "ws63-liteos-app", "ws63-liteos-app.bin") + self.src_test = os.path.join(self.output, "acore", "ws63-liteos-testsuite", "ws63-liteos-testsuite.bin") + + # 差分升级时,以下路径配置为上一个版本的镜像路径 + self.flashboot_old_bin = os.path.join(self.output, "acore", "old_version", "flashboot_sign.bin") + self.app_old_bin = os.path.join(self.output, "acore", "old_version", "ws63-liteos-app-sign.bin") + self.app_iot_old_bin = os.path.join(self.output, "acore", "old_version", "ws63-liteos-app-iot-sign.bin") + self.hilink_old_bin = os.path.join(self.output, "acore", "old_version", "ws63-liteos-hilink-sign.bin") + self.test_old_bin = os.path.join(self.output, "acore", "old_version", "ws63-liteos-testsuite-sign.bin") + self.nv_old_bin = os.path.join(self.output, "acore", "old_version", "ws63_all_nv.bin") + +def check_bin_match(input_param, info): + if 'app_iot' not in input_param: + return True + + target_env = TargetEnvironment("ws63-liteos-app-iot") + defines = target_env.get('defines') + if "CONFIG_SUPPORT_HILINK_INDIE_UPGRADE" not in defines: + return True + + if not check_indie_upg_match(info.hilink_check, info.app_iot_check): + print("indie upg hilink and app not match") + return False + + print("check indie upg hilink and app match succ") + return True + +def get_new_image(input_param, info): + image_list = [] + if 'app' in input_param: + image_list.append("=".join([info.app_bin, "application"])) + if 'app_iot' in input_param: + image_list.append("=".join([info.app_iot_bin, "application"])) + target_env = TargetEnvironment("ws63-liteos-app-iot") + defines = target_env.get('defines') + if "CONFIG_SUPPORT_HILINK_INDIE_UPGRADE" in defines: + image_list.append("=".join([info.hilink_bin, "hilink"])) + if 'hilink' in input_param: + image_list.append("=".join([info.hilink_bin, "hilink"])) + if 'test' in input_param: + image_list.append("=".join([info.test_bin, "application"])) + if 'boot' in input_param: + image_list.append("=".join([info.flashboot, "flashboot"])) + if 'nv' in input_param: + image_list.append("=".join([info.nv_bin, "nv"])) + + new_image = "|".join(image_list) + return new_image + + +def get_old_image(input_param, info): + image_list = [] + if 'app' in input_param: + image_list.append("=".join([info.app_old_bin, "application"])) + if 'app_iot' in input_param: + image_list.append("=".join([info.app_iot_old_bin, "application"])) + target_env = TargetEnvironment("ws63-liteos-app-iot") + defines = target_env.get('defines') + if "CONFIG_SUPPORT_HILINK_INDIE_UPGRADE" in defines: + image_list.append("=".join([info.hilink_old_bin, "hilink"])) + if 'hilink' in input_param: + image_list.append("=".join([info.hilink_old_bin, "hilink"])) + if 'test' in input_param: + image_list.append("=".join([info.test_old_bin, "application"])) + if 'boot' in input_param: + image_list.append("=".join([info.flashboot_old_bin, "flashboot"])) + if 'nv' in input_param: + image_list.append("=".join([info.nv_old_bin, "nv"])) + + old_image = "|".join(image_list) + return old_image + +def get_parameters(): + parser = argparse.ArgumentParser() + + parser.add_argument('--pkt', type=str, default = 'app', + help='需要生成的镜像,包括: app,boot,nv') + + config, unknown = parser.parse_known_args() + return config + +# 打包签名加密前的原镜像 +def make_pkt(info, input_param): + if os.path.exists(info.upg_pkt): + shutil.rmtree(info.upg_pkt) + os.makedirs(info.upg_pkt, exist_ok=True) + shutil.copy(info.fota_cfg, info.upg_pkt) + if 'app' in input_param: + shutil.copy(info.src_app, info.upg_pkt) + if 'test' in input_param: + shutil.copy(info.src_test, info.upg_pkt) + if 'boot' in input_param: + shutil.copy(info.src_boot, info.upg_pkt) + if 'nv' in input_param: + shutil.copy(info.nv_bin, info.upg_pkt) + if os.path.exists(info.upg_pkt_zip): + os.remove(info.upg_pkt_zip) + cmd = ' '.join(['tar -cf %s -C %s .' % (info.upg_pkt_zip, info.upg_pkt)]) + ret = subprocess.run(cmd, shell=True) + if ret.returncode: + print("make_pkt shell cmd", cmd, ", err: ", ret.returncode) + +if __name__ == '__main__': + info = upg_base_info() + conf = get_parameters() + input_param = conf.pkt.split(",") + if "boot" not in input_param: + input_param.append("boot") + + if not check_bin_match(input_param, info): + sys.exit(1) + + conf.app_name = "update" + conf.upg_format_path = info.fota_format_path + conf.base = info.fota_cfg + conf.temp_dir = info.temp_dir + conf.new_images = get_new_image(input_param, info) + conf.old_images = get_old_image(input_param, info) + conf.output_dir = info.upg_output + conf.type = 0 + begin(conf) + make_pkt(info, input_param) diff --git a/build/config/target_config/ws63/codesize_statistic_config.json b/build/config/target_config/ws63/codesize_statistic_config.json new file mode 100755 index 0000000..3bec429 --- /dev/null +++ b/build/config/target_config/ws63/codesize_statistic_config.json @@ -0,0 +1,43 @@ +'component_group': [ + 'efuse_driver', + 'efuse_hal', + 'efuse_port', + 'sfc_driver', + 'sfc_hal', + 'sfc_port', + 'watchdog_driver', + 'watchdog_hal', + 'watchdog_port', + 'timer_driver', + 'timer_hal', + 'timer_port', + 'pinmux_driver', + 'pinmux_hal', + 'pinmux_port', + 'systick_driver', + 'systick_hal', + 'systick_port', + 'tcxo_driver' +], + +group_details = { + 'efuse_driver' : ['efuse'] + 'efuse_hal' : ['hal_efuse_v151'] + 'efuse_port' : ['efuse_port'] + 'sfc_driver' : ['sfc'] + 'sfc_hal' : ['hal_sfc'] + 'sfc_port' : ['sfc_port_ws63'] + 'watchdog_driver': ['watchdog'] + 'watchdog_hal' : ['hal_watchdog'] + 'watchdog_port' : ['watchdog_port'] + 'timer_driver' : ['drv_timer'] + 'timer_hal' : ['hal_timer'] + 'timer_port' : ['timer_port'] + 'pinmux_driver' : ['pinctrl'] + 'pinmux_hal' : ['hal_pinctrl'] + 'pinmux_port' : ['pinctrl_port_ws63'] + 'systick_driver' : ['ws63_systick'] + 'systick_hal' : ['hal_systick'] + 'systick_port' : ['systick_port'] + 'tcxo' : ['ws63_tcxo'] +} \ No newline at end of file diff --git a/build/config/target_config/ws63/config.py b/build/config/target_config/ws63/config.py new file mode 100755 index 0000000..18d9172 --- /dev/null +++ b/build/config/target_config/ws63/config.py @@ -0,0 +1,413 @@ +#!/usr/bin/env python3 +# encoding=utf-8 +# ============================================================================ +# @brief Target Definitions File +# Copyright HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved. +# ============================================================================ +target = { + 'ws63-liteos-app': { + 'base_target_name': 'target_ws63_app_rom_template', + 'os': 'liteos', + 'defines': [ + "USE_CMSIS_OS", + "USE_LITEOS", + "_ALL_SOURCE", + "__LITEOS__", + "-:CHIP_WS63=1", + "LIBUTIL_COMPAT", + "LOG_SUPPORT", + "HSO_SUPPORT", + "NO_TCXO_SUPPORT", + "UNSUPPORT_OTHER_MEM", + "SW_UART_DEBUG", + "SW_UART_CHIP_DEFINE", + "AT_COMMAND", + "DUMP_MEM_SUPPORT", + "BUILD_APPLICATION_STANDARD", + 'CMD_ENABLE', + 'WIFI_TASK_EXIST', + 'BGLE_TASK_EXIST', + 'BTH_TASK_EXIST', + "CONFIG_IPERF_SUPPORT", + "CONFIG_SENDTEST_SUPPORT", + "_PRE_WLAN_FEATURE_BTCOEX", + "_PRE_LWIP_ZERO_COPY", + #"WIFI_TCM_OPTIMIZE", + #"LWIP_TCM_OPTIMIZE", + "CHECKSUM_CHECK_TCP=0", + "CHECKSUM_CHECK_UDP=0", + "MBEDTLS_AES_ROM_TABLES", + "UPDATE_WIFI_STATIC_LIB", + "UPDATE_BTC_STATIC_LIB", + "CONFIG_NV_SUPPORT_SINGLE_CORE_SYSTEM", 'CONFIG_OTA_UPDATE_SUPPORT', + "MBEDTLS_HARDEN_OPEN", + 'CONFIG_UART_SUPPORT_LPM', + "_PRE_RADAR_CCA_SW_OPT", + "MBEDTLS_CONFIG_FILE=\"config-ws-iot.h\"", + "CONFIG_NO_VERIFY_TLS_TIME", + "CHBA_SUPPORT", + "_PRE_WLAN_FEATURE_SLE_BRIDGE", + ], + 'ram_component': [ + 'ws63_liteos_app', + 'ws63_liteos_app_lds', + 'liteos_port', + 'irmalloc', + 'non_os', + 'arch_port', + 'board_config', # 被 pinctrl 组件依赖 + 'lpm', # 被 pwm 组件依赖 + 'chip_ws63', 'pmp_cfg_ws63', + 'reboot', 'hal_reboot', 'reboot_port', 'cpu_utils', 'hal_cpu_core', + 'gpio','hal_gpio_v150','gpio_port', + "dfx_port_ws63", "algorithm", "cmn_header", "lwip", "lwip_tcm", "wifi_service", "mbedtls", "wpa_supplicant", + "at", "wifi_driver_hmac", "wifi_driver_dmac", "wifi_driver_tcm", "wifi_at", "wifi_csa", "wifi_frag", "wifi_alg_txbf", "wifi_alg_temp_protect", "wifi_tx_amsdu", + "wifi_auto_adjust_freq", "wifi_alg_anti_interference", "wifi_alg_edca_opt", "wifi_alg_cca_opt", "wifi_radar_sensor", + 'wifi_btcoex', "wifi_uapsd_ap", 'sio_port', 'i2s', 'hal_sio', + 'liteos_208_5_0', + 'nv', 'nv_ws63', 'nv_zdiag_ws63', 'plt_at', 'dfx_printer', + 'update_common', 'update_common_ws63', 'update_ab_ws63', 'factory_ws63', 'update_storage', 'update_storage_ws63', + 'pm_port_ws63', + 'gmssl_hmac_sm3', + 'bt_at', + "bt_host", + 'bg_common', + 'bth_gle', + 'bth_sdk', + 'samples', + 'bts_header', + 'bt_app', + 'mips', + 'hal_mips', + "bgtp", + 'soc_port', + #'radar_sensing', + #'radar_at', + 'radar_ai', + "cjson", + 'xo_trim_port', + "mqtt", + "coap", + "sle_chba_user","sle_netdev" + ], + 'ccflags': [ + "-DBOARD_ASIC", '-DPRE_ASIC', + ], + 'application': 'application', + 'bin_name': 'ws63-liteos-app', + 'smaller': True, + 'hso_enable_bt': True, + 'hso_enable': True, + 'codesize_statistic': True, + 'nv_update':True, + 'generate_efuse_bin': True, + 'copy_files_to_interim': True + }, + 'ws63-flashboot': { + 'base_target_name': 'target_ws63_boot_template', + 'CONFIG_TIMER_USING_V150': 'y', + "CONFIG_PMP_USING_RISCV_31" : 'y', + 'defines': [ + "__NON_OS__", + "WS63_PRODUCT_NONE", + "CONFIG_TIMER_MAX_NUM=3", + "CONFIG_TIMER_CLOCK_VALUE=24000000", + "CONFIG_TIMER_0_WIDTH_64=0", + "SW_UART_DEBUG", + "CONFIG_UART_SUPPORT_RX", + "CONFIG_UART_SUPPORT_TX", + "BUILD_APPLICATION_ROM", + "BUILD_NOOSAL", + "FLASH_REGION_CFG_FLASHBOOT", + "EFUSE_BIT_OPERATION", + ], + 'ram_component': [ + "flashboot_common", "common_boot", "ws63_flashboot_lds", "dfx_preserve", + "libboundscheck", "chip_ws63", "ws63_mem_config", "common_headers","non_os", + "sfc_port_ws63", "sfc_flash_config_ws63", "sfc_boot", "hal_sfc", + "cmn_header", "arch_port", "osal", "dfx_panic", "dfx_exception","cpu_utils", + '-:rtc', '-:hal_rtc', "common_boot_libc", + "error_code", "board_config", "chip_boot_port", "chip_boot_config", + '-:hal_systick', 'partition', 'partition_ws63','pmp_cfg_ws63', 'nonos_malloc', 'nonos_malloc_port', + 'update_common', 'update_local', 'update_local_ws63', 'lzma_22.00', 'update_storage', 'update_common_ws63', 'update_ab_ws63', 'factory_ws63', + 'efuse', 'hal_efuse_v151', 'efuse_port', 'soc_port', + ], + 'ram_component_set': ['uart', "time_set", "cpu", "pinctrl", "watchdog", "security_unified",'pmp_set'], + 'os': 'non-os', + 'application': 'flashboot', + 'bin_name': 'flashboot' + }, + 'ws63-loaderboot': { + 'base_target_name': 'target_ws63_boot_template', + 'CONFIG_TIMER_USING_V150': 'y', + 'defines': [ + "WS63_PRODUCT_NONE", + "CONFIG_TIMER_MAX_NUM=3", + "CONFIG_TIMER_CLOCK_VALUE=24000000", + "CONFIG_TIMER_0_WIDTH_64=0", + "SW_UART_DEBUG", + "CONFIG_UART_SUPPORT_RX", + "CONFIG_UART_SUPPORT_TX", + "BUILD_APPLICATION_ROM", + "EFUSE_BIT_OPERATION", + "PROVISION_WRITE_WITH_INTERFACE", + "FLASH_REGION_CFG_LOADERBOOT", + "BUILD_NOOSAL" + ], + 'ram_component': [ + "loaderboot_common", "common_boot", "ws63_loaderboot_lds", "dfx_preserve", + "libboundscheck", "chip_ws63", "ws63_mem_config", "common_headers","non_os", + "sfc_port_ws63", "sfc_flash_config_ws63", "sfc_boot", "hal_sfc", + "cmn_header", "arch_port", "osal", "dfx_panic", "dfx_exception","cpu_utils", + '-:rtc', '-:hal_rtc', "common_boot_libc",'soc_port', 'nonos_malloc', 'nonos_malloc_port', 'boot_port_malloc', + "error_code", "board_config", "chip_boot_port", "chip_boot_config", + '-:hal_systick','efuse_port', 'hal_efuse_v151', 'efuse', + ], + 'ram_component_set': ['uart', "time_set", "cpu", "pinctrl", "watchdog", "security_unified"], + 'os': 'non-os', + 'application': 'loaderboot', + 'bin_name': 'loaderboot' + }, + 'ws63-liteos-xts': { + 'base_target_name': 'target_ws63_xts_rom_template', + 'liteos_kconfig': 'ws63_xts', + 'os': 'liteos', + 'defines': [ + "USE_CMSIS_OS", + "USE_LITEOS", + "_ALL_SOURCE", + "__LITEOS__", + "-:CHIP_WS63=1", + "LIBUTIL_COMPAT", + "LOG_SUPPORT", + "HSO_SUPPORT", + "CONFIG_SUPPORT_NEW_DIAG", + "NO_TCXO_SUPPORT", + "UNSUPPORT_OTHER_MEM", + "SW_UART_DEBUG", + "SW_UART_CHIP_DEFINE", + "AT_COMMAND", + "DUMP_MEM_SUPPORT", + "BUILD_APPLICATION_STANDARD", + 'CMD_ENABLE', + 'WIFI_TASK_EXIST', + 'BGLE_TASK_EXIST', + 'BTH_TASK_EXIST', + "CONFIG_IPERF_SUPPORT", + "CONFIG_SENDTEST_SUPPORT", + "CONFIG_CACHE_MISS_SUPPORT", + "_PRE_WLAN_FEATURE_BTCOEX", + "_PRE_LWIP_ZERO_COPY", + #"WIFI_TCM_OPTIMIZE", + #"LWIP_TCM_OPTIMIZE", + "CHECKSUM_CHECK_TCP=0", + "CHECKSUM_CHECK_UDP=0", + "MBEDTLS_AES_ROM_TABLES", + "UPDATE_WIFI_STATIC_LIB", + "UPDATE_BTC_STATIC_LIB", + "CONFIG_NV_SUPPORT_SINGLE_CORE_SYSTEM", 'CONFIG_OTA_UPDATE_SUPPORT', + "MBEDTLS_HARDEN_OPEN", + 'CONFIG_UART_SUPPORT_LPM', + "_PRE_RADAR_CCA_SW_OPT", + ], + 'ram_component': [ + 'ws63_liteos_app', + 'ws63_liteos_xts_lds', + 'liteos_port', + 'irmalloc', + 'non_os', + '-:rtc', + 'arch_port', + 'board_config', # 被 pinctrl 组件依赖 + 'lpm', # 被 pwm 组件依赖 + 'chip_ws63', 'pmp_cfg_ws63', + 'reboot', 'hal_reboot', 'reboot_port', 'cpu_utils', 'hal_cpu_core', + 'gpio','hal_gpio_v150','gpio_port', + "dfx_port_ws63", "algorithm", "cmn_header", "lwip", "lwip_tcm", "wifi_service", "mbedtls", "wpa_supplicant", + "at", "wifi_driver_hmac", "wifi_driver_dmac", "wifi_driver_tcm", "wifi_at", "wifi_csa", "wifi_alg_txbf", "wifi_alg_temp_protect", "wifi_tx_amsdu", "wifi_sdp", + "wifi_auto_adjust_freq", "wifi_promisc", "wifi_alg_anti_interference", "wifi_alg_edca_opt", "wifi_alg_cca_opt", "wifi_sr", + "wifi_frag", "wifi_mbo", "wifi_bsrp_nfrp", "wifi_slp", "wifi_radar_sensor", "wifi_apf", "wifi_repeater", "wifi_csi", "wifi_wapi", "wifi_wps", "wifi_psd", "wifi_blacklist", "wifi_m2u", + "wifi_latency", "wifi_roam", "wifi_uapsd_sta", "wifi_ant_sel", "wifi_twt", "wifi_11k", "wifi_11v", "wifi_11r", 'wifi_btcoex', "wifi_uapsd_ap", "wifi_dnb", + 'liteos_208_5_0', 'rtc_unified', 'hal_rtc_unified', 'rtc_unified_port', + 'nv', 'nv_ws63', 'nv_zdiag_ws63', 'plt_at', + 'update_common', 'update_common_ws63', 'update_ab_ws63', 'factory_ws63', 'update_storage', 'update_storage_ws63', + 'pm_port_ws63', + 'gmssl_hmac_sm3', + 'bt_at', + "bt_host", + 'bg_common', + 'bth_gle', + 'bth_sdk', + 'samples', + 'bts_header', + 'bt_app', + 'mips', + 'hal_mips', + "bgtp", + 'soc_port', + 'radar_sensing', + 'radar_at', + 'ohos_adapt', + 'printf_adapt', + 'little_fs', 'littlefs_adapt_ws63', + 'xo_trim_port', + ], + 'ccflags': [ + "-DBOARD_ASIC", '-DPRE_ASIC', + ], + 'application': 'application', + 'bin_name': 'ws63-liteos-xts', + 'hso_enable_bt': True, + 'hso_enable': True, + 'codesize_statistic': True, + 'nv_update':True, + 'copy_files_to_interim': True + }, + 'ws63-liteos-app-iot': { + 'base_target_name': 'target_ws63_app_rom_template', + # 'liteos_kconfig': 'ws63_iot', + 'os': 'liteos', + 'defines': [ + "USE_CMSIS_OS", + "USE_LITEOS", + "_ALL_SOURCE", + "__LITEOS__", + "-:CHIP_WS63=1", + "LIBUTIL_COMPAT", + "LOG_SUPPORT", + "HSO_SUPPORT", + "NO_TCXO_SUPPORT", + "UNSUPPORT_OTHER_MEM", + "SW_UART_DEBUG", + "SW_UART_CHIP_DEFINE", + "AT_COMMAND", + "DUMP_MEM_SUPPORT", + "BUILD_APPLICATION_STANDARD", + 'CMD_ENABLE', + 'WIFI_TASK_EXIST', + 'BGLE_TASK_EXIST', + 'BTH_TASK_EXIST', + "CONFIG_IPERF_SUPPORT", + "CONFIG_SENDTEST_SUPPORT", + "_PRE_WLAN_FEATURE_BTCOEX", + "_PRE_LWIP_ZERO_COPY", + #"WIFI_TCM_OPTIMIZE", + #"LWIP_TCM_OPTIMIZE", + "CHECKSUM_CHECK_TCP=0", + "CHECKSUM_CHECK_UDP=0", + "MBEDTLS_AES_ROM_TABLES", + "UPDATE_WIFI_STATIC_LIB", + "UPDATE_BTC_STATIC_LIB", + "CONFIG_NV_SUPPORT_SINGLE_CORE_SYSTEM", 'CONFIG_OTA_UPDATE_SUPPORT', + "MBEDTLS_HARDEN_OPEN", + 'CONFIG_UART_SUPPORT_LPM', + "MBEDTLS_CONFIG_FILE=\"config-ws-iot.h\"", + "CONFIG_SUPPORT_HILINK", + "_PRE_RADAR_CCA_SW_OPT", + "SUPPORT_MINIMALIST_NETCFG", # 极简配网 + "SUPPORT_SOFTAP_NETCFG", # softAP配网 + "SUPPORT_BLE_ANCILLAY_NETCFG", # ble辅助配网 + # "SUPPORT_QUICK_NETCFG", # 快速配网 + "CONFIG_SUPPORT_HILINK_INDIE_UPGRADE", + "CONFIG_DHCPS_GW", + "_HSF_", + # "ENABLE_BLE_SCAN" #open ble scan + # "HF_MCU_OTA" #open mcu ota + ], + 'ram_component': [ + 'ws63_liteos_app', + 'ws63_liteos_app_lds', + 'liteos_port', + 'irmalloc', + 'non_os', + '-:rtc', + 'arch_port', + 'board_config', # 被 pinctrl 组件依赖 + 'lpm', # 被 pwm 组件依赖 + 'chip_ws63', 'pmp_cfg_ws63', + 'reboot', 'hal_reboot', 'reboot_port', 'cpu_utils', 'hal_cpu_core', + 'wifi_promisc', + 'gpio','hal_gpio_v150','gpio_port', + "dfx_port_ws63", "algorithm", "cmn_header", "lwip", "lwip_tcm", "wifi_service", "mbedtls", "wpa_supplicant", + "at", "wifi_driver_hmac", "wifi_driver_dmac", "wifi_driver_tcm", "wifi_at", "wifi_csa", "wifi_frag", "wifi_alg_txbf", "wifi_alg_temp_protect", "wifi_tx_amsdu", + "wifi_auto_adjust_freq", "wifi_alg_anti_interference", "wifi_alg_edca_opt", "wifi_alg_cca_opt", "wifi_radar_sensor", + 'wifi_btcoex', "wifi_uapsd_ap", + 'liteos_208_5_0', 'rtc_unified', 'hal_rtc_unified', 'rtc_unified_port', + 'nv', 'nv_ws63', 'nv_zdiag_ws63', 'plt_at', 'dfx_printer', + 'update_common', 'update_common_ws63', 'update_ab_ws63', 'factory_ws63', 'update_storage', 'update_storage_ws63', + 'pm_port_ws63', + 'gmssl_hmac_sm3', + 'bt_at', + "bt_host", + 'bg_common', + 'bth_gle', + 'bth_sdk', + 'samples', + 'bts_header', + 'bt_app', + 'mips', + 'hal_mips', + "bgtp", + 'soc_port', + 'radar_sensing', + 'radar_at', + 'cjson', + 'xo_trim_port', + 'hilink', + 'app_addr_map', + # 'hilinkdevicesdk', + # 'hilinkota', + # 'hilinkbtsdk', + 'huks_sdk', + 'deviceauth', + 'little_fs', 'littlefs_adapt_ws63', + 'hsf', + 'user_main' + ], + 'ccflags': [ + "-DBOARD_ASIC", '-DPRE_ASIC', + ], + 'application': 'application', + 'bin_name': 'ws63-liteos-app-iot', + 'smaller': True, + 'hso_enable_bt': True, + 'hso_enable': True, + 'codesize_statistic': True, + 'nv_update':True, + 'copy_files_to_interim': True + }, + 'ws63-liteos-hilink': { + 'base_target_name': 'target_ws63_hilink_rom_template', + 'os': 'liteos', + 'defines': [ + 'CONFIG_SUPPORT_HILINK_INDIE_UPGRADE', + 'SUPPORT_QUICK_NETCFG', + ], + 'ram_component': [ + 'ws63_liteos_hilink_lds', + 'hilink_addr_map', + 'hilinkdevicesdk', + 'hilinkota', + 'hilinkbtsdk', + 'hilinkquickcfg', + ], + 'ccflags': [ + "-DBOARD_ASIC", '-DPRE_ASIC', + ], + 'application': 'application', + 'bin_name': 'ws63-liteos-hilink', + 'copy_files_to_interim': True + }, +} + +# custom copy rules, put it in target_group below and it takes effect. +# means root path +# means output_root path +# means target_group key_name +target_copy = { + +} + +target_group = { + +} diff --git a/build/config/target_config/ws63/crash_info.py b/build/config/target_config/ws63/crash_info.py new file mode 100755 index 0000000..253fe87 --- /dev/null +++ b/build/config/target_config/ws63/crash_info.py @@ -0,0 +1,262 @@ +import struct +import sys +import os + +path = sys.argv[1:] + +bin_path = "./crashinfo.bin" +format_path = "./crashinfo.txt" +if len(path) >= 1: + for i in path: + if i.endswith("bin") and os.path.isfile(i): + bin_path = i + elif i.endswith("txt"): + format_path = i + else: + print("invalid parameter: ", i) +txt_path = "./crashinfo_bin.txt" +ret = [] + +def exc_info_get_phase(phase): + str = { + 0 : "Init", + 1 : "Task", + 2 : "Irq", + 3 : "Exc" + } + return str.get(phase, None) + +def task_info_get_status(status): + if status & 0x10 == 0x10: + return "Running" + elif status & 0x4 == 0x4: + return "Ready" + elif status & 0x20 == 0x20: + return "Delay" + elif status & 0x82 == 0x82: + return "SuspendTime" + elif status & 0x88 == 0x88: + return "PendTime" + elif status & 0x8 == 0x8: + return "Pend" + elif status & 0x2 == 0x2: + return "Suspend" + elif status & 0x100 == 0x100: + return "Zombie" + else: + return "Invalid" + +if __name__ == "__main__": + with open(bin_path, 'rb') as file: + data = file.read() + for byte in data: + ret.append(f"{byte:02x}") + + with open(txt_path,'w') as file: + line_index = 0 + for byte in ret: + file.write(byte) + line_index += 1 + if line_index >= 16 : + file.write('\n') + line_index = 0 + else: + file.write(' ') + + file = open(bin_path, "rb") + with open(format_path,'w') as write_file: + flag = struct.unpack(' 0 else 96 + task_info_cnt = struct.unpack('= len(task_name_arr): + break + file.seek(task_info_addr + i * task_info_size, 0) + task_info_stackPointer = struct.unpack('@endhtmlonly" \ + "tagBlackQue=@htmlonly
?
@endhtmlonly" \ + "CompanyNameMagicTag=Unname." \ + "CompanyNameTag=Unname." + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is +# Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# (including Cygwin) ands Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +#HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = Eng + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = NO + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = ./../../doxygen/buildfiles/layout.xml + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = NO + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = ./../../../../build/config/target_config/ws63/doc/driver_supports_matrix.dox \ + \ + ./../../../../include/common_def.h \ + ./../../../../include/errcode.h \ + ./../../../../drivers/chips/ws63/include/platform_core.h \ + \ + ./../../../../docs/driver/doxygen/driver_adc.c \ + ./../../../../docs/driver/doxygen/driver_dma.c \ + ./../../../../docs/driver/doxygen/driver_timer.c \ + ./../../../../docs/driver/doxygen/driver_i2c.c \ + ./../../../../docs/driver/doxygen/driver_i2s.c \ + ./../../../../docs/driver/doxygen/driver_pinctrl.c \ + ./../../../../docs/driver/doxygen/driver_pwm.c \ + ./../../../../docs/driver/doxygen/driver_rtc.c \ + ./../../../../docs/driver/doxygen/driver_spi.c \ + ./../../../../docs/driver/doxygen/driver_systick.c \ + ./../../../../docs/driver/doxygen/driver_tcxo.c \ + ./../../../../docs/driver/doxygen/driver_timer.c \ + ./../../../../docs/driver/doxygen/driver_uart.c \ + ./../../../../docs/driver/doxygen/driver_watchdog.c \ + \ + ./../../../../include/driver/adc.h \ + ./../../../../include/driver/dma.h \ + ./../../../../include/driver/efuse.h \ + ./../../../../include/driver/gpio.h \ + ./../../../../include/driver/i2c.h \ + ./../../../../include/driver/i2s.h \ + ./../../../../include/driver/pinctrl.h \ + ./../../../../include/driver/drv_pmp.h \ + ./../../../../include/driver/pwm.h \ + ./../../../../include/driver/rtc.h \ + ./../../../../include/driver/security_unified \ + ./../../../../include/driver/spi.h \ + ./../../../../include/driver/systick.h \ + ./../../../../include/driver/tcxo.h \ + ./../../../../include/driver/timer.h \ + ./../../../../include/driver/uart.h \ + ./../../../../include/driver/watchdog.h \ + \ + ./../../../../drivers/drivers/hal/adc \ + ./../../../../drivers/drivers/hal/dma/hal_dma.h \ + ./../../../../drivers/drivers/hal/dma/hal_dma_mem.h \ + ./../../../../drivers/drivers/hal/dma/v150 \ + ./../../../../drivers/drivers/hal/gpio/hal_gpio.h \ + ./../../../../drivers/drivers/hal/gpio/v150 \ + ./../../../../drivers/drivers/hal/i2c/hal_i2c.h \ + ./../../../../drivers/drivers/hal/i2c/v150 \ + ./../../../../drivers/drivers/hal/pinmux/common/hal_pinctrl.h \ + ./../../../../drivers/chips/ws63/rom/drivers/drivers/hal/pinmux/ws63 \ + ./../../../../drivers/drivers/hal/pwm/hal_pwm.h \ + ./../../../../drivers/drivers/hal/pwm/v151 \ + ./../../../../drivers/drivers/hal/rtc_unified/hal_rtc.h \ + ./../../../../drivers/drivers/hal/spi/hal_spi.h \ + ./../../../../drivers/drivers/hal/spi/v151/hal_spi_v151.h \ + ./../../../../drivers/drivers/hal/spi/v151/hal_spi_v151_regs_def.h \ + ./../../../../drivers/drivers/hal/spi/v151/hal_spi_v151_regs_op.h \ + ./../../../../drivers/drivers/hal/systick \ + ./../../../../drivers/drivers/hal/tcxo \ + ./../../../../drivers/drivers/hal/timer/hal_drv_timer.h \ + ./../../../../drivers/drivers/hal/timer/v150 \ + ./../../../../drivers/drivers/hal/uart/hal_uart.h \ + ./../../../../drivers/drivers/hal/uart/v151 \ + ./../../../../drivers/drivers/hal/watchdog/hal_watchdog.h \ + ./../../../../drivers/drivers/hal/watchdog/v151 \ + ./../../../../drivers/drivers/hal/sio/hal_sio.h \ + ./../../../../drivers/drivers/hal/sio/hal_sio_v150 \ + ./../../../../drivers/drivers/hal/pmp/v31 \ + \ + ./../../../../drivers/chips/ws63/include/platform_core_rom.h \ + ./../../../../drivers/chips/ws63/porting/adc/adc_porting.h \ + ./../../../../drivers/chips/ws63/porting/dma/dma_porting.h \ + ./../../../../drivers/chips/ws63/rom/drivers/chips/ws63/porting/pinctrl/pinctrl_porting.h \ + ./../../../../drivers/chips/ws63/rom/drivers/chips/ws63/porting/timer/timer_porting.h \ + ./../../../../drivers/chips/ws63/porting/gpio/gpio_porting.h \ + ./../../../../drivers/chips/ws63/porting/rtc_unified/rtc_porting.h \ + ./../../../../drivers/chips/ws63/porting/i2c/i2c_porting.h \ + ./../../../../drivers/chips/ws63/porting/spi/spi_porting.h \ + ./../../../../drivers/chips/ws63/rom/drivers/chips/ws63/porting/systick/systick_porting.h \ + ./../../../../drivers/chips/ws63/rom/drivers/chips/ws63/porting/tcxo/tcxo_porting.h \ + ./../../../../drivers/chips/ws63/porting/uart/uart_porting.h \ + ./../../../../drivers/chips/ws63/porting/pwm/pwm_porting.h \ + ./../../../../drivers/chips/ws63/rom/drivers/chips/ws63/porting/watchdog/watchdog_porting.h \ + ./../../../../drivers/chips/ws63/porting/sio/sio_porting.h \ + ./../../../../middleware/utils/at/at \ + ./../../../../middleware/chips/ws63/dfx/include/at_config.h \ + \ + ./../../../../include/middleware/services/bts/ble/bts_factory.h \ + ./../../../../include/middleware/services/bts/ble/bts_gatt_stru.h \ + ./../../../../include/middleware/services/bts/ble/bts_gatt_client.h \ + ./../../../../include/middleware/services/bts/ble/bts_gatt_server.h \ + ./../../../../include/middleware/services/bts/ble/bts_le_gap.h \ + \ + ./../../../../include/middleware/services/bts/sle/sle_common.h \ + ./../../../../include/middleware/services/bts/sle/sle_low_latency.h \ + ./../../../../include/middleware/services/bts/sle/sle_connection_manager.h \ + ./../../../../include/middleware/services/bts/sle/sle_device_discovery.h \ + ./../../../../include/middleware/services/bts/sle/sle_errcode.h \ + ./../../../../include/middleware/services/bts/sle/sle_factory_manager.h \ + ./../../../../include/middleware/services/bts/sle/sle_hadm_manager.h \ + ./../../../../include/middleware/services/bts/sle/sle_ssap_client.h \ + ./../../../../include/middleware/services/bts/sle/sle_ssap_server.h \ + ./../../../../include/middleware/services/bts/sle/sle_ssap_stru.h \ + ./../../../../include/middleware/services/bts/sle/sle_transmition_manager.h \ + \ + ./../../../../include/middleware/services/wifi/wifi_alg.h \ + \ + \ + ./../../../../include/middleware/services/wifi/wifi_device.h \ + \ + \ + ./../../../../include/middleware/services/wifi/wifi_device_config.h \ + \ + \ + ./../../../../include/middleware/services/wifi/wifi_hotspot.h \ + \ + \ + ./../../../../include/middleware/services/wifi/wifi_hotspot_config.h \ + \ + \ + ./../../../../include/middleware/services/wifi/wifi_event.h \ + \ + \ + ./../../../../include/middleware/services/wifi/station_info.h \ + \ + \ + ./../../../../include/middleware/services/wifi/wifi_linked_info.h \ + \ + \ + ./../../../../include/middleware/services/wifi/wifi_scan_info.h \ + \ + ./../../../../include/middleware/services/radar/radar_service.h \ + ./../../../../kernel/osal/include/memory/osal_addr.h \ + ./../../../../kernel/osal/include/atomic/osal_atomic.h \ + ./../../../../kernel/osal/include/memory/osal_barrier.h \ + ./../../../../kernel/osal/include/math/osal_bitmap.h \ + ./../../../../kernel/osal/include/memory/osal_cache.h \ + ./../../../../kernel/osal/include/schedule/osal_completion.h \ + ./../../../../kernel/osal/include/debug/osal_debug.h \ + ./../../../../kernel/osal/include/schedule/osal_delaywork.h \ + ./../../../../kernel/osal/include/device/osal_device.h \ + ./../../../../kernel/osal/include/drvbox/osal_drvbox.h \ + ./../../../../kernel/osal/include/event/osal_event.h \ + ./../../../../kernel/osal/include/fileops/osal_fileops.h \ + ./../../../../kernel/osal/include/interrupt/osal_interrupt.h \ + ./../../../../kernel/osal/include/math/osal_math.h \ + ./../../../../kernel/osal/include/msgqueue/osal_msgqueue.h \ + ./../../../../kernel/osal/include/lock/osal_mutex.h \ + ./../../../../kernel/osal/include/proc/osal_proc.h \ + ./../../../../kernel/osal/include/lock/osal_rwlock.h \ + ./../../../../kernel/osal/include/semaphore/osal_semaphore.h \ + ./../../../../kernel/osal/include/lock/osal_spinlock.h \ + ./../../../../kernel/osal/include/string/osal_string.h \ + ./../../../../kernel/osal/include/schedule/osal_task.h \ + ./../../../../kernel/osal/include/time/osal_timer.h \ + ./../../../../kernel/osal/include/schedule/osal_wait.h \ + ./../../../../kernel/osal/include/schedule/osal_workqueue.h \ + \ + ./../../doxygen/doc/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), +# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen +# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.h \ + *.dox + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = LiteOS \ + *.c + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = ./../../../../application/samples/peripheral/ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = YES + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = ./../../../../docs/driver/doxygen/image/ + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files +# were built. This is equivalent to specifying the "-p" option to a clang tool, +# such as clang-check. These options will then be passed to the parser. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse-libclang=ON option for CMake. +# The default value is: 0. + +#CLANG_COMPILATION_DATABASE_PATH = 0 + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = NO + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = ./../../doxygen/buildfiles/header.html + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = ./../../doxygen/buildfiles/footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = ./../../doxygen/buildfiles/extra_stylesheet.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 196 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 46 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 92 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +#HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +### EDIT THIS ### + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 1 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +#MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /