open_source文件夹1201patch合并 3347/1 3347/head 3348/target/1
authorluozheng <1732036298@qq.com>
Thu, 16 Apr 2026 08:36:48 +0000 (16:36 +0800)
committerluozheng <1732036298@qq.com>
Thu, 16 Apr 2026 08:36:48 +0000 (16:36 +0800)
226 files changed:
code/sdk/open_source/openharmony/CMakeLists.txt
code/sdk/open_source/openharmony/base/global/resmgr_lite/frameworks/resmgr_lite/src/global_utils.c
code/sdk/open_source/openharmony/base/security/appverify/app_mbedtls_pkcs7.c
code/sdk/open_source/openharmony/base/security/appverify/include/app_verify_pub.h
code/sdk/open_source/openharmony/base/security/appverify/include/mbedtls_pkcs7.h
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/CMakeLists.txt
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/include/cipher.h
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/include/cipher_log.h
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_aes.c
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_base64.c [new file with mode: 0644]
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_hmac_sha256.c [new file with mode: 0644]
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_md5.c [new file with mode: 0644]
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_nv_store.c [new file with mode: 0644]
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/js/builtin/CMakeLists.txt
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/js/builtin/include/cipher_module.h
code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/js/builtin/src/cipher_module.cpp
code/sdk/open_source/openharmony/base/sensors/frameworks/src/sensor_agent.c
code/sdk/open_source/openharmony/base/sensors/frameworks/src/sensor_agent_proxy.c
code/sdk/open_source/openharmony/base/sensors/interfaces/kits/native/include/sensor_agent.h
code/sdk/open_source/openharmony/base/sensors/interfaces/kits/native/include/sensor_agent_type.h
code/sdk/open_source/openharmony/base/sensors/interfaces/kits/native/include/sensor_agent_type_ext.h
code/sdk/open_source/openharmony/base/sensors/location/interfaces/kits/include/location.h
code/sdk/open_source/openharmony/base/sensors/location/sample/location_sample.cpp
code/sdk/open_source/openharmony/base/sensors/location/services/location_gnss/gnss/source/gnss_event_callback.cpp
code/sdk/open_source/openharmony/base/sensors/location/services/utils/source/location.cpp
code/sdk/open_source/openharmony/base/sensors/sample/sensor_sample.cpp
code/sdk/open_source/openharmony/base/sensors/services/include/sensor_service.h
code/sdk/open_source/openharmony/base/sensors/services/include/sensor_service_impl.h
code/sdk/open_source/openharmony/base/sensors/services/src/sensor_service.c
code/sdk/open_source/openharmony/base/sensors/services/src/sensor_service_impl.c
code/sdk/open_source/openharmony/base/startup/syspara_lite/src/hal_sys_param.c
code/sdk/open_source/openharmony/base/startup/syspara_lite/src/parameter_common.c
code/sdk/open_source/openharmony/base/startup/syspara_lite/src/文件夹1201patch合并提交 [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/format/interfaces/include/format_type.h
code/sdk/open_source/openharmony/drivers/peripheral/location/gnss/gnss_emulator/source/gnss_emulator_vendor_impl.cpp
code/sdk/open_source/openharmony/drivers/peripheral/location/gnss/hdi_service/include/location_vendor_lib.h
code/sdk/open_source/openharmony/drivers/peripheral/location/gnss/hdi_service/source/gnss_interface_impl.cpp
code/sdk/open_source/openharmony/drivers/peripheral/location/gnss/utils/include/gnss_nmea_parse.h
code/sdk/open_source/openharmony/drivers/peripheral/location/gnss/utils/include/gnss_utils.h
code/sdk/open_source/openharmony/drivers/peripheral/location/gnss/utils/source/gnss_nmea_parse.cpp
code/sdk/open_source/openharmony/drivers/peripheral/location/gnss/utils/source/gnss_utils.cpp
code/sdk/open_source/openharmony/drivers/peripheral/location/interface/gnss/v2_0/gnss_types.h
code/sdk/open_source/openharmony/drivers/peripheral/sensor/CMakeLists.txt [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/CMakeLists.txt [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/include/sensor_common.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/include/sensor_manager.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/include/sensor_typedef.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensor_data_service/include/hsensor_data_service.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensor_data_service/src/hsensor_data_service.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensormgr_service/include/hsensormgr_service.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensormgr_service/src/hsensormgr_service.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/sensor_interface_impl.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/sensor_manager.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/include/sensor_task.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/include/sensor_tmsg.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/src/sensor_task.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/src/sensor_tmsg.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_memory.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_msgqueue.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_para_decision.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_state.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_thread.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_utils.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_log.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_memory.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_msgqueue.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_para_decision.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_state.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_thread.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_utils.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/include/vsensor_task_mgr.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/include/vsensormgr_service.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/include/vsensor_task_class.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/include/vsensor_task_comm.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_class.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_comm.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_mgr.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensormgr_service.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/acc_simulator/CMakeLists.txt [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/acc_simulator/acc_simulator.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/barometer/CMakeLists.txt [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/barometer/barometer.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/gyroscope/CMakeLists.txt [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/gyroscope/gyroscope.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/heart_rate_counter/CMakeLists.txt [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/heart_rate_counter/heart_rate_counter.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/pedometer/CMakeLists.txt [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/pedometer/pedometer.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/wear_detection/CMakeLists.txt [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/wear_detection/wear_detection.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/vsensor/acc_alg_simulator/CMakeLists.txt [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/vsensor/acc_alg_simulator/acc_alg_simulator.c [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/vsensor/common/include/vsensor_common.h [new file with mode: 0644]
code/sdk/open_source/openharmony/drivers/peripheral/sensor/interfaces/include/sensor_if.h
code/sdk/open_source/openharmony/drivers/peripheral/sensor/interfaces/include/sensor_type.h
code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-auto-ota-cli/libams.a
code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-auto-ota-ser/libams.a
code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-native-js/libams.a
code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-xts/libams.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/CMakeLists.txt
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/list_adapter_ext.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/list_ext_component.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/menu_item_component.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/scroll_component.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/base/keys.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_ble.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_ext.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_http.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_websocket.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libnetstack_http.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libwebsocket.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_ble.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_ext.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_http.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_websocket.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libnetstack_http.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libwebsocket.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_ble.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_ext.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_http.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_websocket.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libnetstack_http.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libwebsocket.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-target3/libnetstack_http.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_ble.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_ext.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_http.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_websocket.a [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libnetstack_http.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libwebsocket.a
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/components/component_factory.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/components/component_utils.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/components/input_edittext_component.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/components/input_edittext_component.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/components/list_adapter.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/components/list_adapter.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/components/list_component.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/context/js_ability_impl.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/include/context/js_ability.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/app_module.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/baidumapcomponent/baidumap.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/bluetooth/ble_module.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/bluetooth/ble_module_common.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_manager.cpp [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_manager.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_module.cpp [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_module.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_timer.cpp [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_timer.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_utils.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/event_id_manager.cpp [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/event_id_manager.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/display/display.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/geolocation_module.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/geolocation_module.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_callback.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_module.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_module_callback.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_module_client.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http_errcode.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/http/include/httpclient.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/http/internal/http_form_data.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/http/internal/http_opts.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/http/internal/http_wrappers.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/include/net_websocket_type.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_debug.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_frame.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_list.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_opts.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_priv.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_string.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_thread.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/connection_manage/connection_manage.cpp [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/connection_manage/connection_manage.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/network_listener.cpp [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/network_listener.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/network_module.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/network_module.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/ohos_module_config.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/router_module.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/router_module.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/sensor_module.cpp
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/sensor_module.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/watchface/watchface_module.cpp [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/watchface/watchface_module.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_common.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_module.h
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_module_callback.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_module_client.h [new file with mode: 0644]
code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/router/js_router.h
code/sdk/open_source/openharmony/foundation/appexecfwk/appexecfwk_lite/brandy-auto-ota-cli/libbms.a
code/sdk/open_source/openharmony/foundation/appexecfwk/appexecfwk_lite/brandy-auto-ota-ser/libbms.a
code/sdk/open_source/openharmony/foundation/appexecfwk/appexecfwk_lite/brandy-native-js/libbms.a
code/sdk/open_source/openharmony/foundation/multimedia/audio_capturer/interfaces/kits/audio_capturer_lite/recording_module.h
code/sdk/open_source/openharmony/foundation/multimedia/player/interfaces/kits/player.h
code/sdk/open_source/openharmony/third_party/jerryscript/brandy-auto-ota-cli/libjerryscript.a
code/sdk/open_source/openharmony/third_party/jerryscript/brandy-auto-ota-ser/libjerryscript.a
code/sdk/open_source/openharmony/third_party/jerryscript/brandy-native-js/libjerryscript.a
code/sdk/open_source/openharmony/third_party/jerryscript/brandy-xts/libjerryscript.a
code/sdk/open_source/openharmony/third_party/lwip/CMakeLists.txt
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/arch/sys_arch.c
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include/arch/cc.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include/arch/sys_arch.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include/lwip/lwipopts_default.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter/lwip_driver_adapter.c
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter/lwip_driver_adapter.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter/lwip_net_manage.c [new file with mode: 0644]
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/core/dns.c
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/core/ipv4/dhcp.c
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/core/netif.c
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/core/tcp_out.c
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/lwip/dhcp.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/lwip/dhcp6.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/lwip/dns.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/lwip/etharp.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/lwip/igmp.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/lwip/ip4_frag.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/lwip/ip6_frag.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/lwip/mld6.h
code/sdk/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include/lwip/nd6.h
code/sdk/open_source/openharmony/utils/native/lite/js/builtin/filekit/include/nativeapi_fs.h
code/sdk/open_source/openharmony/utils/native/lite/js/builtin/filekit/src/nativeapi_fs.cpp

index b900aa7..d71bd4f 100644 (file)
@@ -9,9 +9,6 @@ if (DEFINES MATCHES "ENABLE_UIKIT")
     add_subdirectory_with_alias_if_exist(third_party/qrcodegen ${PROJECT_BINARY_DIR}/qrcodegen)
     add_subdirectory_with_alias_if_exist(third_party/icu ${PROJECT_BINARY_DIR}/icu)
     add_subdirectory_with_alias_if_exist(third_party/harfbuzz ${PROJECT_BINARY_DIR}/harfbuzz)
-endif()
-
-if (DEFINES MATCHES "XTS_SUPPORT")
     add_subdirectory_with_alias_if_exist(third_party/libjpeg ${PROJECT_BINARY_DIR}/libjpeg)
     add_subdirectory_with_alias_if_exist(third_party/zlib ${PROJECT_BINARY_DIR}/zlib)
     add_subdirectory_with_alias_if_exist(third_party/libpng ${PROJECT_BINARY_DIR}/libpng)
@@ -37,7 +34,7 @@ add_subdirectory_with_alias_if_exist(base/global/resmgr_lite ${PROJECT_BINARY_DI
 add_subdirectory_with_alias_if_exist(base/sensors/location ${PROJECT_BINARY_DIR}/ohos/location)
 add_subdirectory_with_alias_if_exist(drivers/peripheral/location ${PROJECT_BINARY_DIR}/ohos/location_hdi)
 add_subdirectory_with_alias_if_exist(base/sensors ${PROJECT_BINARY_DIR}/ohos/sensors)
-add_subdirectory_with_alias_if_exist(drivers/peripheral/sensor/hal ${PROJECT_BINARY_DIR}/ohos/sensor_hdi)
+add_subdirectory_with_alias_if_exist(drivers/peripheral/sensor/ ${PROJECT_BINARY_DIR}/ohos/sensor_hdi)
 add_subdirectory_with_alias_if_exist(utils/native/lite/file ${PROJECT_BINARY_DIR}/ohos/file)
 add_subdirectory_with_alias_if_exist(utils/native/lite/kv_store ${PROJECT_BINARY_DIR}/ohos/kv_store)
 add_subdirectory_with_alias_if_exist(utils/native/lite/js/builtin ${PROJECT_BINARY_DIR}/ohos/storage_jsi)
index f966b0b..0ea20e8 100644 (file)
@@ -4,7 +4,7 @@
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
 
 #include "mbedtls_pkcs7.h"
 #include <ctype.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
+#include <stdbool.h>
 #include <dirent.h>
 #include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
 #include "app_common.h"
 #include "securec.h"
 #include "mbedtls/platform.h"
@@ -28,6 +29,8 @@
 #include <mbedtls/rsa.h>
 #include <mbedtls/sha256.h>
 #include <mbedtls/pk.h>
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/oid.h"
 #include "mbedtls/entropy.h"
 #include "mbedtls/ctr_drbg.h"
 #include <mbedtls/ecdh.h>
 #include "log.h"
 #include "nv.h"
 
-/*
- * below pkcs-7 and pkcs-9 oid definition is not defined in mbedtls now
- * pkcs-7 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 }
- */
+#define VERIFY_BUF_LEN 512
+
 #ifndef MBEDTLS_OID_PKCS7
-#define MBEDTLS_OID_PKCS7               MBEDTLS_OID_PKCS "\x07"
+#define MBEDTLS_OID_PKCS7 MBEDTLS_OID_PKCS "\x07"
 #endif
 
 #ifndef MBEDTLS_OID_PKCS7_DATA
@@ -60,7 +61,7 @@
 #define PEM_FORMAT_SINGED_DATA 1
 #define DER_FORMAT_SINGED_DATA 2
 
-#define PKCS7_ERR_GOTO_OUT(rc)                                                                  \
+#define PKCS7_ERR_RETURN_WITH_LOG(rc) \
     do { \
         if ((rc) != PKCS7_SUCC) \
         { \
         } \
     } while (0)
 
+#define OEM_CERT_PATH "/user/app/user/certcfg/"
+
+/* hardcoded public key */
+static const char ROOT_CA_OEM_PUBKEY_IN_PEM[] =
+    "-----BEGIN PUBLIC KEY-----\r\n"
+    "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvnjlpcsSvEOhMfYwrW/Y\r\n"
+    "ExDmXL47SkbomiorGtdF63J2Vkgs2/HTxhUKBkIvSPbGRTR+io8rAo2J3oz1U48m\r\n"
+    "+M/+yIszIYC2s+tW64v8NuxLwMFFeg7+cud07/FwfJYYIRvyDQVduwV0VwvkTQy+\r\n"
+    "4/n5m+zJEHNheCakEEmFXn7vXUzxlSVSji5cHbGZ2ZzdmettLMc88tv/Kq8X3rgM\r\n"
+    "KQkngVylO4p93UvzY9hIAh9heL5VWMVOj241p3RojavIofODIeF7Vti2DjJjvbPW\r\n"
+    "igV0M9C0wLlZzMTQwoZbZT8mKsHkXW3XdTgc8ccD7RioeQa9MOlLKFbnJQLYNKr+\r\n"
+    "WsGDTFO2iHQmRAIGGuvWnxZIGS5Ho+ZUntdIYAvH8ww+36eFOwNp5cb1/ZjZmQ4c\r\n"
+    "p0zTw3zF8mSEieToMgIgz19wc9hvYgMPLlZpzFZklg8tJenJvcNpk5/3saEmpV6R\r\n"
+    "gGZ0IrmT/5h3Z/49W86Dv3b2ro4zb/sqtLufDqGoF3IDAgMBAAE=\r\n"
+    "-----END PUBLIC KEY-----\r\n";
+
 static mbedtls_x509_crt g_rootCaG2Cert;
 static bool g_rootCertLoaded;
-static const unsigned char g_rootCaG2CertInPem[] =
+static const unsigned char ROOT_CA_G2_CERT_IN_PEM[] =
     "-----BEGIN CERTIFICATE-----\r\n"
     "MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC\r\n"
     "Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE\r\n"
@@ -89,7 +106,7 @@ static const unsigned char g_rootCaG2CertInPem[] =
 
 static mbedtls_x509_crt g_debugModeRootCert;
 static bool g_debugModeEnabled;
-static const unsigned char g_debugModeRootCertInPem[] =
+static const unsigned char DEBUG_MODE_ROOT_CERT_IN_PEM[] =
     "-----BEGIN CERTIFICATE-----\r\n"
     "MIICJTCCAaugAwIBAgIIb/9KnVieVTgwCgYIKoZIzj0EAwMwWDELMAkGA1UEBhMC\r\n"
     "Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEjMCEGA1UE\r\n"
@@ -122,19 +139,13 @@ static const unsigned char OHOS_ROOT_CERT_IN_PEM[] =
     "1CumzkcYhgU=\r\n"
     "-----END CERTIFICATE-----\r\n";
 
-#define VERIFY_BUF_LEN 512
-#define MAX_CERTPATH_LEN 256
-#define OEM_CERT_PATH "/user/app/user/certcfg/"
+static CertVerifyCache g_certCache = {0};
+static bool g_cacheValid = false;
 
 static void *Pkcs7Calloc(size_t nmemb, size_t size)
 {
-#if (RUNNING_BOARD == LITE_WEARABLE)
-    void *ptr = PSRAM_Malloc(nmemb * size);
-    if (ptr == NULL) {
-        return NULL;
-    }
-    (void)memset_s(ptr, nmemb * size, 0, nmemb * size);
-    return ptr;
+#ifdef LITEWEARABLE_SUPPORT_ENABLED
+    return APPV_CALLOC(nmemb, size);
 #else
     return calloc(nmemb, size);
 #endif
@@ -142,29 +153,14 @@ static void *Pkcs7Calloc(size_t nmemb, size_t size)
 
 static void Pkcs7Free(void *ptr)
 {
-#if (RUNNING_BOARD == LITE_WEARABLE)
-    PSRAM_Free(ptr);
+#ifdef LITEWEARABLE_SUPPORT_ENABLED
+    APPV_FREE(ptr);
 #else
     free(ptr);
 #endif
 }
-
-#ifdef MARKET_ENABLE
+#ifdef OH_MARKET_ENABLE
 #define DIALMARKET_PUBKEY_PATH "/user/dialpubkey"
-/* hardcoded public key */
-static const char ROOT_CA_OEM_PUBKEY_IN_PEM[] =
-    "-----BEGIN PUBLIC KEY-----\r\n"
-    "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvnjlpcsSvEOhMfYwrW/Y\r\n"
-    "ExDmXL47SkbomiorGtdF63J2Vkgs2/HTxhUKBkIvSPbGRTR+io8rAo2J3oz1U48m\r\n"
-    "+M/+yIszIYC2s+tW64v8NuxLwMFFeg7+cud07/FwfJYYIRvyDQVduwV0VwvkTQy+\r\n"
-    "4/n5m+zJEHNheCakEEmFXn7vXUzxlSVSji5cHbGZ2ZzdmettLMc88tv/Kq8X3rgM\r\n"
-    "KQkngVylO4p93UvzY9hIAh9heL5VWMVOj241p3RojavIofODIeF7Vti2DjJjvbPW\r\n"
-    "igV0M9C0wLlZzMTQwoZbZT8mKsHkXW3XdTgc8ccD7RioeQa9MOlLKFbnJQLYNKr+\r\n"
-    "WsGDTFO2iHQmRAIGGuvWnxZIGS5Ho+ZUntdIYAvH8ww+36eFOwNp5cb1/ZjZmQ4c\r\n"
-    "p0zTw3zF8mSEieToMgIgz19wc9hvYgMPLlZpzFZklg8tJenJvcNpk5/3saEmpV6R\r\n"
-    "gGZ0IrmT/5h3Z/49W86Dv3b2ro4zb/sqtLufDqGoF3IDAgMBAAE=\r\n"
-    "-----END PUBLIC KEY-----\r\n";
-
 static const unsigned char g_dialRootCertInPem[] =
     "-----BEGIN CERTIFICATE-----\r\n"
     "MIIEsTCCAxmgAwIBAgIUdJ4u/0ct0XJHZphCzmBQQddboC4wDQYJKoZIhvcNAQEL\r\n"
@@ -495,7 +491,7 @@ cleanup:
     return ret;
 }
 
-int32_t PKCS7_GenerateECCKeypair()
+int32_t PKCS7_GenerateECCKeypair(void)
 {
     unsigned char clientPubKey[ECC_PEN_KEY_LEN];
     EcdhEntity client = {0};
@@ -548,7 +544,8 @@ int32_t PKCS7_GenerateECCKeypair()
         HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to GetClientECCPubKey!\n");
         goto cleanup;
     }
-    if (CreateCubdirAndFile(DIALMARKET_PUBKEY_PATH, pubKeyFileName, clientPubKey, strlen(clientPubKey)) != 0) {
+    if (CreateCubdirAndFile(DIALMARKET_PUBKEY_PATH, (const char*)pubKeyFileName,
+        clientPubKey, strlen((const char*)clientPubKey)) != 0) {
         HILOG_ERROR(HILOG_MODULE_AAFWK, "Public key write failed!");
         ret = MBEDTLS_ERR_PK_FILE_IO_ERROR;
         goto cleanup;
@@ -920,77 +917,546 @@ cleanup:
     memset_s(eccWorkKey, AES_KEY_LEN, 0, AES_KEY_LEN);
     return ret;
 }
+#endif
 
-static int32_t VerifyHashList()
+static void FreeCertVerifyCache(CertVerifyCache *cache)
 {
-    int32_t rc = 0;
-    const char *hashListFile = OEM_CERT_PATH"root_cert_hash_list.bin";
-    const char *signatureFile = OEM_CERT_PATH"hash_list_sign.bin";
-    unsigned char hash[SHA256_HASH_SIZE];
-    mbedtls_pk_context pk;
-    FILE *file = fopen(hashListFile, "rb");
+    if (cache == NULL) return;
+    
+    if (cache->hashListData != NULL) {
+        Pkcs7Free(cache->hashListData);
+        cache->hashListData = NULL;
+    }
+    cache->hashListSize = 0;
+    cache->verifyTime = 0;
+    g_cacheValid = false;
+}
+
+/**
+ * 计算文件的SHA256哈希值(与openssl dgst -sha256兼容)
+ * @param filePath 文件路径
+ * @param hash 输出二进制哈希值(32字节)
+ * @param hexHash 输出十六进制哈希字符串(65字节,包含终止符)
+ * @return 成功返回PKCS7_SUCC,失败返回错误码
+ */
+static int32_t CalculateFileSha256(const char *filePath, unsigned char *hash, char *hexHash)
+{
+    if (filePath == NULL || hash == NULL || hexHash == NULL) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Invalid parameters to CalculateFileSha256");
+        return PKCS7_INVALID_PARAM;
+    }
+
+    FILE *file = NULL;
+    mbedtls_sha256_context sha256Ctx;
+    unsigned char *buffer = NULL;
+    size_t bufferSize = 4096; // 4KB缓冲区
+    size_t bytesRead;
+    int32_t rc = PKCS7_SUCC;
+    const char *hexChars = "0123456789abcdef";
+
+    // 分配堆内存缓冲区
+    buffer = Pkcs7Calloc(bufferSize, sizeof(unsigned char));
+    if (buffer == NULL) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to allocate buffer for file reading");
+        return PKCS7_MEMORY_EXHAUST;
+    }
+
+    file = fopen(filePath, "rb");
     if (!file) {
-        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open file to verify.");
-        return PKCS7_VERIFY_FAIL;
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open file: %s", filePath);
+        rc = PKCS7_FILE_OPERATION_FAIL;
+        goto cleanup;
     }
-    rc = fseek(file, 0, SEEK_END);
-    if (rc != 0) {
-        rc = PKCS7_HAS_NO_SIGNER_CRT;
-        goto exit;
+
+    mbedtls_sha256_init(&sha256Ctx);
+    
+    // 初始化SHA256上下文(0表示SHA-256,1表示SHA-224)
+    if (mbedtls_sha256_starts(&sha256Ctx, 0) != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to initialize SHA256 context");
+        rc = PKCS7_INVALID_VALUE;
+        goto cleanup;
     }
-    long fileSize = ftell(file);
-    rc = fseek(file, 0, SEEK_SET);
-    if (rc != 0 || fileSize > INT_MAX) {
-        rc = PKCS7_HAS_NO_SIGNER_CRT;
-        goto exit;
+
+    // 读取文件并更新哈希
+    while ((bytesRead = fread(buffer, 1, bufferSize, file)) > 0) {
+        if (mbedtls_sha256_update(&sha256Ctx, buffer, bytesRead) != 0) {
+            HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to update SHA256 hash");
+            rc = PKCS7_INVALID_VALUE;
+            goto cleanup;
+        }
     }
-    unsigned char *fileData = Pkcs7Calloc(fileSize, sizeof(char));
-    if (!fileData) {
-        rc = PKCS7_HAS_NO_SIGNER_CRT;
-        goto exit;
+
+    // 检查文件读取错误
+    if (ferror(file)) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Error reading file: %s", filePath);
+        rc = PKCS7_FILE_OPERATION_FAIL;
+        goto cleanup;
     }
-    int32_t fileLen = fread(fileData, 1, fileSize, file);
-    if (fileLen != fileSize) {
-        rc = PKCS7_HAS_NO_SIGNER_CRT;
-        goto exit;
+
+    // 完成哈希计算
+    if (mbedtls_sha256_finish(&sha256Ctx, hash) != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to finalize SHA256 hash");
+        rc = PKCS7_INVALID_VALUE;
+        goto cleanup;
     }
-    mbedtls_pk_init(&pk);
-    if ((rc = mbedtls_pk_parse_public_key(&pk, (const unsigned char *)ROOT_CA_OEM_PUBKEY_IN_PEM,
-        strlen(ROOT_CA_OEM_PUBKEY_IN_PEM) + 1)) != 0) {
-        rc = PKCS7_HAS_NO_SIGNER_CRT;
-        goto exit;
+
+    // 转换为十六进制字符串(与openssl输出格式一致)
+    for (int i = 0; i < SHA256_HASH_SIZE; i++) {
+        hexHash[i * 2] = hexChars[(hash[i] >> 4) & 0x0F];
+        hexHash[i * 2 + 1] = hexChars[hash[i] & 0x0F];
     }
-    mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
-    mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
-    FILE *sigFile = fopen(signatureFile, "rb");
-    if (!sigFile) {
-        rc = PKCS7_HAS_NO_SIGNER_CRT;
-        goto exit;
+    hexHash[64] = '\0';
+
+cleanup:
+    if (file) fclose(file);
+    if (buffer) Pkcs7Free(buffer);
+    mbedtls_sha256_free(&sha256Ctx);
+    return rc;
+}
+
+// 十六进制哈希转换为二进制(使用安全函数)
+static int32_t HexHashToBinary(const char *hexHash, unsigned char *binaryHash)
+{
+    if (hexHash == NULL || binaryHash == NULL) {
+        return PKCS7_INVALID_PARAM;
     }
-    unsigned char *signature = Pkcs7Calloc(RSA3072_SIG_SIZE, sizeof(char));
-    if (!signature) {
-        rc = PKCS7_HAS_NO_SIGNER_CRT;
-        goto exit;
+
+    for (size_t i = 0; i < SHA256_HASH_SIZE; i++) {
+        unsigned int byte = 0;
+        if (sscanf_s(hexHash + i * 2, "%2x", &byte) != 1) {
+            return PKCS7_INVALID_VALUE;
+        }
+        binaryHash[i] = (unsigned char)byte;
     }
-    if (fread(signature, 1, RSA3072_SIG_SIZE, sigFile) != RSA3072_SIG_SIZE) {
-        rc = PKCS7_VERIFY_FAIL;
-        goto exit;
+    return PKCS7_SUCC;
+}
+
+// 解析单行哈希条目
+static int32_t ParseHashLine(const char *line, size_t lineLen, CertHashEntry *entry)
+{
+    if (line == NULL || entry == NULL) {
+        return PKCS7_INVALID_PARAM;
     }
-    mbedtls_sha256(fileData, fileSize, hash, 0);
-    rc = mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256, hash, SHA256_HASH_SIZE, signature, RSA3072_SIG_SIZE);
-    if (rc != 0) {
-        HILOG_ERROR(HILOG_MODULE_AAFWK, "mbedtls_pk_verify failed! return %d\n", rc);
-        goto exit;
+
+    const char *colon = memchr(line, ':', lineLen);
+    if (colon == NULL || colon <= line || colon >= line + lineLen - 1) {
+        return PKCS7_INVALID_VALUE;
     }
-exit:
-    if (file) {
+
+    size_t nameLen = colon - line;
+    size_t hashHexLen = line + lineLen - colon - 1;
+
+    // 跳过可能的回车符
+    if (hashHexLen > 0 && *(colon + hashHexLen) == '\r') {
+        hashHexLen--;
+    }
+
+    if (hashHexLen != 64) {
+        return PKCS7_INVALID_VALUE;
+    }
+
+    // 分配证书名内存
+    entry->certName = Pkcs7Calloc(nameLen + 1, 1);
+    if (entry->certName == NULL) {
+        return PKCS7_MEMORY_EXHAUST;
+    }
+
+    // 复制证书名
+    if (memcpy_s(entry->certName, nameLen + 1, line, nameLen) != EOK) {
+        Pkcs7Free(entry->certName);
+        entry->certName = NULL;
+        return PKCS7_INVALID_VALUE;
+    }
+    entry->certName[nameLen] = '\0';
+
+    // 复制哈希十六进制字符串
+    if (memcpy_s(entry->hashHex, sizeof(entry->hashHex), colon + 1, hashHexLen) != EOK) {
+        Pkcs7Free(entry->certName);
+        entry->certName = NULL;
+        return PKCS7_INVALID_VALUE;
+    }
+    entry->hashHex[hashHexLen] = '\0';
+    entry->hashHexLen = hashHexLen;
+
+    // 转换为二进制哈希
+    return HexHashToBinary(entry->hashHex, entry->hash);
+}
+
+// 十六进制哈希转换为二进制
+/**
+ * 解析哈希列表文本格式(证书文件名:哈希值)
+ * 格式示例:cert.pem:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ */
+int32_t ParseHashListTextFormat(const unsigned char *data, size_t dataLen, CertHashList *hashList)
+{
+    if (data == NULL || dataLen == 0 || hashList == NULL) {
+        return PKCS7_INVALID_PARAM;
+    }
+
+    const char *start = (const char *)data;
+    const char *end = start + dataLen;
+    const char *ptr = start;
+    size_t lineCount = 0;
+
+    // 计算行数
+    while (ptr < end) {
+        const char *lineEnd = memchr(ptr, '\n', end - ptr);
+        if (lineEnd == NULL) {
+            if (ptr < end) lineCount++;
+            break;
+        }
+        if (lineEnd > ptr) lineCount++;
+        ptr = lineEnd + 1;
+    }
+
+    if (lineCount == 0) {
+        return PKCS7_INVALID_VALUE;
+    }
+
+    // 分配内存
+    hashList->entries = Pkcs7Calloc(lineCount, sizeof(CertHashEntry));
+    if (hashList->entries == NULL) {
+        return PKCS7_MEMORY_EXHAUST;
+    }
+    
+    hashList->count = 0;
+    hashList->capacity = lineCount;
+
+    // 解析每行
+    ptr = start;
+    size_t index = 0;
+    
+    while (ptr < end && index < lineCount) {
+        const char *lineEnd = memchr(ptr, '\n', end - ptr);
+        if (lineEnd == NULL) lineEnd = end;
+        
+        size_t lineLen = lineEnd - ptr;
+        if (lineLen > 0) {
+            int32_t rc = ParseHashLine(ptr, lineLen, &hashList->entries[index]);
+            if (rc == PKCS7_SUCC) {
+                hashList->count++;
+                index++;
+            }
+        }
+        ptr = lineEnd + 1;
+    }
+
+    return (hashList->count > 0) ? PKCS7_SUCC : PKCS7_INVALID_VALUE;
+}
+
+static void FreeCertHashList(CertHashList *hashList)
+{
+    if (hashList == NULL) return;
+    
+    if (hashList->entries != NULL) {
+        for (size_t i = 0; i < hashList->count; i++) {
+            if (hashList->entries[i].certName != NULL) {
+                Pkcs7Free(hashList->entries[i].certName);
+                hashList->entries[i].certName = NULL;
+            }
+        }
+        Pkcs7Free(hashList->entries);
+        hashList->entries = NULL;
+    }
+    hashList->count = 0;
+    hashList->capacity = 0;
+}
+
+// 解析hash列表文件内容
+static int32_t ParseHashListContent(const unsigned char *data, size_t dataLen, 
+                                   char ***certNames, unsigned char **certHashes, 
+                                   size_t *certCount)
+{
+    if (data == NULL || dataLen == 0 || certNames == NULL || 
+        certHashes == NULL || certCount == NULL) {
+        return PKCS7_INVALID_PARAM;
+    }
+    HILOG_INFO(HILOG_MODULE_AAFWK, "ParseHashListContent: dataLen=%zu", dataLen);
+    // 简单的行解析逻辑,实际应根据具体格式调整
+    size_t count = 0;
+    const char *start = (const char *)data;
+    const char *end = start + dataLen;
+    
+    // 第一遍:计算行数
+    const char *ptr = start;
+    while (ptr < end) {
+        const char *lineEnd = memchr(ptr, '\n', end - ptr);
+        if (lineEnd == NULL) break;
+        if (lineEnd > ptr) count++;
+        ptr = lineEnd + 1;
+    }
+    HILOG_INFO(HILOG_MODULE_AAFWK, "Found %zu lines in hash list", count);
+    if (count == 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "No valid lines found in hash list");
+        return PKCS7_INVALID_VALUE;
+    }
+    
+    *certNames = Pkcs7Calloc(count, sizeof(char *));
+    *certHashes = Pkcs7Calloc(count, SHA256_HASH_SIZE);
+    if (*certNames == NULL || *certHashes == NULL) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Memory allocation failed for certNames or certHashes");
+        if (*certNames) Pkcs7Free(*certNames);
+        if (*certHashes) Pkcs7Free(*certHashes);
+        return PKCS7_MEMORY_EXHAUST;
+    }
+    
+    // 第二遍:解析每行
+    ptr = start;
+    size_t index = 0;
+    while (ptr < end && index < count) {
+        const char *lineEnd = memchr(ptr, '\n', end - ptr);
+        if (lineEnd == NULL) lineEnd = end;
+        
+        const char *colon = memchr(ptr, ':', lineEnd - ptr);
+        if (colon != NULL && colon > ptr && (lineEnd - colon - 1) >= SHA256_HASH_SIZE) {
+            // 解析证书文件名
+            size_t nameLen = colon - ptr;
+            (*certNames)[index] = Pkcs7Calloc(nameLen + 1, 1);
+            if ((*certNames)[index] == NULL) {
+                // 清理已分配的内存
+                for (size_t i = 0; i < index; i++) {
+                    Pkcs7Free((*certNames)[i]);
+                }
+                Pkcs7Free(*certNames);
+                Pkcs7Free(*certHashes);
+                return PKCS7_MEMORY_EXHAUST;
+            }
+            int ret = memcpy_s((*certNames)[index], nameLen + 1, ptr, nameLen);
+            if (ret != 0) {
+                HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to copy certificate name, error: %d", ret);
+                // 清理已分配的内存
+                Pkcs7Free((*certNames)[index]);
+                for (size_t i = 0; i < index; i++) {
+                    Pkcs7Free((*certNames)[i]);
+                }
+                Pkcs7Free(*certNames);
+                Pkcs7Free(*certHashes);
+                return PKCS7_FILE_OPERATION_FAIL;
+            }
+            (*certNames)[index][nameLen] = '\0';
+            
+            // 解析哈希值
+            ret = memcpy_s(&(*certHashes)[index * SHA256_HASH_SIZE], SHA256_HASH_SIZE, colon + 1, SHA256_HASH_SIZE);
+            if (ret != 0) {
+                HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to copy certificate hash, error: %d", ret);
+                // 清理已分配的内存
+                Pkcs7Free((*certNames)[index]);
+                for (size_t i = 0; i < index; i++) {
+                    Pkcs7Free((*certNames)[i]);
+                }
+                Pkcs7Free(*certNames);
+                Pkcs7Free(*certHashes);
+                return PKCS7_FILE_OPERATION_FAIL;
+            }
+            index++;
+        }
+        
+        ptr = lineEnd + 1;
+    }
+    
+    *certCount = index;
+    return PKCS7_SUCC;
+}
+
+// 读取哈希列表文件
+static int32_t ReadHashListFile(const char *hashListFile, unsigned char **fileData, long *fileSize)
+{
+    FILE *file = NULL;
+    int32_t rc = PKCS7_SUCC;
+
+    if (hashListFile == NULL || fileData == NULL || fileSize == NULL) {
+        return PKCS7_INVALID_PARAM;
+    }
+
+    file = fopen(hashListFile, "rb");
+    if (!file) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open hash list file: %s", hashListFile);
+        return PKCS7_FILE_OPERATION_FAIL;
+    }
+
+    if (fseek(file, 0, SEEK_END) != 0) {
+        fclose(file);
+        return PKCS7_FILE_OPERATION_FAIL;
+    }
+    
+    *fileSize = ftell(file);
+    if (fseek(file, 0, SEEK_SET) != 0 || *fileSize <= 0) {
+        fclose(file);
+        return PKCS7_FILE_OPERATION_FAIL;
+    }
+    
+    *fileData = Pkcs7Calloc(*fileSize + 1, sizeof(char));
+    if (*fileData == NULL) {
         fclose(file);
-        file = NULL;
+        return PKCS7_MEMORY_EXHAUST;
+    }
+    
+    size_t bytesRead = fread(*fileData, 1, *fileSize, file);
+    fclose(file);
+    
+    if (bytesRead != (size_t)*fileSize) {
+        Pkcs7Free(*fileData);
+        *fileData = NULL;
+        return PKCS7_FILE_OPERATION_FAIL;
     }
-    if (sigFile) {
+    
+    (*fileData)[*fileSize] = '\0';
+    return PKCS7_SUCC;
+}
+
+// 读取签名文件
+static int32_t ReadSignatureFile(const char *signatureFile, unsigned char **signature)
+{
+    FILE *sigFile = NULL;
+    
+    if (signatureFile == NULL || signature == NULL) {
+        return PKCS7_INVALID_PARAM;
+    }
+
+    sigFile = fopen(signatureFile, "rb");
+    if (!sigFile) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open signature file: %s", signatureFile);
+        return PKCS7_FILE_OPERATION_FAIL;
+    }
+
+    *signature = Pkcs7Calloc(RSA3072_SIG_SIZE, sizeof(char));
+    if (*signature == NULL) {
         fclose(sigFile);
-        sigFile = NULL;
+        return PKCS7_MEMORY_EXHAUST;
+    }
+
+    size_t sigLen = fread(*signature, 1, RSA3072_SIG_SIZE, sigFile);
+    fclose(sigFile);
+    
+    if (sigLen != RSA3072_SIG_SIZE) {
+        Pkcs7Free(*signature);
+        *signature = NULL;
+        return PKCS7_FILE_OPERATION_FAIL;
+    }
+    
+    return PKCS7_SUCC;
+}
+
+// 验证哈希列表签名
+static int32_t VerifyHashListSignature(const unsigned char *fileData, long fileSize, 
+                                      const unsigned char *signature)
+{
+    mbedtls_pk_context pk;
+    unsigned char hash[SHA256_HASH_SIZE];
+    int32_t rc;
+
+    if (fileData == NULL || fileSize <= 0 || signature == NULL) {
+        return PKCS7_INVALID_PARAM;
     }
+
+    mbedtls_pk_init(&pk);
+    
+    rc = mbedtls_pk_parse_public_key(&pk, (const unsigned char *)ROOT_CA_OEM_PUBKEY_IN_PEM,
+        strlen(ROOT_CA_OEM_PUBKEY_IN_PEM) + 1);
+    if (rc != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Public key parsing failed: -0x%04X", -rc);
+        mbedtls_pk_free(&pk);
+        return PKCS7_INVALID_PARAM;
+    }
+
+    // 设置RSA填充模式
+    if (mbedtls_pk_get_type(&pk) == MBEDTLS_PK_RSA) {
+        mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
+        mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
+    }
+
+    rc = mbedtls_sha256(fileData, fileSize, hash, 0);
+    if (rc != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "SHA256 calculation failed: -0x%04X", -rc);
+        mbedtls_pk_free(&pk);
+        return rc;
+    }
+
+    rc = mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256, hash, SHA256_HASH_SIZE, 
+                          signature, RSA3072_SIG_SIZE);
+    if (rc != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Signature verification failed: -0x%04X", -rc);
+    }
+    
+    mbedtls_pk_free(&pk);
+    return (rc == 0) ? PKCS7_SUCC : rc;
+}
+
+static int32_t VerifyAndCacheHashList(CertVerifyCache *cache)
+{
+    int32_t rc = 0;
+    const char *hashListFile = OEM_CERT_PATH"root_cert_hash_list.bin";
+    const char *signatureFile = OEM_CERT_PATH"hash_list_sign.bin";
+    unsigned char *fileData = NULL;
+    unsigned char *signature = NULL;
+    unsigned char *cachedData = NULL;
+    long fileSize = 0;
+
+    if (cache == NULL) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Invalid cache parameter");
+        return PKCS7_INVALID_PARAM;
+    }
+
+    // 检查缓存是否仍然有效
+    if (g_cacheValid && cache->hashListData != NULL) {
+        struct stat st;
+        if (stat(hashListFile, &st) == 0 && st.st_mtime <= cache->verifyTime) {
+            HILOG_INFO(HILOG_MODULE_AAFWK, "Using cached hash list verification");
+            return PKCS7_SUCC;
+        }
+    }
+    
+    // 清除旧缓存
+    FreeCertVerifyCache(cache);
+
+    // 读取哈希列表文件
+    rc = ReadHashListFile(hashListFile, &fileData, &fileSize);
+    if (rc != PKCS7_SUCC) {
+        goto cleanup;
+    }
+
+    // 读取签名文件
+    rc = ReadSignatureFile(signatureFile, &signature);
+    if (rc != PKCS7_SUCC) {
+        goto cleanup;
+    }
+
+    // 验证签名
+    rc = VerifyHashListSignature(fileData, fileSize, signature);
+    if (rc != PKCS7_SUCC) {
+        goto cleanup;
+    }
+
+    // 创建缓存数据的副本
+    cachedData = Pkcs7Calloc(fileSize + 1, sizeof(char));
+    if (cachedData == NULL) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Memory allocation failed for cache data");
+        rc = PKCS7_MEMORY_EXHAUST;
+        goto cleanup;
+    }
+    
+    if (memcpy_s(cachedData, fileSize + 1, fileData, fileSize) != EOK) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to copy cache data");
+        rc = PKCS7_INVALID_VALUE;
+        goto cleanup;
+    }
+    cachedData[fileSize] = '\0';
+
+    // 设置缓存
+    cache->hashListData = cachedData;
+    cache->hashListSize = fileSize;
+    cache->verifyTime = time(NULL);
+    
+    if (strcpy_s(cache->certDirPath, sizeof(cache->certDirPath), OEM_CERT_PATH) != EOK) {
+        HILOG_WARN(HILOG_MODULE_AAFWK, "Failed to copy certificate directory path");
+    }
+    
+    g_cacheValid = true;
+    cachedData = NULL; // 所有权转移给cache,避免重复释放
+
+    HILOG_INFO(HILOG_MODULE_AAFWK, "Hash list verification successful");
+
+cleanup:
     if (fileData) {
         Pkcs7Free(fileData);
         fileData = NULL;
@@ -999,10 +1465,12 @@ exit:
         Pkcs7Free(signature);
         signature = NULL;
     }
-    mbedtls_pk_free(&pk);
+    if (cachedData) {
+        Pkcs7Free(cachedData);
+        cachedData = NULL;
+    }
     return rc;
 }
-#endif
 
 /* valid digest alg now: sha256 sha384 sha512 */
 static bool InvalidDigestAlg(const mbedtls_asn1_buf *alg)
@@ -1012,8 +1480,8 @@ static bool InvalidDigestAlg(const mbedtls_asn1_buf *alg)
         MBEDTLS_OID_CMP(MBEDTLS_OID_DIGEST_ALG_SHA512, alg);
 }
 
-static int32_t GetContentInfoType(unsigned char **p, const unsigned char *end, mbedtls_asn1_buf *contentType,
-    bool *hasContent)
+static int32_t GetContentInfoType(unsigned char **p, const unsigned char *end,
+                              mbedtls_asn1_buf *contentType, bool *hasContent)
 {
     size_t seqLen = 0;
     size_t len = 0;
@@ -1272,36 +1740,36 @@ static int32_t ParseSignedDataSignerInfos(unsigned char **p, const unsigned char
         unsigned char *oneSignerEnd = NULL;
         /* parse one signer info */
         rc = mbedtls_asn1_get_tag(p, end, &oneSignerLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
-        PKCS7_ERR_GOTO_OUT(rc);
+        PKCS7_ERR_RETURN_WITH_LOG(rc);
 
         oneSignerEnd = *p + oneSignerLen;
         /* parse version */
         rc = ParseSignerVersion(p, oneSignerEnd, signers);
-        PKCS7_ERR_GOTO_OUT(rc);
+        PKCS7_ERR_RETURN_WITH_LOG(rc);
 
         /* parse issuerAndSerialNum */
         rc = ParseSignerIssuerAndSerialNum(p, oneSignerEnd, signers);
-        PKCS7_ERR_GOTO_OUT(rc);
+        PKCS7_ERR_RETURN_WITH_LOG(rc);
 
         /* parse digestAlgorithm */
         rc = ParseSignerDigestAlg(p, oneSignerEnd, signers);
-        PKCS7_ERR_GOTO_OUT(rc);
+        PKCS7_ERR_RETURN_WITH_LOG(rc);
 
         /* parse authenticatedAttributes */
         rc = ParseSignerAuthAttr(p, oneSignerEnd, signers);
-        PKCS7_ERR_GOTO_OUT(rc);
+        PKCS7_ERR_RETURN_WITH_LOG(rc);
 
         /* parse digestEncryptionAlgorithm */
         rc = ParseSignerEncAlg(p, oneSignerEnd, signers);
-        PKCS7_ERR_GOTO_OUT(rc);
+        PKCS7_ERR_RETURN_WITH_LOG(rc);
 
         /* parse encryptedDigest */
         rc = ParseSignerSignature(p, oneSignerEnd, signers);
-        PKCS7_ERR_GOTO_OUT(rc);
+        PKCS7_ERR_RETURN_WITH_LOG(rc);
 
         /* parse unauthenticatedAttributes */
         rc = ParseSignerUnAuthAttr(p, oneSignerEnd, signers);
-        PKCS7_ERR_GOTO_OUT(rc);
+        PKCS7_ERR_RETURN_WITH_LOG(rc);
 
         if (*p < end) {
             signers->next = Pkcs7Calloc(1, sizeof(*signers));
@@ -1484,71 +1952,249 @@ static mbedtls_x509_crt *FindSuperCert(mbedtls_x509_crt *cur, mbedtls_x509_crt *
     return certsList;
 }
 
-static int32_t LoadSelfSignedCert(void)
+// 验证单个证书文件
+static int32_t VerifyCertificateFile(const char *certPath, const unsigned char *expectedHash, 
+                                   mbedtls_x509_crt *topCert)
 {
-    mbedtls_x509_crt_init(&g_ohosRootCert);
-    int32_t rc = mbedtls_x509_crt_parse(&g_ohosRootCert, OHOS_ROOT_CERT_IN_PEM, sizeof(OHOS_ROOT_CERT_IN_PEM));
-    if (rc) {
-        HILOG_ERROR(HILOG_MODULE_AAFWK,"load oh signed ca failed %d", rc);
+    unsigned char actualHash[SHA256_HASH_SIZE];
+    char actualHashHex[65];
+    int32_t rc;
+
+    if (certPath == NULL || expectedHash == NULL || topCert == NULL) {
+        return PKCS7_INVALID_PARAM;
+    }
+
+    // 计算文件哈希
+    rc = CalculateFileSha256(certPath, actualHash, actualHashHex);
+    if (rc != PKCS7_SUCC) {
         return rc;
-    } else {
-        HILOG_INFO(HILOG_MODULE_AAFWK,"load oh signed root ca success");
     }
-    return rc;
+
+    // 比较哈希值
+    if (memcmp(actualHash, expectedHash, SHA256_HASH_SIZE) != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Certificate hash verification failed for: %s", certPath);
+        return PKCS7_INVALID_VALUE;
+    }
+
+    // 解析证书
+    mbedtls_x509_crt tmpCert;
+    mbedtls_x509_crt_init(&tmpCert);
+    
+    rc = mbedtls_x509_crt_parse_file(&tmpCert, certPath);
+    if (rc != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to parse certificate: %s, error: -0x%04X", certPath, -rc);
+        mbedtls_x509_crt_free(&tmpCert);
+        return rc;
+    }
+
+    // 检查证书匹配
+    int32_t match = CompareX509NameList(&tmpCert.subject, &topCert->issuer);
+    mbedtls_x509_crt_free(&tmpCert);
+    
+    return (match == 0) ? PKCS7_SUCC : PKCS7_INVALID_VALUE;
 }
 
-static int32_t FindAndStoreRootCert(mbedtls_x509_crt *topCert)
+// 加载根证书
+static int32_t LoadRootCertificate(const char *certPath)
 {
-    int32_t rc = PKCS7_PARSING_ERROR;
-    DIR *dir = NULL;
-    struct dirent *entry = NULL;
-    char certPath[MAX_CERTPATH_LEN];
-    if (access(OEM_CERT_PATH, F_OK) != 0) {
-        HILOG_DEBUG(HILOG_MODULE_AAFWK, "Please upload the application root certificate.");
-        return LoadSelfSignedCert();
+    if (certPath == NULL) {
+        return PKCS7_INVALID_PARAM;
     }
-    dir = opendir(OEM_CERT_PATH);
-    if (dir == NULL) {
-        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open certificate directory.");
-        return PKCS7_BUILD_CERT_PATH_FAIL;
+
+    mbedtls_x509_crt_free(&g_ohosRootCert);
+    mbedtls_x509_crt_init(&g_ohosRootCert);
+    
+    int32_t rc = mbedtls_x509_crt_parse_file(&g_ohosRootCert, certPath);
+    if (rc != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to load root certificate: %s, error: -0x%04X", certPath, -rc);
+        return PKCS7_HAS_NO_SIGNER_CRT;
+    }
+    
+    return PKCS7_SUCC;
+}
+
+// 辅助函数
+static bool ShouldSkipFile(const struct dirent *entry)
+{
+    if (entry == NULL) {
+        return true;
+    }
+    
+    return (strcmp(entry->d_name, ".") == 0 || 
+            strcmp(entry->d_name, "..") == 0 ||
+            strstr(entry->d_name, ".pem") == NULL);
+}
+
+static const CertHashEntry *FindHashEntry(const CertHashList *hashList, const char *fileName)
+{
+    if (hashList == NULL || fileName == NULL) {
+        return NULL;
+    }
+
+    for (size_t i = 0; i < hashList->count; i++) {
+        if (hashList->entries[i].certName != NULL && 
+            strcmp(fileName, hashList->entries[i].certName) == 0) {
+            return &hashList->entries[i];
+        }
+    }
+    return NULL;
+}
+
+// 扫描证书目录
+static int32_t ScanCertificateDirectory(DIR *dir, const CertHashList *hashList, 
+                                       mbedtls_x509_crt *topCert)
+{
+    struct dirent *entry;
+    char certPath[MAX_CERTPATH_LEN];
+    int32_t rc = PKCS7_PARSING_ERROR;
+
+    if (dir == NULL || hashList == NULL || topCert == NULL) {
+        return PKCS7_INVALID_PARAM;
     }
+
     while ((entry = readdir(dir)) != NULL) {
-        const char *ext = strrchr(entry->d_name, '.');
-        if (ext == NULL || strcmp(ext, ".pem") != 0) {
+        if (ShouldSkipFile(entry)) {
             continue;
         }
-        rc = snprintf_s(certPath, sizeof(certPath), sizeof(certPath) - 1, OEM_CERT_PATH"%s", entry->d_name);
-        if (rc < 0) {
-            HILOG_ERROR(HILOG_MODULE_AAFWK, "Get cert path failed, return %d!", rc);
+
+        // 构建证书路径
+        if (snprintf_s(certPath, sizeof(certPath), sizeof(certPath) - 1, 
+                      "%s%s", OEM_CERT_PATH, entry->d_name) < 0) {
             continue;
         }
-        mbedtls_x509_crt tmpRootCert;
-        mbedtls_x509_crt_init(&tmpRootCert);
-        rc = mbedtls_x509_crt_parse_file(&tmpRootCert, certPath);
-        if (rc != 0) {
-            HILOG_ERROR(HILOG_MODULE_AAFWK, "Parse %s failed: %d.", certPath, rc);
-            mbedtls_x509_crt_free(&tmpRootCert);
+
+        // 查找匹配的哈希条目
+        const CertHashEntry *hashEntry = FindHashEntry(hashList, entry->d_name);
+        if (hashEntry == NULL) {
             continue;
         }
-        /* Compare the subject of the device root certificate and the issuer of the uppermost certificate. */
-        if (CompareX509NameList(&tmpRootCert.subject, &topCert->issuer) == 0) {
-            HILOG_INFO(HILOG_MODULE_AAFWK, "Found matching root cert: %s.", entry->d_name);
-            /* Reparse the root certificate to g_ohosRootCert. */
-            rc = mbedtls_x509_crt_parse_file(&g_ohosRootCert, certPath);
-            if (rc != 0) {
-                HILOG_ERROR(HILOG_MODULE_AAFWK, "Re-parsing root cert failed: %d!", rc);
-                mbedtls_x509_crt_free(&tmpRootCert);
-                closedir(dir);
-                return PKCS7_HAS_NO_SIGNER_CRT;
+
+        // 验证证书文件
+        rc = VerifyCertificateFile(certPath, hashEntry->hash, topCert);
+        if (rc == PKCS7_SUCC) {
+            // 加载根证书
+            rc = LoadRootCertificate(certPath);
+            if (rc == PKCS7_SUCC) {
+                break;
             }
-            rc = PKCS7_SUCC;
-            mbedtls_x509_crt_free(&tmpRootCert);
-            break;
         }
-        mbedtls_x509_crt_free(&tmpRootCert);
     }
 
+    return rc;
+}
+
+// 检查证书路径是否可用
+bool IsCertPathAvailable(void)
+{
+    struct stat st;
+    if (stat(OEM_CERT_PATH, &st) != 0) {
+        HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate path does not exist: %s", OEM_CERT_PATH);
+        return false;
+    }
+    
+    if (!S_ISDIR(st.st_mode)) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Certificate path is not a directory: %s", OEM_CERT_PATH);
+        return false;
+    }
+    
+    // 检查目录是否可读
+    if (access(OEM_CERT_PATH, 0) != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Certificate directory is not readable: %s", OEM_CERT_PATH);
+        return false;
+    }
+    
+    return true;
+}
+
+// 加载内置证书
+static int32_t LoadSelfSignedCert(void)
+{
+    mbedtls_x509_crt_free(&g_ohosRootCert);
+    mbedtls_x509_crt_init(&g_ohosRootCert);
+
+    HILOG_INFO(HILOG_MODULE_AAFWK, "Loading built-in OpenHarmony root certificate");
+
+    // 规范化证书格式:将\r\n转换为\n
+    size_t certLen = strlen((const char*)OHOS_ROOT_CERT_IN_PEM);
+    char *normalizedCert = Pkcs7Calloc(certLen + 1, 1);
+    if (normalizedCert == NULL) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Memory allocation failed for certificate normalization");
+        return PKCS7_MEMORY_EXHAUST;
+    }
+
+    // 复制并替换换行符
+    const char *src = (const char*)OHOS_ROOT_CERT_IN_PEM;
+    char *dst = normalizedCert;
+    while (*src) {
+        if (src[0] == '\r' && src[1] == '\n') {
+            *dst++ = '\n';
+            src += 2; // 跳过\r\n
+        } else {
+            *dst++ = *src++;
+        }
+    }
+    *dst = '\0';
+
+    int32_t rc = mbedtls_x509_crt_parse(&g_ohosRootCert, (const unsigned char*)normalizedCert, 
+                                       strlen(normalizedCert) + 1);
+
+    Pkcs7Free(normalizedCert);
+
+    if (rc != 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to parse built-in certificate: -0x%04X", -rc);
+        return PKCS7_HAS_NO_SIGNER_CRT;
+    }
+    
+    HILOG_INFO(HILOG_MODULE_AAFWK, "Built-in certificate loaded successfully with normalized line endings");
+    return PKCS7_SUCC;
+}
+
+static int32_t FindAndStoreRootCertWithCache(mbedtls_x509_crt *topCert, CertVerifyCache *cache)
+{
+    if (topCert == NULL) {
+        return PKCS7_INVALID_PARAM;
+    }
+
+    // 如果缓存无效,先验证哈希列表
+    if (cache == NULL || cache->hashListData == NULL) {
+        HILOG_INFO(HILOG_MODULE_AAFWK, "Cache invalid, verifying hash list");
+        int32_t rc = VerifyAndCacheHashList(cache);
+        if (rc != PKCS7_SUCC) {
+            HILOG_ERROR(HILOG_MODULE_AAFWK, "Hash list verification failed: %d", rc);
+            return rc;
+        }
+    }
+
+    CertHashList hashList = {0};
+    DIR *dir = NULL;
+    int32_t rc = PKCS7_PARSING_ERROR;
+
+    // 解析哈希列表
+    rc = ParseHashListTextFormat(cache->hashListData, cache->hashListSize, &hashList);
+    if (rc != PKCS7_SUCC || hashList.count == 0) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to parse hash list or no entries found");
+        FreeCertHashList(&hashList);
+        return PKCS7_INVALID_VALUE;
+    }
+
+    // 打开证书目录
+    dir = opendir(OEM_CERT_PATH);
+    if (dir == NULL) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to open certificate directory: %s", OEM_CERT_PATH);
+        FreeCertHashList(&hashList);
+        return PKCS7_BUILD_CERT_PATH_FAIL;
+    }
+
+    // 扫描证书文件
+    rc = ScanCertificateDirectory(dir, &hashList, topCert);
+
     closedir(dir);
+    FreeCertHashList(&hashList);
+    
+    if (rc != PKCS7_SUCC) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to find matching root certificate");
+    }
+    
     return rc;
 }
 
@@ -1557,7 +2203,7 @@ static int32_t LoadRootCert()
     int32_t rc = 0;
     if (!g_rootCertLoaded) {
         mbedtls_x509_crt_init(&g_rootCaG2Cert);
-        rc = mbedtls_x509_crt_parse(&g_rootCaG2Cert, g_rootCaG2CertInPem, sizeof(g_rootCaG2CertInPem));
+        rc = mbedtls_x509_crt_parse(&g_rootCaG2Cert, ROOT_CA_G2_CERT_IN_PEM, sizeof(ROOT_CA_G2_CERT_IN_PEM));
         if (rc) {
             HILOG_ERROR(HILOG_MODULE_AAFWK, "load root ca failed!");
             return rc;
@@ -1580,8 +2226,8 @@ static void UnLoadRootCert(void)
 static int32_t LoadDebugModeRootCert(void)
 {
     mbedtls_x509_crt_init(&g_debugModeRootCert);
-    int32_t rc = mbedtls_x509_crt_parse(&g_debugModeRootCert, g_debugModeRootCertInPem,
-        sizeof(g_debugModeRootCertInPem));
+    int32_t rc = mbedtls_x509_crt_parse(&g_debugModeRootCert, DEBUG_MODE_ROOT_CERT_IN_PEM,
+        sizeof(DEBUG_MODE_ROOT_CERT_IN_PEM));
     if (rc) {
         HILOG_ERROR(HILOG_MODULE_AAFWK, "load debug mode root ca failed %d", rc);
         return rc;
@@ -1608,7 +2254,6 @@ static mbedtls_x509_crt *GetLowLevelCerts(SignedData *signedData)
     mbedtls_x509_buf *signerSerial = &signer->serial;
     mbedtls_x509_name *signerIssuer = &signer->issuer;
     mbedtls_x509_crt *cert = signedData->certs;
-    HILOG_INFO(HILOG_MODULE_AAFWK, "To filter one signer's cert");
     while (cert != NULL) {
         if (SerialCmp(signerSerial, &cert->serial) == 0 &&
             CompareX509NameList(signerIssuer, &cert->issuer) == 0) {
@@ -1793,51 +2438,90 @@ static void AddCertToSignerCertPath(SignerInfo *signer, mbedtls_x509_crt *crt)
     signer->certPath.depth++;
 }
 
-static int32_t BuildSignerCertPath(SignerInfo *signer, mbedtls_x509_crt *lowerCrt, SignedData *signeData)
+static int32_t BuildSignerCertPath(SignerInfo *signer, mbedtls_x509_crt *lowerCrt, SignedData *signedData)
 {
+    if (signer == NULL || lowerCrt == NULL || signedData == NULL) {
+        return PKCS7_INVALID_PARAM;
+    }
+    
+    HILOG_INFO(HILOG_MODULE_AAFWK, "Building certificate path");
+    
     int32_t scanCnt = 0;
     int32_t rc = PKCS7_SUCC;
+    
+    // 确保根证书已加载
     if (!g_rootCertLoaded) {
-        return PKCS7_ROOT_CA_NOT_VALID;
+        rc = LoadRootCert();
+        if (rc != PKCS7_SUCC) {
+            HILOG_ERROR(HILOG_MODULE_AAFWK, "Root certificate not loaded: %d", rc);
+            return PKCS7_ROOT_CA_NOT_VALID;
+        }
     }
+    
+    // 设置默认根证书
     signer->rootCert = &g_rootCaG2Cert;
 
-    mbedtls_x509_crt *certs = signeData->certs;
-    /* From the root ca cert, to found the signer secondary ca , and use secondary cert to
-     * find the next level ca cert */
+    mbedtls_x509_crt *certs = signedData->certs;
+    if (certs == NULL) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "No certificates in signed data");
+        return PKCS7_INVALID_VALUE;
+    }
+    
     mbedtls_x509_crt *cur = lowerCrt;
     mbedtls_x509_crt *next = NULL;
     int32_t certsCnt = GetCertsNumOfSignedData(certs);
-    DelCertOfSignedData(signeData, cur);
+    
+    HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate chain has %d certificates", certsCnt);
+    
+    DelCertOfSignedData(signedData, cur);
     AddCertToSignerCertPath(signer, cur);
+    
     while (true) {
-        next = FindSuperCert(cur, signeData->certs);
+        next = FindSuperCert(cur, signedData->certs);
         if (next == NULL) {
-            mbedtls_x509_crt_init(&g_ohosRootCert);
-            rc = FindAndStoreRootCert(cur);
-            if (rc == 0) {
-                HILOG_INFO(HILOG_MODULE_AAFWK, "load self signed root ca success");
+            HILOG_INFO(HILOG_MODULE_AAFWK, "Reached top of certificate chain");
+            
+            // 根据路径可用性选择证书源
+            if (IsCertPathAvailable()) {
+                HILOG_INFO(HILOG_MODULE_AAFWK, "Using local certificate path for root certificate");
+                rc = FindAndStoreRootCertWithCache(cur, &g_certCache);
             } else {
-                HILOG_ERROR(HILOG_MODULE_AAFWK, "load self signed ca failed %d", rc);
+                HILOG_INFO(HILOG_MODULE_AAFWK, "Using built-in OpenHarmony root certificate");
+                rc = LoadSelfSignedCert();
+                if (rc == PKCS7_SUCC) {
+                    // 设置签名者的根证书为内置证书
+                    signer->rootCert = &g_ohosRootCert;
+                }
+            }
+            
+            if (rc != PKCS7_SUCC) {
+                HILOG_ERROR(HILOG_MODULE_AAFWK, "Failed to load root certificate: %d", rc);
             }
             break;
         } else {
-            DelCertOfSignedData(signeData, next);
+            DelCertOfSignedData(signedData, next);
             AddCertToSignerCertPath(signer, next);
         }
+        
         scanCnt++;
         if (scanCnt > certsCnt) {
+            HILOG_ERROR(HILOG_MODULE_AAFWK, "Certificate chain scanning exceeded limit");
             rc = PKCS7_BUILD_CERT_PATH_FAIL;
             break;
         }
         cur = next;
     }
+    
+    HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate path building completed: %d", rc);
     return rc;
 }
 
 static int32_t ConstructSignerCerts(SignedData *signedData)
 {
-    /* scan all of the signers , and filter the signer's certs by serial and name */
+    if (signedData == NULL) {
+        return PKCS7_INVALID_PARAM;
+    }
+    
     SignerInfo *signer = &signedData->signers;
     while (signer != NULL) {
         mbedtls_x509_crt *cert = GetLowLevelCerts(signedData);
@@ -1845,14 +2529,17 @@ static int32_t ConstructSignerCerts(SignedData *signedData)
             HILOG_ERROR(HILOG_MODULE_AAFWK, "Could not found signer's lowest cert");
             return PKCS7_INVALID_VALUE;
         }
+        
+        // 根据路径可用性构建证书路径
         int32_t rc = BuildSignerCertPath(signer, cert, signedData);
-        if (rc != 0) {
+        if (rc != PKCS7_SUCC) {
+            HILOG_ERROR(HILOG_MODULE_AAFWK, "Build signer certificate path failed: %d", rc);
             return rc;
         }
 
         signer = signer->next;
     }
-    return 0;
+    return PKCS7_SUCC;
 }
 
 /* get signer digest alg */
@@ -1986,7 +2673,7 @@ static int32_t VerifyCrl(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *cr
 
 static int32_t VerifyClicert(mbedtls_x509_crt *clicert, mbedtls_x509_crt *rootCert, const Pkcs7 *pkcs7)
 {
-    uint32_t flags;
+    uint32_t flags = 0;
     int32_t rc = mbedtls_x509_crt_verify(clicert, rootCert,
         (mbedtls_x509_crl *)&pkcs7->signedData.crl, NULL, &flags, NULL, NULL);
     if (rc) {
@@ -2007,47 +2694,49 @@ int32_t PKCS7_VerifyCertsChain(const Pkcs7 *pkcs7)
     if (pkcs7 == NULL) {
         return PKCS7_INVALID_PARAM;
     }
+    
     int32_t cnt = 0;
     const SignerInfo *signer = &pkcs7->signedData.signers;
+    
     while (signer != NULL) {
         mbedtls_x509_crt *clicert = signer->certPath.crt;
         if (clicert == NULL) {
-            HILOG_ERROR(HILOG_MODULE_AAFWK, "Signer has no certs");
+            HILOG_ERROR(HILOG_MODULE_AAFWK, "Signer has no certificates");
             return PKCS7_HAS_NO_SIGNER_CRT;
         }
+
         int32_t rc;
         cnt++;
-        HILOG_INFO(HILOG_MODULE_AAFWK, "signer : %d", cnt);
+
         if (g_debugModeEnabled) {
             rc = VerifyClicert(clicert, &g_debugModeRootCert, pkcs7);
-            HILOG_DEBUG(HILOG_MODULE_AAFWK, "Verify inner: %d", rc);
             if (rc == PKCS7_SUCC) {
                 signer = signer->next;
                 continue;
             }
-            if (rc == PKCS7_IS_REVOKED) {
-                return PKCS7_IS_REVOKED;
-            }
+            HILOG_WARN(HILOG_MODULE_AAFWK, "Debug mode verification failed");
         }
-        rc = VerifyClicert(clicert, signer->rootCert, pkcs7);
-        HILOG_DEBUG(HILOG_MODULE_AAFWK, "Verify : %d", rc);
+#ifndef OHOS_SIGN_HAPS_BY_SERVER
+        // 首先尝试使用内置OpenHarmony根证书
+        rc = VerifyClicert(clicert, &g_ohosRootCert, pkcs7);
         if (rc == PKCS7_SUCC) {
             signer = signer->next;
             continue;
         }
-        if (rc == PKCS7_IS_REVOKED) {
-            return PKCS7_IS_REVOKED;
-        }
-#ifndef OHOS_SIGN_HAPS_BY_SERVER
-        rc = VerifyClicert(clicert, &g_ohosRootCert, pkcs7);
-        HILOG_DEBUG(HILOG_MODULE_AAFWK, "Verify self : %d", rc);
+#endif
+        // 如果内置证书验证失败,尝试系统根证书
+        HILOG_WARN(HILOG_MODULE_AAFWK, "Built-in certificate failed, trying system root certificate");
+        rc = VerifyClicert(clicert, &g_rootCaG2Cert, pkcs7);
         if (rc == PKCS7_SUCC) {
+            HILOG_INFO(HILOG_MODULE_AAFWK, "System root certificate verification successful");
             signer = signer->next;
             continue;
         }
-#endif
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "All certificate verification attempts failed: %d", rc);
         return rc;
     }
+    
+    HILOG_INFO(HILOG_MODULE_AAFWK, "All certificate chains verified successfully");
     return PKCS7_SUCC;
 }
 
@@ -2292,6 +2981,39 @@ static int32_t ParsePemFormatSignedData(const unsigned char *buf, size_t bufLen,
 }
 #endif
 
+// 统一的证书加载入口
+static int32_t CheckAndLoadCertificates(void)
+{
+    static bool certificatesLoaded = false;
+    static int32_t lastLoadResult = PKCS7_SUCC;
+    
+    // 如果已经加载过且成功,直接返回缓存结果
+    if (certificatesLoaded) {
+        return lastLoadResult;
+    }
+    
+    int32_t rc = PKCS7_SUCC;
+    
+    if (IsCertPathAvailable()) {
+        HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate path available, verifying hash list");
+        rc = VerifyAndCacheHashList(&g_certCache);
+        if (rc != PKCS7_SUCC) {
+            HILOG_ERROR(HILOG_MODULE_AAFWK, "Hash list verification failed, falling back to built-in certificate");
+            // 验证失败时回退到内置证书
+            rc = LoadSelfSignedCert();
+        }
+    } else {
+        HILOG_INFO(HILOG_MODULE_AAFWK, "Certificate path not available, using built-in certificate");
+        // 清理可能存在的旧缓存
+        FreeCertVerifyCache(&g_certCache);
+        rc = LoadSelfSignedCert();
+    }
+    
+    certificatesLoaded = true;
+    lastLoadResult = rc;
+    return rc;
+}
+
 int32_t PKCS7_ParseSignedData(const unsigned char *buf, size_t bufLen, Pkcs7 *pkcs7)
 {
     int32_t rc;
@@ -2299,55 +3021,67 @@ int32_t PKCS7_ParseSignedData(const unsigned char *buf, size_t bufLen, Pkcs7 *pk
     bool hasContent = false;
     unsigned char *start = NULL;
     unsigned char *end = NULL;
+    
     if (buf == NULL || bufLen == 0 || pkcs7 == NULL) {
         return PKCS7_INVALID_PARAM;
     }
+    
     (void)memset_s(pkcs7, sizeof(*pkcs7), 0, sizeof(*pkcs7));
+
+    HILOG_INFO(HILOG_MODULE_AAFWK, "Starting PKCS7 parsing, bufLen=%zu", bufLen);
+
     start = (unsigned char *)buf;
-#ifdef PARSE_PEM_FORMAT_SIGNED_DATA
-    char format = 0;
-    rc = ParsePemFormatSignedData(buf, bufLen, &pkcs7->pem, &format);
-    if (rc) {
-        goto EXIT;
-    }
-    if (format == PEM_FORMAT_SINGED_DATA) {
-        start = pkcs7->pem.MBEDTLS_PRIVATE(buf);
-        bufLen = pkcs7->pem.MBEDTLS_PRIVATE(buflen);
-    }
-#endif
-#ifdef MARKET_ENABLE
-    if (access(OEM_CERT_PATH, F_OK) == 0) {
-        rc = VerifyHashList();
-        P_ERR_GOTO_WTTH_LOG(rc);
-    }
-#endif
-    /* loaded the c2 root ca cert */
-    rc = LoadRootCert();
-    P_ERR_GOTO_WTTH_LOG(rc);
-    HILOG_INFO(HILOG_MODULE_AAFWK, "Begin to parse pkcs#7 signed data");
     end = start + bufLen;
-    /* parse the ContentInfo total head */
+
+    // 先解析PKCS7数据,再处理证书
+    HILOG_INFO(HILOG_MODULE_AAFWK, "Begin to parse pkcs#7 signed data");
+
+    // 解析ContentInfo头部
     rc = GetContentInfoType(&start, end, &(pkcs7->contentTypeOid), &hasContent);
-    P_ERR_GOTO_WTTH_LOG(rc);
+    if (rc != PKCS7_SUCC) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Get content info type failed: %d", rc);
+        goto exit;
+    }
+    
     if (!IsSigedDataOid(pkcs7) || !hasContent) {
         rc = PKCS7_INVALID_CONTENT_TYPE_OR_NO_CONTENT;
         HILOG_ERROR(HILOG_MODULE_AAFWK, "Input data is not pkcs#7 signed data format or has no content info");
-        goto EXIT;
+        goto exit;
     }
+    
     rc = GetContentLenOfContentInfo(&start, end, &len);
-    P_ERR_GOTO_WTTH_LOG(rc);
+    if (rc != PKCS7_SUCC) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Get content length failed: %d", rc);
+        goto exit;
+    }
+    
     if (start + len > end) {
         rc = PKCS7_INVALID_CONTENT_TYPE_OR_NO_CONTENT;
         HILOG_ERROR(HILOG_MODULE_AAFWK, "The length of input data is invalid");
-        goto EXIT;
+        goto exit;
     }
+    
     rc = ParseSignedData(start, len, &(pkcs7->signedData));
-    P_ERR_GOTO_WTTH_LOG(rc);
+    if (rc != PKCS7_SUCC) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Parse signed data failed: %d", rc);
+        goto exit;
+    }
+    
     HILOG_INFO(HILOG_MODULE_AAFWK, "Parse pkcs#7 signed data success");
+
+    // 现在构建证书路径(这里会根据路径可用性选择证书)
     rc = ConstructSignerCerts(&pkcs7->signedData);
-    P_ERR_GOTO_WTTH_LOG(rc);
+    if (rc != PKCS7_SUCC) {
+        HILOG_ERROR(HILOG_MODULE_AAFWK, "Construct signer certificates failed: %d", rc);
+        goto exit;
+    }
+    
+    HILOG_INFO(HILOG_MODULE_AAFWK, "PKCS7 parsing completed successfully");
     return rc;
-EXIT:
+
+exit:
+    HILOG_ERROR(HILOG_MODULE_AAFWK, "PKCS7 parsing failed: %d", rc);
+    PKCS7_FreeRes(pkcs7);
     return rc;
 }
 
@@ -2364,4 +3098,5 @@ void PKCS7_FreeRes(Pkcs7 *pkcs7)
 #ifndef OHOS_SIGN_HAPS_BY_SERVER
     UnLoadSelfSignedCert();
 #endif
+    FreeCertVerifyCache(&g_certCache);
 }
\ No newline at end of file
index 5ad48ef..c450b3d 100644 (file)
@@ -118,7 +118,7 @@ typedef struct {
     int len;
 } AppSignPk;
 
-#ifdef MARKET_ENABLE
+#ifdef OH_MARKET_ENABLE
 #define NOISE_SIZE 32
 #define SALT_INFO_POOL_ROWS 3
 #define PUBLIC_KEY_FILE_LEN (SALT_INFO_POOL_ROWS * NOISE_SIZE * 2 + 4 + 1)
@@ -174,14 +174,14 @@ int APPVERI_SetDebugMode(bool mode);
 /* get unsigned file len without verify, return V_ERR if not OK */
 int APPVERI_GetUnsignedFileLength(const char *filePath);
 
-#ifdef MARKET_ENABLE
+#ifdef OH_MARKET_ENABLE
 /*******************************************************************************
  * Function    : PKCS7_GenerateECCKeypair
  * Description : Generate ECC brainpool256R1 key pair and write to PEM files
  *
  * Return      : int 0 on success, non-zero error code on failure
  *******************************************************************************/
-int32_t PKCS7_GenerateECCKeypair();
+int32_t PKCS7_GenerateECCKeypair(void);
 
 /*******************************************************************************
  * Function    : PKCS7_VerifyAndDecrypt
index a21759a..3c65b60 100644 (file)
@@ -40,6 +40,9 @@ extern "C" {
  * #define PARSE_PEM_FORMAT_SIGNED_DATA 1
  */
 #define MAX_SIGNER_NAME_LEN 512
+#define MAX_CERTPATH_LEN 256
+#define SHA256_HASH_SIZE 32
+#define RSA3072_SIG_SIZE 384
 /* Parse error definition */
 typedef enum {
     PKCS7_SUCC = 0,
@@ -149,6 +152,26 @@ typedef struct {
 #endif
 } Pkcs7;
 
+typedef struct {
+    unsigned char *hashListData;
+    size_t hashListSize;
+    char certDirPath[MAX_CERTPATH_LEN];
+    time_t verifyTime;
+} CertVerifyCache;
+
+typedef struct {
+    char *certName;
+    unsigned char hash[SHA256_HASH_SIZE];
+    size_t hashHexLen;
+    char hashHex[65]; // 十六进制表示的哈希值
+} CertHashEntry;
+
+typedef struct {
+    CertHashEntry *entries;
+    size_t count;
+    size_t capacity;
+} CertHashList;
+
 /*******************************************************************************
  * Function    : PKCS7_ParseSignedData
  * Description : parse the pkcs7 signed data, store the resolved data to pkcs7
index 6e38445..a567f76 100644 (file)
@@ -11,11 +11,16 @@ set(PRIVATE_HEADER
     ${CMAKE_CURRENT_SOURCE_DIR}/include
     ${ROOT_DIR}/open_source/mbedtls/mbedtls_v3.6.0/include
     ${OHOS_DIR}/commonlibrary/utils_lite/include
+    ${ROOT_DIR}/open_source/openharmony/base/security/appverify/include
 )
 
 set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_sha256.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_aes.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_base64.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_hmac_sha256.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_md5.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/cipher_nv_store.c
 )
 
 set(COMPONENT_PUBLIC_CCFLAGS
index 2380343..3845be3 100644 (file)
 #ifdef __cplusplus\r
 #include <cstdint>\r
 #include <cstdio>\r
+#include <cstdbool>\r
 #else\r
 #include <stdint.h>\r
 #include <stdio.h>\r
+#include <stdbool.h>\r
 #endif\r
+#include "nv.h"\r
 \r
 #ifdef __cplusplus\r
 #if __cplusplus\r
@@ -35,6 +38,11 @@ extern "C" {
 #define ERROR_CODE_GENERAL   (-1)\r
 #define ERROR_SUCCESS         0\r
 \r
+#define UT_NV_MAX_LENGTH 4060\r
+#define KEY_ID_START NV_ID_ACE_CIPHER\r
+#define KEY_ID_END 0x2900\r
+#define KEY_ID_COUNT (KEY_ID_END - KEY_ID_START)\r
+\r
 typedef struct Sha256Context Sha256Context;\r
 \r
 typedef enum {\r
@@ -91,6 +99,19 @@ int32_t Sha256(const unsigned char *input, int ilen, unsigned char output[32]);
 void Sha256Starts(Sha256Context *ctx);\r
 int32_t Sha256Update(Sha256Context *ctx, const unsigned char *input, size_t ilen);\r
 void Sha256Finish(Sha256Context *ctx, unsigned char output[32]);\r
+\r
+int Base64EncodeInternal(const unsigned char *input, size_t inputLen, char *output, size_t outputLen);\r
+int Base64DecodeInternal(const char *input, size_t inputLen, unsigned char *output, size_t outputLen);\r
+int HmacSha256Compute(const unsigned char *key,\r
+    size_t keyLen, const unsigned char *input, size_t inputLen, unsigned char *output);\r
+int Md5Compute(const unsigned char *input, size_t inputLen, unsigned char *output);\r
+uint16_t InnerGetUsedKeyIds(uint16_t *used_ids, uint16_t max_count);\r
+uint16_t InnerGetAvailableKeyIds(uint16_t *available_ids, uint16_t max_count);\r
+int32_t InnerDeleteKeyFromNv(uint16_t keyId);\r
+int32_t InnerGetKeyFromNv(uint16_t keyId, uint8_t *data, uint16_t *actualKeyLen);\r
+int32_t InnerSaveKeyToNv(unsigned char *keyBuff, uint32_t keyBuffLen, uint16_t keyId, bool overwrite);\r
+\r
+\r
 // ohos end\r
 int32_t InitAesCryptData(const char *action, const char *text, const char *key,\r
     const AesIvMode *iv, AesCryptContext *aesCryptCxt);\r
index 14a6942..aa6f246 100644 (file)
@@ -32,6 +32,8 @@
 \r
 enum CipherLogLevel {\r
     CIPHER_LOG_LEVEL_E,\r
+    CIPHER_LOG_LEVEL_D,\r
+    CIPHER_LOG_LEVEL_I,\r
 };\r
 \r
 #ifdef __cplusplus\r
@@ -42,8 +44,12 @@ void CipherLog(uint32_t logLevel, const char *funcName, uint32_t lineNo, const c
 \r
 #ifndef __LITEOS__\r
 #define CIPHER_LOG_E(...) CipherLog(CIPHER_LOG_LEVEL_E, __func__, __LINE__, __VA_ARGS__)\r
+#define CIPHER_LOG_D(...) CipherLog(CIPHER_LOG_LEVEL_D, __func__, __LINE__, __VA_ARGS__)\r
+#define CIPHER_LOG_I(...) CipherLog(CIPHER_LOG_LEVEL_I, __func__, __LINE__, __VA_ARGS__)\r
 #else\r
 #define CIPHER_LOG_E printf\r
+#define CIPHER_LOG_D printf\r
+#define CIPHER_LOG_I printf\r
 #endif\r
 #ifdef __cplusplus\r
 }\r
index 6adffd7..fd9a1ac 100644 (file)
@@ -224,6 +224,18 @@ static int32_t SetIv(const unsigned char *ivBuf, size_t ivBufSize, int32_t ivOff
     return ERROR_SUCCESS;
 }
 
+static void GetPaddingLen(char *data, int32_t *paddingLen)
+{
+    uint8_t pad_len = data[*paddingLen - 1];
+    for (int i = 0; i < *paddingLen; i++) {
+        uint8_t temp = data[i];
+        if (temp > 0 && temp <= AES_BLOCK_SIZE && temp == pad_len) {
+            *paddingLen = i;
+            break;
+        }
+    }
+}
+
 static int32_t InitAesCryptContext(const char *key, const AesIvMode *iv, AesCryptContext *ctx)
 {
     int32_t ret;
@@ -474,6 +486,9 @@ static int32_t DoAesCbcEncrypt(mbedtls_aes_context *aesCtx, AesCryptContext *ctx
             CIPHER_LOG_E("remove padding failed.\n");
             return ERROR_CODE_GENERAL;
         }
+        if (ctx->paddingMode == PADDING_NONE) {
+            GetPaddingLen(ctx->data.text, &unpaddedLen);
+        }
         ctx->data.textLen = unpaddedLen;
         
         // 添加字符串终止符
@@ -530,6 +545,9 @@ static int32_t DoAesEcbEncrypt(mbedtls_aes_context *aesCtx, AesCryptContext *ctx
             CIPHER_LOG_E("remove padding failed.\n");
             return ERROR_CODE_GENERAL;
         }
+        if (ctx->paddingMode == PADDING_NONE) {
+            GetPaddingLen(ctx->data.text, &unpaddedLen);
+        }
         ctx->data.textLen = unpaddedLen;
         
         // 添加字符串终止符
diff --git a/code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_base64.c b/code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_base64.c
new file mode 100644 (file)
index 0000000..4267cf3
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2025-2030 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ohos begin
+// Add software base64
+#include "cipher.h"
+#include "mbedtls/base64.h"
+
+// Base64编码底层实现
+int Base64EncodeInternal(const unsigned char *input, size_t inputLen, char *output, size_t outputLen)
+{
+    size_t actualOutputLen = 0;
+    return mbedtls_base64_encode((unsigned char *)(output), outputLen, &actualOutputLen, input, inputLen);
+}
+
+// Base64解码底层实现
+int Base64DecodeInternal(const char *input, size_t inputLen, unsigned char *output, size_t outputLen)
+{
+    size_t actualOutputLen = 0;
+    return mbedtls_base64_decode(
+        output, outputLen, &actualOutputLen, (const unsigned char *)(input), inputLen);
+}
+// ohos end
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_hmac_sha256.c b/code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_hmac_sha256.c
new file mode 100644 (file)
index 0000000..f54ab51
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2025-2030 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ohos begin
+// Add software hmac-sha256
+#include "cipher.h"
+#include "cipher_log.h"
+#include "mbedtls/md.h"
+#include "mbedtls/error.h"
+#include <string.h>
+
+// HMAC-SHA256底层计算
+int HmacSha256Compute(
+    const unsigned char *key, size_t keyLen, const unsigned char *input, size_t inputLen, unsigned char *output)
+{
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+    if (md_info == NULL) {
+        return -1;
+    }
+
+    return mbedtls_md_hmac(md_info, key, keyLen, input, inputLen, output);
+}
+// ohos end
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_md5.c b/code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_md5.c
new file mode 100644 (file)
index 0000000..e055622
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2025-2030 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ohos begin
+// Add software md5
+#include "cipher.h"
+#include "mbedtls/md5.h"
+
+// MD5底层计算
+int Md5Compute(const unsigned char *input, size_t inputLen, unsigned char *output)
+{
+    mbedtls_md5_context ctx;
+    mbedtls_md5_init(&ctx);
+
+    int ret = mbedtls_md5_starts(&ctx);
+    if (ret != 0) {
+        goto cleanup;
+    }
+
+    ret = mbedtls_md5_update(&ctx, input, inputLen);
+    if (ret != 0) {
+        goto cleanup;
+    }
+
+    ret = mbedtls_md5_finish(&ctx, output);
+
+cleanup:
+    mbedtls_md5_free(&ctx);
+    return ret;
+}
+// ohos end
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_nv_store.c b/code/sdk/open_source/openharmony/base/security/huks/frameworks/crypto_lite/cipher/src/cipher_nv_store.c
new file mode 100644 (file)
index 0000000..63c3d83
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2025-2030 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ohos begin
+// Add NV store
+#include "cipher.h"
+#include "cipher_log.h"
+#include "app_common.h"
+#include <stdint.h>
+#include <string.h>
+
+// 位图大小计算(每个bit表示一个keyId)
+#define BITMAP_SIZE ((KEY_ID_COUNT + 7) / 8)
+
+// 使用一个特殊的keyId来存储位图(在密钥区间之前)
+#define BITMAP_KEY_ID 0x26FF
+
+// 全局位图变量
+static uint8_t keyIdBitmap[BITMAP_SIZE] = {0};
+static int bitmapInitialized = 0;
+
+// 属性配置
+static nv_key_attr_t nvAttr = {0, 1, 0, 0};
+
+/**
+ * @brief 初始化密钥ID位图
+ * @return 0-成功,其他-失败
+ */
+static int32_t InitKeyIdBitmap(void)
+{
+    int32_t ret = 0;
+    uint16_t readLen = 0;
+
+    if (bitmapInitialized) {
+        return 0;
+    }
+
+    // 尝试从NV读取位图
+    ret = uapi_nv_read_with_attr(BITMAP_KEY_ID, BITMAP_SIZE, &readLen, keyIdBitmap, &nvAttr);
+    if (ret != 0 || readLen != BITMAP_SIZE) {
+        // 读取失败或长度不匹配,初始化位图为全0
+        CIPHER_LOG_D("Initialize key_id bitmap for first use\n");
+        memset_s(keyIdBitmap, BITMAP_SIZE, 0, BITMAP_SIZE);
+
+        // 将初始化的位图保存到NV
+        ret = uapi_nv_write_with_attr(BITMAP_KEY_ID, keyIdBitmap, BITMAP_SIZE, &nvAttr, NULL);
+        if (ret != 0) {
+            CIPHER_LOG_E("Failed to initialize key_id bitmap to NV\n");
+            return ret;
+        }
+    }
+
+    bitmapInitialized = 1;
+    CIPHER_LOG_I("Key_id bitmap initialized successfully\n");
+    return 0;
+}
+
+/**
+ * @brief 保存位图到NV
+ * @return 0-成功,其他-失败
+ */
+static int32_t SaveKeyIdBitmap(void)
+{
+    if (!bitmapInitialized) {
+        CIPHER_LOG_E("Bitmap not initialized\n");
+        return -1;
+    }
+
+    int32_t ret = uapi_nv_write_with_attr(BITMAP_KEY_ID, keyIdBitmap, BITMAP_SIZE, &nvAttr, NULL);
+    if (ret != 0) {
+        CIPHER_LOG_E("Failed to save key_id bitmap to NV\n");
+    }
+    return ret;
+}
+
+/**
+ * @brief 检查keyId是否有效且在范围内
+ * @param keyId 密钥ID
+ * @return 1-有效,0-无效
+ */
+static int IsValidKeyId(uint16_t keyId)
+{
+    return (keyId >= KEY_ID_START && keyId < KEY_ID_END);
+}
+
+/**
+ * @brief 设置keyId为已使用
+ * @param keyId 密钥ID
+ */
+static void SetKeyIdUsed(uint16_t keyId)
+{
+    if (IsValidKeyId(keyId)) {
+        uint16_t index = keyId - KEY_ID_START;
+        keyIdBitmap[index / 8] |= (1 << (index % 8));
+    }
+}
+
+/**
+ * @brief 检查keyId是否已被使用
+ * @param keyId 密钥ID
+ * @return 1-已使用,0-未使用
+ */
+static int IsKeyIdUsed(uint16_t keyId)
+{
+    if (!IsValidKeyId(keyId)) {
+        return 0;
+    }
+    uint16_t index = keyId - KEY_ID_START;
+    return (keyIdBitmap[index / 8] >> (index % 8)) & 1;
+}
+
+/**
+ * @brief 清除keyId的使用标记
+ * @param keyId 密钥ID
+ */
+static void ClearKeyIdUsed(uint16_t keyId)
+{
+    if (IsValidKeyId(keyId)) {
+        uint16_t index = keyId - KEY_ID_START;
+        keyIdBitmap[index / 8] &= ~(1 << (index % 8));
+    }
+}
+
+/**
+ * @brief 保存密钥到NV存储
+ * @param keyBuff 密钥数据缓冲区
+ * @param keyBuffLen 密钥数据长度
+ * @param keyId 密钥ID
+ * @param overwrite 是否覆盖已存在的密钥
+ * @return 0-成功,其他-失败
+ */
+int32_t InnerSaveKeyToNv(unsigned char *keyBuff, uint32_t keyBuffLen, uint16_t keyId, bool overwrite)
+{
+    int32_t ret = 0;
+
+    // 初始化位图(如果未初始化)
+    if (!bitmapInitialized) {
+        ret = InitKeyIdBitmap();
+        if (ret != 0) {
+            CIPHER_LOG_E("Failed to initialize key_id bitmap\n");
+            return ret;
+        }
+    }
+
+    // 检查keyId是否有效
+    if (!IsValidKeyId(keyId)) {
+        CIPHER_LOG_E("Invalid keyId: 0x%04X, valid range: [0x%04X, 0x%04X)\n", 
+                    keyId, KEY_ID_START, KEY_ID_END);
+        return -1;
+    }
+
+    // 检查参数有效性
+    if (keyBuff == NULL || keyBuffLen == 0) {
+        CIPHER_LOG_E("Invalid key buffer or length\n");
+        return -1;
+    }
+
+    // 检查keyId是否已被使用
+    bool keyUsed = IsKeyIdUsed(keyId);
+    if (keyUsed && !overwrite) {
+        CIPHER_LOG_E("KeyId 0x%04X already used and overwrite not allowed\n", keyId);
+        return -1;
+    }
+
+    // 保存密钥到NV
+    ret = uapi_nv_write_with_attr(keyId, keyBuff, keyBuffLen, &nvAttr, NULL);
+    if (ret != 0) {
+        CIPHER_LOG_E("Failed to write key 0x%04X to nv, ret=%d\n", keyId, ret);
+        return ret;
+    }
+
+    // 如果之前未使用,标记为已使用并保存位图
+    if (!keyUsed) {
+        SetKeyIdUsed(keyId);
+        ret = SaveKeyIdBitmap();
+        if (ret != 0) {
+            CIPHER_LOG_E("Failed to save key_id bitmap after writing key 0x%04X\n", keyId);
+        } else {
+            CIPHER_LOG_D("Key 0x%04X saved successfully (new)\n", keyId);
+        }
+    } else {
+        CIPHER_LOG_I("Key 0x%04X saved successfully (overwritten)\n", keyId);
+    }
+
+    return ret;
+}
+
+/**
+ * @brief 从NV读取密钥
+ * @param keyId 密钥ID
+ * @param data 输出缓冲区
+ * @return 0-成功,其他-失败
+ */
+int32_t InnerGetKeyFromNv(uint16_t keyId, uint8_t *data, uint16_t *actualKeyLen)
+{
+    int32_t ret = 0;
+    uint16_t keyLen = 0;
+
+    // 初始化位图(如果未初始化)
+    if (!bitmapInitialized) {
+        ret = InitKeyIdBitmap();
+        if (ret != 0) {
+            CIPHER_LOG_E("Failed to initialize key_id bitmap\n");
+            return ret;
+        }
+    }
+
+    // 检查keyId是否有效
+    if (!IsValidKeyId(keyId)) {
+        CIPHER_LOG_E("Invalid keyId: 0x%04X\n", keyId);
+        return -1;
+    }
+
+    // 检查keyId是否已被使用
+    if (!IsKeyIdUsed(keyId)) {
+        CIPHER_LOG_E("KeyId 0x%04X not exists\n", keyId);
+        return -1;
+    }
+
+    // 检查输出缓冲区
+    if (data == NULL || actualKeyLen == NULL) {
+        CIPHER_LOG_E("Invalid output buffer\n");
+        return -1;
+    }
+
+    // 从NV读取密钥
+    ret = uapi_nv_read_with_attr(keyId, UT_NV_MAX_LENGTH, &keyLen, data, &nvAttr);
+    if (ret != 0) {
+        CIPHER_LOG_E("Failed to read key 0x%04X from nv, ret=%d\n", keyId, ret);
+
+        // 如果读取失败,可能密钥数据已损坏,清除使用标记
+        ClearKeyIdUsed(keyId);
+        SaveKeyIdBitmap(); // 尝试保存更新后的位图
+    } else {
+        CIPHER_LOG_I("Key 0x%04X read successfully, length=%d\n", keyId, keyLen);
+        *actualKeyLen = keyLen; // 设置实际长度
+    }
+
+    return ret;
+}
+
+/**
+ * @brief 从NV删除密钥
+ * @param keyId 密钥ID
+ * @return 0-成功,其他-失败
+ */
+int32_t InnerDeleteKeyFromNv(uint16_t keyId)
+{
+    int32_t ret = 0;
+    uint16_t keyLen = 0;
+    // 初始化位图(如果未初始化)
+    if (!bitmapInitialized) {
+        ret = InitKeyIdBitmap();
+        if (ret != 0) {
+            CIPHER_LOG_E("Failed to initialize key_id bitmap\n");
+            return ret;
+        }
+    }
+
+    // 检查keyId是否有效
+    if (!IsValidKeyId(keyId)) {
+        CIPHER_LOG_E("Invalid keyId: 0x%04X\n", keyId);
+        return -1;
+    }
+
+    // 检查keyId是否已被使用
+    if (!IsKeyIdUsed(keyId)) {
+        CIPHER_LOG_E("KeyId 0x%04X not exists\n", keyId);
+        return -1;
+    }
+    uint8_t *tempBuffer = (uint8_t*)APPV_MALLOC(UT_NV_MAX_LENGTH);
+    if (tempBuffer == NULL) {
+        CIPHER_LOG_E("Failed to allocate memory for temp deletion data\n");
+        return -1;
+    }
+    ret = uapi_nv_read_with_attr(keyId, UT_NV_MAX_LENGTH, &keyLen, tempBuffer, &nvAttr);
+    if (ret != 0) {
+        APPV_FREE(tempBuffer);
+        tempBuffer = NULL;
+        CIPHER_LOG_E("Failed to read key length for deletion 0x%04X, ret=%X\n", keyId, ret);
+        return -1;
+    }
+    APPV_FREE(tempBuffer);
+    tempBuffer = NULL;
+    uint8_t *zeroData = (uint8_t*)APPV_MALLOC(keyLen);
+    if (zeroData == NULL) {
+        CIPHER_LOG_E("Failed to allocate memory for deletion data\n");
+        return -1;
+    }
+
+    // 用0xf填充数据
+    memset_s(zeroData, keyLen, 0xFF, keyLen);
+    // 删除密钥:覆盖原始数据
+    ret = uapi_nv_write_with_attr(keyId, zeroData, keyLen, &nvAttr, NULL);
+    if (ret != 0) {
+        APPV_FREE(zeroData);
+        zeroData = NULL;
+        CIPHER_LOG_E("Failed to delete key 0x%04X from nv, ret=%d\n", keyId, ret);
+        return ret;
+    }
+    APPV_FREE(zeroData);
+    zeroData = NULL;
+    // 清除使用标记并保存位图
+    ClearKeyIdUsed(keyId);
+    ret = SaveKeyIdBitmap();
+    if (ret != 0) {
+        CIPHER_LOG_E("Failed to save key_id bitmap after deleting key 0x%04X\n", keyId);
+    } else {
+        CIPHER_LOG_I("Key 0x%04X deleted successfully\n", keyId);
+    }
+
+    return ret;
+}
+
+/**
+ * @brief 获取可用的密钥ID列表
+ * @param availableIds 输出可用ID数组
+ * @param maxCount 数组最大容量
+ * @return 可用ID数量
+ */
+uint16_t InnerGetAvailableKeyIds(uint16_t *availableIds, uint16_t maxCount)
+{
+    // 初始化密钥ID位图
+    uint16_t count = 0;
+
+    // 检查位图是否已初始化,若未初始化则进行初始化
+    if (!bitmapInitialized) {
+        if (InitKeyIdBitmap() != 0) {
+            return 0;
+        }
+    }
+
+    // 检查输入参数是否有效
+    if (availableIds == NULL || maxCount == 0) {
+        return 0;
+    }
+
+    // 遍历所有密钥ID,查找可用的密钥ID
+    for (uint16_t i = 0; i < KEY_ID_COUNT && count < maxCount; i++) {
+        // 检查当前密钥ID是否可用,8:一个字节8位
+        if (!(keyIdBitmap[i / 8] & (1 << (i % 8)))) {
+            // 将可用的密钥ID存入数组,并增加计数
+            availableIds[count++] = KEY_ID_START + i;
+        }
+    }
+
+    // 返回实际获取的可用密钥ID的数量
+    return count;
+}
+
+/**
+ * @brief 获取已使用的密钥ID列表
+ * @param usedIds 输出已使用ID数组
+ * @param maxCount 数组最大容量
+ * @return 已使用ID数量
+ */
+uint16_t InnerGetUsedKeyIds(uint16_t *usedIds, uint16_t maxCount)
+{
+    // 初始化计数器
+    uint16_t count = 0;
+
+    // 如果位图未初始化,则尝试初始化
+    if (!bitmapInitialized) {
+        if (InitKeyIdBitmap() != 0) {
+            return 0;
+        }
+    }
+
+    // 检查参数有效性
+    if (usedIds == NULL || maxCount == 0) {
+        return 0;
+    }
+
+    // 遍历所有密钥ID,查找已使用的密钥ID
+    for (uint16_t i = 0; i < KEY_ID_COUNT && count < maxCount; i++) {
+        // 检查当前密钥ID是否已使用,8:一个字节8位
+        if (keyIdBitmap[i / 8] & (1 << (i % 8))) {
+            // 将已使用的密钥ID存入数组,并递增计数器
+            usedIds[count++] = KEY_ID_START + i;
+        }
+    }
+
+    // 返回实际获取的已使用密钥ID数量
+    return count;
+}
+// ohos end
\ No newline at end of file
index 96ddbb3..e1d642f 100644 (file)
@@ -14,6 +14,7 @@ set(PRIVATE_HEADER
     ${ROOT_DIR}/foundation/arkui/ace_engine_lite/interfaces/jsi
     ${ROOT_DIR}/foundation/arkui/ace_engine_lite/interfaces/base
     ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/interfaces/base
+    ${ROOT_DIR}/open_source/openharmony/base/security/appverify/include
 )
 
 set(SOURCES
index 5a530ec..dde7c03 100644 (file)
@@ -32,13 +32,31 @@ public:
     static JSIValue Sha256SubStarts(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
     static JSIValue Sha256SubUpdate(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
     static JSIValue Sha256SubFinish(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+
+    static JSIValue HmacSha256(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue HmacSha256Bytes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue Md5FromString(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue Md5FromBytes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue Base64Encode(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue Base64Decode(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue GetAvailableKeyIds(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue GetUsedKeyIds(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue DeleteKeyFromNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue GetKeyFromNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue SaveKeyToNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+
     static void OnDestroy();
 #endif
 private:
-    static constexpr uint8_t ERR_CODE = 200;
+    static const int HMAC_SHA256_LEN = 32; // SHA1²»°²È«£¬·ñÔò³¤¶ÈΪ20
+    static const int HMAC_SHA256_RESULT_LEN = 64;
+    static const int MD5_LEN = 16;
+    static const int MD5_RESULT_LEN = 32;
+
     static void ResetStrBuf(char *strBuf);
     static CipherAesMode GetMode(char *strTransformation);
     static PaddingMode GetPaddingMode(char *strTransformation);
+    static constexpr uint8_t ERR_CODE = 200;
 };
 
 void InitCipherModule(JSIValue exports);
index c2a0675..3009a00 100644 (file)
 // OHOS BEGIN
 #include <string>
 #ifdef HUKS_LITEWEARABLE_SUPPORT_ENABLED
+#include "app_common.h"
 #include "mbedtls/sha256.h"
+#include "mbedtls/base64.h"
 #include "js_async_work.h"
 #endif
 
 const int8_t SHA256_LEN = 32;
 const int8_t SHA256_RESULT_LEN = SHA256_LEN * 2;
 const int32_t MAX_LEN = 16384;
+const int32_t MAX_TXT_LEN = 4096;
+const int32_t MAX_KEY_LEN = 64;
 
 struct CipherMsgParams {
     char *msgBody;
@@ -44,6 +48,36 @@ Sha256Context *g_sha256Context;
 // OHOS END
 namespace OHOS {
 namespace ACELite {
+void CipherModule::ResetStrBuf(char *strBuf)
+{
+    if (strBuf == nullptr) {
+        return;
+    }
+
+    int ret = memset_s(strBuf, strlen(strBuf), 0, strlen(strBuf));
+    if (ret != EOK) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "memset failed.");
+    }
+}
+
+static int32_t CheckTxtLen(char *text)
+{
+    uint32_t textLen = strlen(text);
+    if (textLen == 0 || textLen > MAX_TXT_LEN) {
+        return ERROR_CODE_GENERAL;
+    }
+    return ERROR_SUCCESS;
+}
+
+static int32_t CheckKeyLen(char *key)
+{
+    uint32_t keyLen = strlen(key);
+    if (keyLen == 0 || keyLen > MAX_KEY_LEN * 2) {
+        return ERROR_CODE_GENERAL;
+    }
+    return ERROR_SUCCESS;
+}
+
 JSIValue CipherModule::Rsa(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
 {
     JSIValue undefValue = JSI::CreateUndefined();
@@ -162,6 +196,7 @@ JSIValue CipherModule::Sha256All(const JSIValue thisVal, const JSIValue *args, u
     }
 
 RELEASE:
+    JSI::ReleaseValueList(success, fail, context, ARGS_END);
     JSI::ReleaseString(strText);
     return undefValue;
 }
@@ -221,6 +256,7 @@ JSIValue CipherModule::Sha256SubFinish(const JSIValue thisVal, const JSIValue *a
         HILOG_ERROR(HILOG_MODULE_ACE, "Sha256SubFinish send message error.");
         CipherMsgToJS("Sha256SubFinish error", context, fail);
     }
+    JSI::ReleaseValueList(success, fail, context, ARGS_END);
     DestroySha256Context(&g_sha256Context);
     return undefValue;
 }
@@ -264,6 +300,10 @@ JSIValue CipherModule::Aes(const JSIValue thisVal, const JSIValue *args, uint8_t
         HILOG_ERROR(HILOG_MODULE_ACE, "args error , text is nullptr");
         goto RELEASE;
     }
+    if (strlen(strText) > MAX_LEN) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "args error , text size more than 16KB");
+        goto RELEASE;
+    }
     if (!strcmp(strAction, "encrypt") && paddingMode == PADDING_NONE && strlen(strText) % AES_BLOCK_SIZE != 0) {
         HILOG_ERROR(HILOG_MODULE_ACE, "args error , text is not valid");
         goto RELEASE;
@@ -326,6 +366,10 @@ RELEASE:
     JSI::ReleaseString(strKey);
     JSI::ReleaseString(strIv);
     JSI::ReleaseString(strTransformation);
+#ifdef HUKS_LITEWEARABLE_SUPPORT_ENABLED
+    JSI::ReleaseValue(context);
+#endif
+    JSI::ReleaseValueList(success, fail, jsIvLen, code, data, result, ARGS_END);
     DeinitAesCryptData(&aes);
     return undefValue;
 }
@@ -340,17 +384,6 @@ void CipherModule::OnDestroy()
 }
 #endif
 // OHOS END
-void CipherModule::ResetStrBuf(char *strBuf)
-{
-    if (strBuf == nullptr) {
-        return;
-    }
-
-    int ret = memset_s(strBuf, strlen(strBuf), 0, strlen(strBuf));
-    if (ret != EOK) {
-        HILOG_ERROR(HILOG_MODULE_ACE, "memset failed.");
-    }
-}
 
 CipherAesMode CipherModule::GetMode(char *strTransformation)
 {
@@ -390,7 +423,7 @@ static int32_t CopyStr(char **destStr, const char *srcStr)
         HILOG_ERROR(HILOG_MODULE_ACE, "More than Max Memory");
         return -1;
     }
-    *destStr = static_cast<char *>(ace_malloc(length));
+    *destStr = static_cast<char *>(APPV_MALLOC(length));
     if (*destStr == nullptr) {
         HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for destination string");
         return -1;
@@ -398,37 +431,862 @@ static int32_t CopyStr(char **destStr, const char *srcStr)
 
     if (memset_s(*destStr, length, 0, length) != EOK) {
         HILOG_ERROR(HILOG_MODULE_ACE, "Failed to set memory for destination string");
-        ace_free(*destStr);
+        APPV_FREE(*destStr);
         return -1;
     }
     if (memcpy_s(*destStr, length, srcStr, length) != EOK) {
         HILOG_ERROR(HILOG_MODULE_ACE, "Failed to copy source string to destination string");
-        ace_free(*destStr);
+        APPV_FREE(*destStr);
         return -1;
     }
 
     return 0;
 }
 
-static void ExecuteSendMsgToJS(void *data)
+// HMAC-SHA256实现
+JSIValue CipherModule::HmacSha256(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
 {
-    if (data == nullptr) {
-        return;
+    int32_t ret = 0;
+    JSIValue undefValue = JSI::CreateUndefined();
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256 args error.");
+        return undefValue;
     }
-    CipherMsgParams *params = static_cast<CipherMsgParams *>(data);
 
-    char *msgBody = params->msgBody;
-    OHOS::ACELite::JSIValue callback = params->callback;
-    OHOS::ACELite::JSIValue context = params->context;
-    delete params;
-    params = nullptr;
+    JSIValue context = JSI::AcquireValue(thisVal);
+    JSIValue success = JSI::GetNamedProperty(args[0], "success");
+    JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
 
-    OHOS::ACELite::JSIValue dataInfo = OHOS::ACELite::JSI::CreateString(msgBody);
-    OHOS::ACELite::JSIValue callbackArgv[OHOS::ACELite::ARGC_ONE] = {dataInfo};
-    OHOS::ACELite::JSI::CallFunction(callback, context, callbackArgv, OHOS::ACELite::ARGC_ONE);
-    OHOS::ACELite::JSI::ReleaseValue(dataInfo);
-    ace_free(msgBody);
-    return;
+    char *text = JSI::GetStringProperty(args[0], "text");
+    char *key = JSI::GetStringProperty(args[0], "key");
+    unsigned char hmacResult[HMAC_SHA256_LEN];
+    char result[HMAC_SHA256_RESULT_LEN + 1];
+    if (text == nullptr || key == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256: text or key is null");
+        CipherMsgToJS("HmacSha256: text or key is null", context, fail);
+        goto RELEASE;
+    }
+    if (CheckTxtLen(text) != ERROR_SUCCESS || CheckKeyLen(key) != ERROR_SUCCESS) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256: the length of text or key is out of range.");
+        goto RELEASE;
+    }
+
+    ret = HmacSha256Compute(
+        reinterpret_cast<unsigned char*>(key), strlen(key),
+        reinterpret_cast<unsigned char*>(text), strlen(text),
+        hmacResult
+    );
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256 compute error: %d", ret);
+        CipherMsgToJS("HmacSha256 compute error", context, fail);
+        goto RELEASE;
+    }
+    // 转换为十六进制字符串
+    for (int i = 0; i < HMAC_SHA256_LEN; i++) {
+        ret = sprintf_s(&result[i * 2], 3, "%02x", hmacResult[i]);
+        if (ret < 0) {
+            HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256 sprintf_s error.");
+            CipherMsgToJS("HmacSha256 format error", context, fail);
+            goto RELEASE;
+        }
+    }
+    result[HMAC_SHA256_RESULT_LEN] = '\0';
+
+    ret = CipherMsgToJS(result, context, success);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256 send message error.");
+        CipherMsgToJS("HmacSha256 send message error", context, fail);
+    }
+
+RELEASE:
+    JSI::ReleaseValueList(success, fail, context, ARGS_END);
+    if (text != nullptr) {
+        JSI::ReleaseString(text);
+    }
+    if (key != nullptr) {
+        JSI::ReleaseString(key);
+    }
+    return undefValue;
+}
+
+JSIValue CipherModule::HmacSha256Bytes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    int32_t ret = 0;
+    JSIValue result[1];
+    JSIValue undefValue = JSI::CreateUndefined();
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes args error.");
+        return undefValue;
+    }
+
+    JSIValue context = JSI::AcquireValue(thisVal);
+    JSIValue success = JSI::GetNamedProperty(args[0], "success");
+    JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
+    uint8_t *bufferPtr = nullptr;
+    JSIValue arrayBuffer = JSI::CreateUndefined();
+
+    char *text = JSI::GetStringProperty(args[0], "text");
+    char *key = JSI::GetStringProperty(args[0], "key");
+    unsigned char hmacResult[HMAC_SHA256_LEN];
+
+    if (text == nullptr || key == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes: text or key is null");
+        CipherMsgToJS("HmacSha256Bytes: text or key is null", context, fail);
+        goto RELEASE;
+    }
+    if (CheckTxtLen(text) != ERROR_SUCCESS || CheckKeyLen(key) != ERROR_SUCCESS) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes: the length of text or key is out of range.");
+        goto RELEASE;
+    }
+
+    ret = HmacSha256Compute(
+        reinterpret_cast<unsigned char*>(key), strlen(key),
+        reinterpret_cast<unsigned char*>(text), strlen(text),
+        hmacResult
+    );
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes compute error: %d", ret);
+        CipherMsgToJS("HmacSha256Bytes compute error", context, fail);
+        goto RELEASE;
+    }
+
+    // 创建 ArrayBuffer 并直接返回字节数组
+    arrayBuffer = JSI::CreateArrayBuffer(HMAC_SHA256_LEN, bufferPtr);
+    if (bufferPtr == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes: CreateArrayBuffer failed");
+        CipherMsgToJS("HmacSha256Bytes: CreateArrayBuffer failed", context, fail);
+        JSI::ReleaseValue(arrayBuffer);
+        goto RELEASE;
+    }
+
+    // 拷贝数据到 ArrayBuffer
+    if (memcpy_s(bufferPtr, HMAC_SHA256_LEN, hmacResult, HMAC_SHA256_LEN) != EOK) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "HmacSha256Bytes: memcpy_s failed");
+        CipherMsgToJS("HmacSha256Bytes: memcpy_s failed", context, fail);
+        JSI::ReleaseValue(arrayBuffer);
+        goto RELEASE;
+    }
+
+    // 返回 ArrayBuffer
+    result[0] = arrayBuffer;
+    JSI::CallFunction(success, context, result, 1);
+    JSI::ReleaseValueList(arrayBuffer, ARGS_END);
+
+RELEASE:
+    JSI::ReleaseValueList(success, fail, context, ARGS_END);
+    if (text != nullptr) {
+        JSI::ReleaseString(text);
+    }
+    if (key != nullptr) {
+        JSI::ReleaseString(key);
+    }
+    return undefValue;
+}
+
+// Base64编码实现
+JSIValue CipherModule::Base64Encode(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    int32_t ret = 0;
+    JSIValue undefValue = JSI::CreateUndefined();
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode args error.");
+        return undefValue;
+    }
+
+    JSIValue context = JSI::AcquireValue(thisVal);
+    JSIValue success = JSI::GetNamedProperty(args[0], "success");
+    JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
+    size_t inputLen = 0;
+    size_t outputLen = 0;
+    char *base64Result = nullptr;
+
+    char *text = JSI::GetStringProperty(args[0], "text");
+    if (text == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode: text is null");
+        CipherMsgToJS("Base64Encode: text is null", context, fail);
+        goto RELEASE;
+    }
+    if (CheckTxtLen(text) != ERROR_SUCCESS) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode: the length of text is out of range.");
+        goto RELEASE;
+    }
+
+    inputLen = strlen(text);
+    mbedtls_base64_encode(nullptr, 0, &outputLen, 
+                         reinterpret_cast<const unsigned char*>(text), inputLen);
+
+    base64Result = static_cast<char*>(APPV_MALLOC(outputLen + 1));
+    if (base64Result == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode: malloc failed");
+        CipherMsgToJS("Base64Encode: memory allocation failed", context, fail);
+        goto RELEASE;
+    }
+
+    ret = Base64EncodeInternal(
+        reinterpret_cast<const unsigned char*>(text), inputLen,
+        base64Result, outputLen
+    );
+
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode error: %d", ret);
+        CipherMsgToJS("Base64Encode error", context, fail);
+        APPV_FREE(base64Result);
+        goto RELEASE;
+    }
+
+    base64Result[outputLen] = '\0';
+    ret = CipherMsgToJS(base64Result, context, success);
+    APPV_FREE(base64Result);
+
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Encode send message error.");
+        CipherMsgToJS("Base64Encode send message error", context, fail);
+    }
+
+RELEASE:
+    JSI::ReleaseValueList(success, fail, context, ARGS_END);
+    if (text != nullptr) {
+        JSI::ReleaseString(text);
+    }
+    return undefValue;
+}
+
+// Base64解码实现  
+JSIValue CipherModule::Base64Decode(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    int32_t ret = 0;
+    JSIValue undefValue = JSI::CreateUndefined();
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode args error.");
+        return undefValue;
+    }
+
+    JSIValue context = JSI::AcquireValue(thisVal);
+    JSIValue success = JSI::GetNamedProperty(args[0], "success");
+    JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
+    size_t inputLen = 0;
+    size_t outputLen = 0;
+    unsigned char *decodedResult = nullptr;
+    char *resultStr = nullptr;
+
+    char *base64Text = JSI::GetStringProperty(args[0], "text");
+    if (base64Text == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode: text is null");
+        CipherMsgToJS("Base64Decode: text is null", context, fail);
+        goto RELEASE;
+    }
+    if (CheckTxtLen(base64Text) != ERROR_SUCCESS) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode: the length of text is out of range.");
+        goto RELEASE;
+    }
+
+    inputLen = strlen(base64Text);
+    mbedtls_base64_decode(nullptr, 0, &outputLen, 
+                         reinterpret_cast<const unsigned char*>(base64Text), inputLen);
+
+    decodedResult = static_cast<unsigned char*>(APPV_MALLOC(outputLen + 1));
+    if (decodedResult == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode: malloc failed");
+        CipherMsgToJS("Base64Decode: memory allocation failed", context, fail);
+        goto RELEASE;
+    }
+
+    ret = Base64DecodeInternal(base64Text, inputLen, decodedResult, outputLen);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode error: %d", ret);
+        CipherMsgToJS("Base64Decode error", context, fail);
+        APPV_FREE(decodedResult);
+        goto RELEASE;
+    }
+
+    decodedResult[outputLen] = '\0';
+    resultStr = reinterpret_cast<char*>(decodedResult);
+    ret = CipherMsgToJS(resultStr, context, success);
+    APPV_FREE(decodedResult);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Base64Decode send message error.");
+        CipherMsgToJS("Base64Decode send message error", context, fail);
+    }
+
+RELEASE:
+    JSI::ReleaseValueList(success, fail, context, ARGS_END);
+    if (base64Text != nullptr) {
+        JSI::ReleaseString(base64Text);
+    }
+    return undefValue;
+}
+
+// MD5实现
+JSIValue CipherModule::Md5FromString(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    int32_t ret = 0;
+    JSIValue undefValue = JSI::CreateUndefined();
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5 args error.");
+        return undefValue;
+    }
+
+    JSIValue context = JSI::AcquireValue(thisVal);
+    JSIValue success = JSI::GetNamedProperty(args[0], "success");
+    JSIValue fail = JSI::GetNamedProperty(args[0], "fail");
+    unsigned char md5Result[MD5_LEN];
+    char result[MD5_RESULT_LEN + 1];
+
+    char *text = JSI::GetStringProperty(args[0], "text");
+    if (text == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5: text is null");
+        CipherMsgToJS("Md5: text is null", context, fail);
+        goto RELEASE;
+    }
+    if (CheckTxtLen(text) != ERROR_SUCCESS) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5: the length of text is out of range.");
+        goto RELEASE;
+    }
+
+    ret = Md5Compute(reinterpret_cast<unsigned char*>(text), strlen(text), md5Result);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5 compute error: %d", ret);
+        CipherMsgToJS("Md5 compute error", context, fail);
+        goto RELEASE;
+    }
+
+    // 转换为十六进制字符串
+    for (int i = 0; i < MD5_LEN; i++) {
+        ret = sprintf_s(&result[i * 2], 3, "%02x", md5Result[i]);
+        if (ret < 0) {
+            HILOG_ERROR(HILOG_MODULE_ACE, "Md5 sprintf_s error.");
+            CipherMsgToJS("Md5 format error", context, fail);
+            goto RELEASE;
+        }
+    }
+    result[MD5_RESULT_LEN] = '\0';
+
+    ret = CipherMsgToJS(result, context, success);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5 send message error.");
+        CipherMsgToJS("Md5 send message error", context, fail);
+    }
+
+RELEASE:
+    JSI::ReleaseValueList(success, fail, context, ARGS_END);
+    if (text != nullptr) {
+        JSI::ReleaseString(text);
+    }
+    return undefValue;
+}
+
+JSIValue CipherModule::Md5FromBytes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    int32_t ret = 0;
+    JSIValue undefValue = JSI::CreateUndefined();
+    JSIValue context = JSI::CreateUndefined();
+    JSIValue success = JSI::CreateUndefined();
+    JSIValue fail = JSI::CreateUndefined();
+    JSIValue dataBuffer = JSI::CreateUndefined();
+    size_t dataLen = 0;
+    unsigned char md5Result[MD5_LEN];
+    uint8_t* byteData = nullptr;
+    char result[MD5_LEN * 2 + 1];
+    bool conversionSuccess = true;
+
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes args error.");
+        goto RELEASE;
+    }
+
+    context = JSI::AcquireValue(thisVal);
+    success = JSI::GetNamedProperty(args[0], "success");
+    fail = JSI::GetNamedProperty(args[0], "fail");
+
+    // 获取 ArrayBuffer 参数
+    dataBuffer = JSI::GetNamedProperty(args[0], "data");
+    if (JSI::ValueIsUndefined(dataBuffer)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: data is undefined");
+        CipherMsgToJS("Md5FromBytes: data is undefined", context, fail);
+        goto RELEASE;
+    }
+
+    // 从 ArrayBuffer 获取数据指针和长度
+    byteData = JSI::GetArrayBufferInfo(dataBuffer, dataLen);
+    if (byteData == nullptr || dataLen == 0 || dataLen > MAX_KEY_LEN) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: invalid array buffer");
+        CipherMsgToJS("Md5FromBytes: invalid array buffer", context, fail);
+        goto RELEASE;
+    }
+
+    ret = Md5Compute(byteData, dataLen, md5Result);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes compute error: %d", ret);
+        CipherMsgToJS("Md5FromBytes compute error", context, fail);
+        goto RELEASE;
+    }
+
+    // 转换为十六进制字符串 - 添加安全检查
+    for (int i = 0; i < MD5_LEN; i++) {
+        // 检查缓冲区边界
+        if (i * 2 + 2 > MD5_LEN * 2) {
+            HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: buffer overflow detected");
+            conversionSuccess = false;
+            break;
+        }
+
+        // 使用 sprintf_s 并检查返回值
+        int written = sprintf_s(&result[i * 2], 3, "%02x", md5Result[i]);
+        if (written != 2) { // 期望写入2个字符
+            HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: sprintf_s failed at position %d, written=%d", i, written);
+            conversionSuccess = false;
+            break;
+        }
+    }
+
+    if (!conversionSuccess) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes: hex conversion failed");
+        CipherMsgToJS("Md5FromBytes: hex conversion failed", context, fail);
+        goto RELEASE;
+    }
+
+    result[MD5_LEN * 2] = '\0';
+
+    ret = CipherMsgToJS(result, context, success);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Md5FromBytes send message error.");
+        CipherMsgToJS("Md5FromBytes send message error", context, fail);
+    }
+
+RELEASE:
+    JSI::ReleaseValueList(success, fail, context, dataBuffer, ARGS_END);
+    return undefValue;
+}
+
+// 最大密钥ID数量
+#define MAX_KEY_IDS_COUNT 100
+
+// 将密钥内容字节数组转换为十六进制字符串
+static char* BytesToHexString(const uint8_t *bytes, uint32_t len)
+{
+    if (bytes == NULL || len == 0) {
+        return NULL;
+    }
+
+    char *hexStr = (char*)APPV_MALLOC(len * 2 + 1);
+    if (hexStr == NULL) {
+        return NULL;
+    }
+
+    for (uint32_t i = 0; i < len; i++) {
+        int written = snprintf_s(&hexStr[i * 2], 3, 2, "%02x", bytes[i]);
+        if (written < 0 || written >= 3) {
+            APPV_FREE(hexStr);
+            return NULL;
+        }
+    }
+    hexStr[len * 2] = '\0';
+
+    return hexStr;
+}
+
+// 将密钥ID数组转换为十六进制字符串
+static char* KeyIdsToHexString(uint16_t *keyIds, uint16_t count)
+{
+    if (keyIds == NULL || count == 0) {
+        return NULL;
+    }
+
+    // 每个keyId占4个十六进制字符,加上分隔符和结束符
+    char *hexStr = (char*)APPV_MALLOC(count * 5); // 5: 4字符 + 1分隔符
+    if (hexStr == NULL) {
+        return NULL;
+    }
+
+    int offset = 0;
+    for (uint16_t i = 0; i < count; i++) {
+        // 5: 4字符 + 1分隔符
+        int written = snprintf_s(hexStr + offset, 5, 4, "%04X", keyIds[i]);
+        if (written < 0 || written >= 5) {
+            APPV_FREE(hexStr);
+            return NULL;
+        }
+        offset += written;
+
+        // 添加分隔符(最后一个不添加)
+        if (i < count - 1) {
+            hexStr[offset] = ',';
+            offset++;
+        }
+    }
+    hexStr[offset] = '\0';
+
+    return hexStr;
+}
+
+// 将十六进制字符串转换为字节数组
+static int HexStringToBytes(const char *hexStr, uint8_t *bytes, uint32_t maxLen)
+{
+    if (hexStr == NULL || bytes == NULL) {
+        return -1;
+    }
+
+    size_t hexLen = strlen(hexStr);
+    if (hexLen % 2 != 0 || hexLen / 2 > maxLen) {
+        return -1;
+    }
+
+    for (size_t i = 0; i < hexLen; i += 2) {
+        char hexByte[3] = {hexStr[i], hexStr[i + 1], '\0'};
+        bytes[i / 2] = (uint8_t)strtol(hexByte, NULL, 16);
+    }
+
+    return hexLen / 2;
+}
+
+/**
+ * @brief 获取已使用的密钥ID列表
+ */
+JSIValue CipherModule::GetUsedKeyIds(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // 提前声明所有变量
+    JSIValue undefValue = JSI::CreateUndefined();
+    JSIValue context = JSI::CreateUndefined();
+    JSIValue success = JSI::CreateUndefined();
+    JSIValue fail = JSI::CreateUndefined();
+    JSIValue countValue = JSI::CreateUndefined();
+    uint16_t maxCount = MAX_KEY_IDS_COUNT;
+    uint16_t *usedIds = NULL;
+    uint16_t actualCount = 0;
+    char *hexString = NULL;
+    
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetUsedKeyIdsJSI args error.");
+        goto release;
+    }
+
+    context = JSI::AcquireValue(thisVal);
+    success = JSI::GetNamedProperty(args[0], "success");
+    fail = JSI::GetNamedProperty(args[0], "fail");
+
+    // 获取count参数,默认为MAX_KEY_IDS_COUNT
+    countValue = JSI::GetNamedProperty(args[0], "count");
+    if (!JSI::ValueIsUndefined(countValue)) {
+        maxCount = (uint16_t)JSI::ValueToNumber(countValue);
+        if (maxCount > MAX_KEY_IDS_COUNT) {
+            maxCount = MAX_KEY_IDS_COUNT;
+        }
+    }
+
+    usedIds = (uint16_t*)APPV_MALLOC(maxCount * sizeof(uint16_t));
+    if (usedIds == NULL) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetUsedKeyIds: memory allocation failed");
+        CipherMsgToJS("Memory allocation failed", context, fail);
+        goto release;
+    }
+
+    actualCount = InnerGetUsedKeyIds(usedIds, maxCount);
+    
+    if (actualCount == 0) {
+        HILOG_INFO(HILOG_MODULE_ACE, "No used key IDs found");
+        CipherMsgToJS("", context, success);
+        goto release;
+    }
+
+    // 将密钥ID数组转换为十六进制字符串
+    hexString = KeyIdsToHexString(usedIds, actualCount);
+    if (hexString != NULL) {
+        CipherMsgToJS(hexString, context, success);
+    } else {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetUsedKeyIds: hex string conversion failed");
+        CipherMsgToJS("Data conversion failed", context, fail);
+    }
+
+release:
+    // 释放所有分配的内存
+    APPV_FREE(usedIds);
+    APPV_FREE(hexString);
+    JSI::ReleaseValueList(countValue, success, fail, context, ARGS_END);
+    return undefValue;
+}
+
+/**
+ * @brief 获取可用的密钥ID列表
+ */
+JSIValue CipherModule::GetAvailableKeyIds(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // 提前声明所有变量
+    JSIValue undefValue = JSI::CreateUndefined();
+    JSIValue context = JSI::CreateUndefined();
+    JSIValue success = JSI::CreateUndefined();
+    JSIValue fail = JSI::CreateUndefined();
+    JSIValue countValue = JSI::CreateUndefined();
+    uint16_t maxCount = MAX_KEY_IDS_COUNT;
+    uint16_t *availableIds = NULL;
+    uint16_t actualCount = 0;
+    char *hexString = NULL;
+    
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetAvailableKeyIdsJSI args error.");
+        goto release;
+    }
+
+    context = JSI::AcquireValue(thisVal);
+    success = JSI::GetNamedProperty(args[0], "success");
+    fail = JSI::GetNamedProperty(args[0], "fail");
+
+    // 获取count参数,默认为MAX_KEY_IDS_COUNT
+    countValue = JSI::GetNamedProperty(args[0], "count");
+    if (!JSI::ValueIsUndefined(countValue)) {
+        maxCount = (uint16_t)JSI::ValueToNumber(countValue);
+        if (maxCount > MAX_KEY_IDS_COUNT) {
+            maxCount = MAX_KEY_IDS_COUNT;
+        }
+    }
+
+    availableIds = (uint16_t*)APPV_MALLOC(maxCount * sizeof(uint16_t));
+    if (availableIds == NULL) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetAvailableKeyIds: memory allocation failed");
+        CipherMsgToJS("Memory allocation failed", context, fail);
+        goto release;
+    }
+
+    actualCount = InnerGetAvailableKeyIds(availableIds, maxCount);
+    if (actualCount == 0) {
+        HILOG_INFO(HILOG_MODULE_ACE, "No available key IDs found");
+        CipherMsgToJS("", context, success);
+        goto release;
+    }
+
+    // 将密钥ID数组转换为十六进制字符串
+    hexString = KeyIdsToHexString(availableIds, actualCount);
+    if (hexString != NULL) {
+        CipherMsgToJS(hexString, context, success);
+    } else {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetAvailableKeyIds: hex string conversion failed");
+        CipherMsgToJS("Data conversion failed", context, fail);
+    }
+
+release:
+    // 释放所有分配的内存
+    APPV_FREE(availableIds);
+    APPV_FREE(hexString);
+    JSI::ReleaseValueList(countValue, success, fail, context, ARGS_END);
+    return undefValue;
+}
+
+/**
+ * @brief 删除密钥
+ */
+JSIValue CipherModule::DeleteKeyFromNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // 提前声明所有变量
+    JSIValue undefValue = JSI::CreateUndefined();
+    JSIValue context = JSI::CreateUndefined();
+    JSIValue success = JSI::CreateUndefined();
+    JSIValue fail = JSI::CreateUndefined();
+    JSIValue keyIdValue = JSI::CreateUndefined();
+    uint16_t keyId = 0;
+    int32_t ret = 0;
+    
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "DeleteKeyFromNvJSI args error.");
+        goto release;
+    }
+
+    context = JSI::AcquireValue(thisVal);
+    success = JSI::GetNamedProperty(args[0], "success");
+    fail = JSI::GetNamedProperty(args[0], "fail");
+
+    // 获取keyId参数
+    keyIdValue = JSI::GetNamedProperty(args[0], "keyId");
+    if (JSI::ValueIsUndefined(keyIdValue)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "DeleteKeyFromNvJSI: keyId is required");
+        CipherMsgToJS("keyId is required", context, fail);
+        goto release;
+    }
+
+    keyId = (uint16_t)JSI::ValueToNumber(keyIdValue);
+    
+    ret = InnerDeleteKeyFromNv(keyId);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "DeleteKeyFromNv failed: %d", ret);
+        CipherMsgToJS("Key deleted failed", context, fail);
+    } else {
+        CipherMsgToJS("Key deleted successfully", context, success);
+    }
+
+release:
+    JSI::ReleaseValueList(keyIdValue, success, fail, context, ARGS_END);
+    return undefValue;
+}
+
+/**
+ * @brief 读取密钥
+ */
+JSIValue CipherModule::GetKeyFromNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum) {
+    // 提前声明所有变量
+    JSIValue undefValue = JSI::CreateUndefined();
+    JSIValue context = JSI::CreateUndefined();
+    JSIValue success = JSI::CreateUndefined();
+    JSIValue fail = JSI::CreateUndefined();
+    JSIValue keyIdValue = JSI::CreateUndefined();
+    uint16_t keyId = 0;
+    uint8_t *keyData = NULL;
+    int32_t ret = 0;
+    char *hexKey = NULL;
+    uint16_t actualKeyLen = 0; // 新增:实际密钥长度
+
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetKeyFromNvJSI args error.");
+        goto release;
+    }
+
+    context = JSI::AcquireValue(thisVal);
+    success = JSI::GetNamedProperty(args[0], "success");
+    fail = JSI::GetNamedProperty(args[0], "fail");
+
+    // 获取keyId参数
+    keyIdValue = JSI::GetNamedProperty(args[0], "keyId");
+    if (JSI::ValueIsUndefined(keyIdValue)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetKeyFromNvJSI: keyId is required");
+        CipherMsgToJS("keyId is required", context, fail);
+        goto release;
+    }
+
+    keyId = (uint16_t)JSI::ValueToNumber(keyIdValue);
+
+    keyData = (uint8_t*)APPV_MALLOC(UT_NV_MAX_LENGTH);
+    if (keyData == NULL) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetKeyFromNv: memory allocation failed");
+        CipherMsgToJS("Memory allocation failed", context, fail);
+        goto release;
+    }
+
+    // 修改:调用支持实际长度的InnerGetKeyFromNv
+    ret = InnerGetKeyFromNv(keyId, keyData, &actualKeyLen);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetKeyFromNv failed: %d", ret);
+        CipherMsgToJS("Get key failed!", context, fail);
+    } else {
+        // 修改:使用实际长度转换十六进制字符串
+        hexKey = BytesToHexString(keyData, actualKeyLen);
+        if (hexKey != NULL) {
+            CipherMsgToJS(hexKey, context, success);
+        } else {
+            CipherMsgToJS("Key data format conversion failed", context, fail);
+        }
+    }
+
+release:
+    // 释放所有分配的内存
+    APPV_FREE(keyData);
+    APPV_FREE(hexKey);
+    JSI::ReleaseValueList(keyIdValue, success, fail, context, ARGS_END);
+    return undefValue;
+}
+
+/**
+ * @brief 保存密钥
+ */
+/**
+ * @brief 保存密钥 - 优化内存使用
+ */
+JSIValue CipherModule::SaveKeyToNv(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum) {
+    // 提前声明所有变量
+    int32_t ret = 0;
+    uint8_t *keyData = NULL;
+    uint16_t keyId = 0;
+    bool overwrite = false;
+    int keyLen = 0;
+    char *keyDataHex = NULL;
+    size_t hexLen = 0;
+    size_t actualDataLen = 0;
+
+    JSIValue undefValue = JSI::CreateUndefined();
+    JSIValue context = JSI::CreateUndefined();
+    JSIValue success = JSI::CreateUndefined();
+    JSIValue fail = JSI::CreateUndefined();
+    JSIValue keyIdValue = JSI::CreateUndefined();
+    JSIValue keyDataValue = JSI::CreateUndefined();
+    JSIValue overwriteValue = JSI::CreateUndefined();
+    
+    if ((args == nullptr) || argsNum == 0 || JSI::ValueIsUndefined(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI args error.");
+        goto release;
+    }
+
+    context = JSI::AcquireValue(thisVal);
+    success = JSI::GetNamedProperty(args[0], "success");
+    fail = JSI::GetNamedProperty(args[0], "fail");
+
+    // 获取必需参数
+    keyIdValue = JSI::GetNamedProperty(args[0], "keyId");
+    keyDataValue = JSI::GetNamedProperty(args[0], "keyData");
+    overwriteValue = JSI::GetNamedProperty(args[0], "overwrite");
+
+    if (JSI::ValueIsUndefined(keyIdValue) || JSI::ValueIsUndefined(keyDataValue)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyId and keyData are required");
+        CipherMsgToJS("keyId and keyData are required", context, fail);
+        goto release;
+    }
+
+    keyId = (uint16_t)JSI::ValueToNumber(keyIdValue);
+    overwrite = JSI::ValueToBoolean(overwriteValue);
+    
+    // 获取密钥数据字符串
+    keyDataHex = JSI::GetStringProperty(args[0], "keyData");
+    if (keyDataHex == NULL) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyData is null");
+        CipherMsgToJS("keyData is null", context, fail);
+        goto release;
+    }
+    
+    // 计算实际需要的缓冲区大小
+    hexLen = strlen(keyDataHex);
+    if (hexLen % 2 != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyData format error (odd length)");
+        CipherMsgToJS("keyData format error (must be even length hex string)", context, fail);
+        JSI::ReleaseString(keyDataHex);
+        goto release;
+    }
+    
+    actualDataLen = hexLen / 2;
+    if (actualDataLen > UT_NV_MAX_LENGTH) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyData too long");
+        CipherMsgToJS("keyData too long", context, fail);
+        JSI::ReleaseString(keyDataHex);
+        goto release;
+    }
+    
+    // 修改:按实际长度分配内存
+    keyData = (uint8_t*)APPV_MALLOC(actualDataLen);
+    if (keyData == NULL) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNv: memory allocation failed");
+        CipherMsgToJS("Memory allocation failed", context, fail);
+        JSI::ReleaseString(keyDataHex);
+        goto release;
+    }
+    
+    // 将十六进制字符串转换为字节数组
+    keyLen = HexStringToBytes(keyDataHex, keyData, actualDataLen);
+    if (keyLen <= 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNvJSI: keyData format error");
+        CipherMsgToJS("keyData format error (must be hex string)", context, fail);
+        JSI::ReleaseString(keyDataHex);
+        goto release;
+    }
+    
+    ret = InnerSaveKeyToNv(keyData, keyLen, keyId, overwrite);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "SaveKeyToNv failed: %d", ret);
+        CipherMsgToJS("Save key failed!", context, fail);
+    } else {
+        CipherMsgToJS("Key saved successfully", context, success);
+    }
+    
+    JSI::ReleaseString(keyDataHex);
+
+release:
+    // 释放所有分配的内存
+    APPV_FREE(keyData);
+    JSI::ReleaseValueList(keyIdValue, keyDataValue, overwriteValue, success, fail, context, ARGS_END);
+    return undefValue;
 }
 #endif
 // OHOS END
@@ -441,6 +1299,19 @@ void InitCipherModule(JSIValue exports)
     JSI::SetModuleAPI(exports, "shaInit", CipherModule::Sha256SubStarts);
     JSI::SetModuleAPI(exports, "shaUpdate", CipherModule::Sha256SubUpdate);
     JSI::SetModuleAPI(exports, "shaFinal", CipherModule::Sha256SubFinish);
+
+    JSI::SetModuleAPI(exports, "hmacSha256", CipherModule::HmacSha256);
+    JSI::SetModuleAPI(exports, "hmacSha256Bytes", CipherModule::HmacSha256Bytes);
+    JSI::SetModuleAPI(exports, "md5FromBytes", CipherModule::Md5FromBytes);
+    JSI::SetModuleAPI(exports, "md5FromString", CipherModule::Md5FromString);
+    JSI::SetModuleAPI(exports, "base64Encode", CipherModule::Base64Encode);
+    JSI::SetModuleAPI(exports, "base64Decode", CipherModule::Base64Decode);
+    JSI::SetModuleAPI(exports, "getUsedKeyIds", CipherModule::GetUsedKeyIds);
+    JSI::SetModuleAPI(exports, "getAvailableKeyIds", CipherModule::GetAvailableKeyIds);
+    JSI::SetModuleAPI(exports, "deleteKeyFromNv", CipherModule::DeleteKeyFromNv);
+    JSI::SetModuleAPI(exports, "getKeyFromNv", CipherModule::GetKeyFromNv);
+    JSI::SetModuleAPI(exports, "saveKeyToNv", CipherModule::SaveKeyToNv);
+
     JSI::SetOnDestroy(exports, CipherModule::OnDestroy);
 #endif
 }
@@ -449,6 +1320,30 @@ void InitCipherModule(JSIValue exports)
 }  // namespace OHOS
 // OHOS START
 #ifdef HUKS_LITEWEARABLE_SUPPORT_ENABLED
+static void ExecuteSendMsgToJS(void *data)
+{
+    if (data == nullptr) {
+        return;
+    }
+    CipherMsgParams *params = static_cast<CipherMsgParams *>(data);
+
+    char *msgBody = params->msgBody;
+    OHOS::ACELite::JSIValue callback = params->callback;
+    OHOS::ACELite::JSIValue context = params->context;
+    params->msgBody = nullptr;
+    delete params;
+    params = nullptr;
+
+    OHOS::ACELite::JSIValue dataInfo = OHOS::ACELite::JSI::CreateString(msgBody);
+    OHOS::ACELite::JSIValue callbackArgv[OHOS::ACELite::ARGC_ONE] = {dataInfo};
+    OHOS::ACELite::JSI::CallFunction(callback, context, callbackArgv, OHOS::ACELite::ARGC_ONE);
+    OHOS::ACELite::JSI::ReleaseValue(dataInfo);
+    OHOS::ACELite::JSI::ReleaseValue(callback);
+    OHOS::ACELite::JSI::ReleaseValue(context);
+    OHOS::ACELite::ace_free(msgBody);
+    return;
+}
+
 int32_t CipherMsgToJS(const char *msgBody, OHOS::ACELite::JSIValue context, OHOS::ACELite::JSIValue callback)
 {
     CipherMsgParams *params = new CipherMsgParams();
@@ -456,11 +1351,13 @@ int32_t CipherMsgToJS(const char *msgBody, OHOS::ACELite::JSIValue context, OHOS
         HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for params");
         return -1;
     }
-    params->context = context;
-    params->callback = callback;
+    params->context = OHOS::ACELite::JSI::AcquireValue(context);
+    params->callback = OHOS::ACELite::JSI::AcquireValue(callback);
     int32_t copyRet = OHOS::ACELite::CopyStr(&params->msgBody, msgBody);
     if (copyRet != 0) {
         HILOG_ERROR(HILOG_MODULE_ACE, "Failed to copy msgBody");
+        OHOS::ACELite::JSI::ReleaseValue(params->callback);
+        OHOS::ACELite::JSI::ReleaseValue(params->context);
         OHOS::ACELite::ace_free(params->msgBody);
         params->msgBody = nullptr;
         delete params;
@@ -468,9 +1365,11 @@ int32_t CipherMsgToJS(const char *msgBody, OHOS::ACELite::JSIValue context, OHOS
         return copyRet;
     }
     bool ret =
-        OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(OHOS::ACELite::ExecuteSendMsgToJS, static_cast<void *>(params));
+        OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(ExecuteSendMsgToJS, static_cast<void *>(params));
     if (!ret) {
         HILOG_ERROR(HILOG_MODULE_ACE, "Failed to dispatch async work");
+        OHOS::ACELite::JSI::ReleaseValue(params->callback);
+        OHOS::ACELite::JSI::ReleaseValue(params->context);
         OHOS::ACELite::ace_free(params->msgBody);
         params->msgBody = nullptr;
         delete params;
index 540175f..0871593 100644 (file)
@@ -79,4 +79,13 @@ int32_t SetOption(int32_t sensorTypeId, SensorUser *user, int32_t option)
         g_proxy = GetServiceProxy();\r
     }\r
     return SetOptionByProxy(g_proxy, sensorTypeId, user, option);\r
-}
\ No newline at end of file
+}\r
+// ohos-hisi begin\r
+int32_t GetSensorData(int32_t sensorTypeId, SensorUser *user, void *sensorData)\r
+{\r
+    if (g_proxy == NULL) {\r
+        g_proxy = GetServiceProxy();\r
+    }\r
+    return GetSensorDataByProxy(g_proxy, sensorTypeId, user, sensorData);\r
+}\r
+// ohos-hisi end
\ No newline at end of file
index b2f5440..abda9b6 100644 (file)
@@ -114,3 +114,16 @@ int32_t SetOptionByProxy(const void *proxy, int32_t sensorId, const SensorUser *
     SensorFeatureApi *sensor = (SensorFeatureApi *)proxy;\r
     return sensor->SetOption(sensorId, user, option);\r
 }\r
+\r
+// ohos-hisi begin\r
+int32_t GetSensorDataByProxy(const void *proxy, int32_t sensorId, const SensorUser *user, void *sensorData)\r
+{\r
+    HILOG_DEBUG(HILOG_MODULE_APP, "%s begin", __func__);\r
+    if ((proxy == NULL) || (user == NULL)) {\r
+        HILOG_ERROR(HILOG_MODULE_APP, "%s proxy or user is NULL", __func__);\r
+        return SENSOR_ERROR_INVALID_PARAM;\r
+    }\r
+    SensorFeatureApi *sensor = (SensorFeatureApi *)proxy;\r
+    return sensor->GetData(sensorId, user, sensorData);\r
+}\r
+// ohos-hisi end
\ No newline at end of file
index 4654751..c26d27f 100644 (file)
@@ -133,7 +133,20 @@ int32_t DeactivateSensor(int32_t sensorTypeId, SensorUser *user);
  * @since 5\r
  */\r
 int32_t SetMode(int32_t sensorTypeId, SensorUser *user, int32_t mode);\r
-\r
+// ohos-hisi begin\r
+/**\r
+* @brief Get the data of the specified sensor stored.\r
+*\r
+* @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.\r
+* @param user Indicates the pointer to the sensor subscriber that requests sensor data.\r
+* For details, see {@link SensorUser}. A subscriber can obtain data from only one sensor.\r
+* @param sensorData Indicates the data of sensor stored For details, see {@link SensorData}.\r
+* @return Returns <b>0</b> if get sensor data successfully; returns a non-zero value otherwise.\r
+*\r
+* @since 5\r
+*/\r
+int32_t GetSensorData(int32_t sensorTypeId, SensorUser *user, void *sensorData);\r
+// ohos-hisi end\r
 #ifdef __cplusplus\r
 #if __cplusplus\r
 }\r
index e02b04c..71bbaf9 100644 (file)
@@ -51,7 +51,7 @@ extern "C" {
 #define SENSOR_OK 0\r
 #ifndef SENSOR_NAME_MAX_LEN\r
 /** Maximum length of the sensor name */\r
-#define SENSOR_NAME_MAX_LEN 16\r
+#define SENSOR_NAME_MAX_LEN 32\r
 #endif /* SENSOR_NAME_MAX_LEN */\r
 \r
 #ifndef SENSOR_USER_DATA_SIZE\r
@@ -101,7 +101,11 @@ typedef enum SensorTypeId {
     SENSOR_TYPE_ID_DEVICE_ORIENTATION = 279,    /**< Device orientation sensor */\r
     SENSOR_TYPE_ID_WEAR_DETECTION = 280,        /**< Wear detection sensor */\r
     SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED = 281,   /**< Uncalibrated acceleration sensor */\r
-    SENSOR_TYPE_ID_MAX = 0xFFF,      /**< Maximum number of sensor type IDs*/\r
+       // ohos-hisi begin\r
+    SENSOR_TYPE_ID_VSENSOR_EXPAND_START        = 0x1000,   /* 4096 */\r
+    SENSOR_TYPE_ID_VSENSOR_ACCELEROMETER_ALG_SIMU,         /**< ACCELEROMETER ALG sensor */\r
+    SENSOR_TYPE_ID_MAX,                                    /**< Maximum number of sensor types */\r
+       // ohos-hisi end\r
 } SensorTypeId;\r
 \r
 /**\r
@@ -117,8 +121,12 @@ typedef struct SensorInfo {
     int32_t sensorTypeId;  /**< Sensor type ID */\r
     int32_t sensorId;      /**< Sensor ID */\r
     float maxRange;        /**< Maximum measurement range of the sensor */\r
-    float precision;       /**< Sensor accuracy */\r
+    float accuracy;       /**< Sensor accuracy */\r
     float power;           /**< Sensor power */\r
+    int64_t minDelay;     /**< Minimum sample period allowed in microseconds */\r
+    int64_t maxDelay;     /**< Maxmum sample period allowed in microseconds */\r
+    uint32_t fifoMaxEventCount; /**< Maxmum number of events of this sensor that could be batched */\r
+    uint32_t reserved;    /**< Reserved fields */\r
 } SensorInfo;\r
 \r
 /**\r
index 2af904c..59c6209 100644 (file)
@@ -66,6 +66,18 @@ typedef struct PressureData {
     uint32_t dataValid;\r
 } PressureData;\r
 \r
+/**\r
+ * @brief Defines the sensor data.\r
+ *\r
+ * @since 5\r
+ */\r
+typedef struct SensorData {\r
+    int64_t timestamp;     /**< Time when sensor data was reported */\r
+    uint32_t batchCnt;     /**< Sensor batch cnt */\r
+    uint8_t *data;         /**< Sensor data */\r
+    uint32_t dataLen;      /**< Sensor data length */\r
+} SensorData;\r
+\r
 #ifdef __cplusplus\r
 #if __cplusplus\r
 }\r
index 5a601bb..2d32968 100644 (file)
@@ -172,6 +172,36 @@ public:
     {
         directionAccuracy_ = directionAccuracy;
     }
+
+    inline double GetNorthVelocity() const
+    {
+        return velocityNorth_;
+    }
+
+    inline void SetNorthVelocity(double velocityNorth)
+    {
+        velocityNorth_ = velocityNorth;
+    }
+
+    inline double GetEastVelocity() const
+    {
+        return velocityEast_;
+    }
+
+    inline void SetEastVelocity(double velocityEast)
+    {
+        velocityEast_ = velocityEast;
+    }
+
+    inline double GetDescendVelocity() const
+    {
+        return velocityDescend_;
+    }
+
+    inline void SetDescendVelocity(double velocityDescend)
+    {
+        velocityDescend_ = velocityDescend;
+    }
     
     inline int32_t GetLocationSourceType() const
     {
@@ -183,6 +213,16 @@ public:
         locationSourceType_ = locationSourceType;
     }
 
+    inline int32_t GetStatusNumber() const
+    {
+        return statusNumber_;
+    }
+
+    inline void SetStatusNumber(int32_t statusNumber)
+    {
+        statusNumber_ = statusNumber;
+    }
+
     inline std::string GetUuid() const
     {
         return uuid_;
@@ -217,8 +257,12 @@ private:
     double altitudeAccuracy_;
     double speedAccuracy_;
     double directionAccuracy_;
+    float velocityNorth_;
+    float velocityEast_;
+    float velocityDescend_;
     int64_t uncertaintyOfTimeSinceBoot_;
     int32_t locationSourceType_;
+    int32_t statusNumber_;
     std::string uuid_;
 };
 } // namespace Location
index 4a9a24c..fcc7048 100644 (file)
@@ -89,9 +89,11 @@ public:
 
     void OnLocationReport(const std::shared_ptr<Location> &location) override
     {
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "OnLocationReport Lat:%.3f Long:%.3f Alt:%.3f Speed:%.3f dir:%.3f\n",
+        WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "OnLocationReport Lat:%.3f Long:%.3f Alt:%.3f Speed:%.3f dir:%.3f"
+                      " AltitudeAccuracy:%.3f SpeedAccuracy:%.3f DirectionAccuracy:%.3f Nvelocity:%.3f Evelocity:%.3f DVelocity:%.3f statusNumber:%d\n",
                       location->GetLatitude(), location->GetLongitude(), location->GetAltitude(),
-                      location->GetSpeed(), location->GetDirection());
+                      location->GetSpeed(), location->GetDirection(), location->GetAltitudeAccuracy(), location->GetSpeedAccuracy(), location->GetDirectionAccuracy(),
+                      location->GetNorthVelocity(), location->GetEastVelocity(), location->GetDescendVelocity(), location->GetStatusNumber());
     }
 
     void OnErrorReport(const int errorCode) override
index ae3237c..6f59d92 100644 (file)
@@ -62,9 +62,13 @@ int32_t GnssEventCallback::ReportLocation(const LocationInfo& location)
     locationNew->SetAltitudeAccuracy(location.verticalAccuracy);
     locationNew->SetSpeedAccuracy(location.speedAccuracy);
     locationNew->SetDirectionAccuracy(location.bearingAccuracy);
+    locationNew->SetNorthVelocity(location.velocityNorth);
+    locationNew->SetEastVelocity(location.velocityEast);
+    locationNew->SetDescendVelocity(location.velocityDescend);
     locationNew->SetTimeStamp(location.timeForFix);
     locationNew->SetTimeSinceBoot(location.timeSinceBoot);
     locationNew->SetUncertaintyOfTimeSinceBoot(location.timeUncertainty);
+    locationNew->SetStatusNumber(location.signal);
     locationNew->SetLocationSourceType(LocationSourceType::GNSS_TYPE);
 
     // add dummy sv if needed
index c4a61c2..2b6373a 100644 (file)
@@ -34,8 +34,12 @@ Location::Location()
     altitudeAccuracy_ = 0.0;
     speedAccuracy_ = 0.0;
     directionAccuracy_ = 0.0;
+    velocityNorth_ = 0.0;
+    velocityEast_ = 0.0;
+    velocityDescend_ = 0.0;
     uncertaintyOfTimeSinceBoot_ = 0;
     locationSourceType_ = 0;
+    statusNumber_ = 0;
     uuid_ = "";
 }
 
@@ -55,8 +59,12 @@ Location::Location(Location& location)
     altitudeAccuracy_ = location.GetAltitudeAccuracy();
     speedAccuracy_ = location.GetSpeedAccuracy();
     directionAccuracy_ = location.GetDirectionAccuracy();
+    velocityNorth_ = location.GetNorthVelocity();
+    velocityEast_ = location.GetEastVelocity();
+    velocityDescend_ = location.GetDescendVelocity();
     uncertaintyOfTimeSinceBoot_ = location.GetUncertaintyOfTimeSinceBoot();
     locationSourceType_ = location.GetLocationSourceType();
+    statusNumber_ = location.GetStatusNumber();
     uuid_ = location.GetUuid();
 }
 
@@ -73,8 +81,12 @@ std::string Location::ToString() const
         ", altitudeAccuracy : " + std::to_string(altitudeAccuracy_) +
         ", speedAccuracy : " + std::to_string(speedAccuracy_) +
         ", directionAccuracy : " + std::to_string(directionAccuracy_) +
+        ", velocityEast : " + std::to_string(velocityEast_) +
+        ", velocityNorth_ : " + std::to_string(velocityNorth_) +
+        ", velocityDescend_ : " + std::to_string(velocityDescend_) +
         ", uncertaintyOfTimeSinceBoot : " + std::to_string(uncertaintyOfTimeSinceBoot_) +
         ", locationSourceType : " + std::to_string(locationSourceType_) +
+        ", statusNumber : " + std::to_string(statusNumber_) +
         ", uuid : " + uuid_;
     return str;
 }
index 1d30f0d..b87d421 100644 (file)
@@ -38,6 +38,7 @@ static int32_t SensorSubscribe(SensorTypeId sensorTypeId);
 static int32_t SensorActivate(SensorTypeId sensorTypeId);
 static int32_t SensorUnsubscribe(SensorTypeId sensorTypeId);
 static int32_t SensorDeactivate(SensorTypeId sensorTypeId);
+static int32_t SensorGetData(SensorTypeId sensorTypeId);
 
 typedef struct {
     char cmd[SENSOR_CMD_LEN_MAX];
@@ -50,6 +51,7 @@ static FuncsMap g_sensorFuncs[] = {
     {"activate", SensorActivate},
     {"unsubscribe", SensorUnsubscribe},
     {"deactivate", SensorDeactivate},
+    {"getdata", SensorGetData},
 };
 
 typedef struct {
@@ -361,6 +363,39 @@ static int32_t SensorDeactivate(SensorTypeId sensorTypeId)
     return SENSOR_OK;
 }
 
+static int32_t SensorGetData(SensorTypeId sensorTypeId)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "getData :%d\n", sensorTypeId);
+    SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);
+    if (sensorDev == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetSensorIdBySensorDevIndex failed\n");
+        return SENSOR_ERROR_UNKNOWN;
+    }
+    SensorData *sensorData = (SensorData *)malloc(sizeof(SensorData));
+    if (sensorData == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "malloc failed\n");
+        return SENSOR_ERROR_UNKNOWN;
+    }
+    int32_t errCode = GetSensorData(sensorTypeId, &sensorDev->user, sensorData);
+    if (errCode != SENSOR_OK) {
+        free(sensorData);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetSensorData failed:%d\n", errCode);
+        return errCode;
+    }
+    AccelData *accData = (AccelData *)sensorData->data;
+    for (uint32_t i = 0; i < sensorData->batchCnt; i++) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+            "SensorData dataX:%x, datY:%x, dataZ:%x\n",
+            accData[i].axisX,
+            accData[i].axisY,
+            accData[i].axisZ);
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SensorData batchCnt:%u timestamp:%lld\n",
+        sensorData->batchCnt, sensorData->timestamp);
+    free(sensorData);
+    return SENSOR_OK;
+}
+
 static SensorTypeId GetSensorIdByParam(const char *argv)
 {
     if (argv == NULL) {
index 3edd20e..51dae8a 100644 (file)
@@ -55,6 +55,9 @@ typedef struct SensorFeatureApi {
     int32_t (*UnsubscribeSensor)(int32_t sensorTypeId, const SensorUser *user);\r
     int32_t (*SetMode)(int32_t sensorTypeId, const SensorUser *user, int32_t mode);\r
     int32_t (*SetOption)(int32_t sensorTypeId, const SensorUser *user, int32_t option);\r
+// ohos-hisi begin\r
+    int32_t (*GetData)(int32_t sensorTypeId, const SensorUser *user, void *sensorData);\r
+// ohos-hisi end\r
 } SensorFeatureApi;\r
 \r
 typedef struct SensorService {\r
index ff3d59b..6374e2e 100644 (file)
@@ -52,6 +52,9 @@ int32_t UnsubscribeSensorInvoke(SensorFeatureApi *defaultApi, IpcIo *req, IpcIo
 int32_t SetModeInvoke(SensorFeatureApi *defaultApi, IpcIo *req, IpcIo *reply);\r
 int32_t SetOptionInvoke(SensorFeatureApi *defaultApi, IpcIo *req, IpcIo *reply);\r
 void SetSvcIdentity(IpcIo *req, const IpcIo *reply);\r
+// ohos-hisi begin\r
+int32_t GetSensorDataImpl(int32_t sensorId, const SensorUser *user, void *sensorData);\r
+// ohos-hisi end\r
 #ifdef __cplusplus\r
 #if __cplusplus\r
 }\r
index 56a82f9..2e20980 100644 (file)
@@ -47,6 +47,9 @@ static SensorService g_sensorService = {
     .UnsubscribeSensor = UnsubscribeSensorImpl,\r
     .SetMode = SetModeImpl,\r
     .SetOption = SetOptionImpl,\r
+// ohos-hisi begin\r
+    .GetData = GetSensorDataImpl,\r
+// ohos-hisi end\r
     IPROXY_END,\r
 };\r
 \r
index 69eb121..7179b07 100644 (file)
@@ -255,3 +255,15 @@ int32_t SetOptionImpl(int32_t sensorTypeId, const SensorUser *user, int32_t opti
     }\r
     return SENSOR_OK;\r
 }\r
+\r
+// ohos-hisi begin\r
+int32_t GetSensorDataImpl(int32_t sensorId, const SensorUser *user, void *sensorData)\r
+{\r
+    HILOG_DEBUG(HILOG_MODULE_APP, "[SERVICE:%s]: %s begin",\r
+        SENSOR_SERVICE, __func__);\r
+    if (!CheckSensorTypeId(sensorId)) {\r
+        return SENSOR_ERROR_INVALID_ID;\r
+    }\r
+    return g_sensorDevice->GetSensorData(sensorId, (SensorData *)sensorData);\r
+}\r
+// ohos-hisi end
\ No newline at end of file
index ea4ee78..e5ddc9e 100644 (file)
@@ -32,11 +32,11 @@ static const char OHOS_SOFTWARE_MODEL[] = {"1.0.0"};
 static const char OHOS_HARDWARE_MODEL[] = {"FD230V10"};\r
 static const char OHOS_HARDWARE_PROFILE[] = {"aout:true,display:true"};\r
 static const char OHOS_BOOTLOADER_VERSION[] = {"bootloader"};\r
-static const char OHOS_SECURITY_PATCH_TAG[] = {"2024/12/01"};\r
+static const char OHOS_SECURITY_PATCH_TAG[] = {"2025/06/17"};\r
 static const char OHOS_ABI_LIST[] = {"riscv-liteos"};\r
 static const char OHOS_SERIAL[] = {"****"};  // provided by OEM.\r
 const char g_roBuildOs[] = {"OpenHarmony"};\r
-const char g_roBuildVerShow[] = {"OpenHarmony 5.0.1.115"};\r
+const char g_roBuildVerShow[] = {"OpenHarmony 5.1.1.115"};\r
 const int g_roFirstApiLevel = 1;\r
 const char INCREMENTAL_VERSION[] = {"version"};\r
 const char BUILD_TYPE[] = {"BUILD_TYPE"};\r
index 820ba13..8acc631 100644 (file)
@@ -27,7 +27,7 @@
 #define FILE_RO "ro."\r
 #define VERSION_ID_LEN 256\r
 #define PROPERTY_MAX_LENGTH 2048\r
-#define INCREMENTAL_VERSION "version"\r
+#define INCREMENTAL_VERSION "OpenHarmony 5.1 Release"\r
 #define BUILD_TYPE "release"\r
 #define BUILD_USER "luozheng"\r
 #define BUILD_HOST "linux"\r
 #define BT_MAC_BUFF_SIZE 6\r
 #define BT_MAC_BUFF_LEN 17\r
 \r
-static char g_roBuildOs[] = {"OpenHarmony-5.0.1.115"};\r
+static char g_roBuildOs[] = {"OpenHarmony-5.1.1.115"};\r
 static char g_roBuildVerShow[] = {"1.0.0"};\r
 static char g_roSdkApiLevel[] = {"13"};\r
 static char g_roFirstApiLevel[] = {"1"};\r
 static const char OHOS_OS_NAME[] = { "OpenHarmony" };\r
 static const int OHOS_SDK_API_VERSION = 13;\r
-static const char OHOS_SECURITY_PATCH_TAG[] = {"2024/12/01"};\r
+static const char OHOS_SECURITY_PATCH_TAG[] = {"2025/06/17"};\r
 static const char OHOS_RELEASE_TYPE[] = { "Release" };\r
 static const char OHOS_DEFAULT_VALUE[] = { "Default" };\r
 \r
 static const int MAJOR_VERSION = 5;\r
-static const int SENIOR_VERSION = 0;\r
-static const int FEATURE_VERSION = 0;\r
-static const int BUILD_VERSION = 0;\r
+static const int SENIOR_VERSION = 1;\r
+static const int FEATURE_VERSION = 1;\r
+static const int BUILD_VERSION = 115;\r
 \r
 static const char EMPTY_STR[] = { "" };\r
 \r
diff --git a/code/sdk/open_source/openharmony/base/startup/syspara_lite/src/文件夹1201patch合并提交 b/code/sdk/open_source/openharmony/base/startup/syspara_lite/src/文件夹1201patch合并提交
new file mode 100644 (file)
index 0000000..0065aa2
--- /dev/null
@@ -0,0 +1 @@
+文件夹1201patch合并提交
\ No newline at end of file
index 33a35ec..d91f264 100644 (file)
@@ -420,7 +420,7 @@ typedef enum {
     SOURCE_TYPE_BUT /**< Undefined source */
 } SourceType;
 
-#define URL_LEN 4096 /**< Indicates the URL length. */
+#define URL_LEN 256 /**< Indicates the URL length. */
 
 /**
  * @brief Defines the demuxer data source.
@@ -454,6 +454,8 @@ typedef enum {
     OUTPUT_FORMAT_HEIF = 3, /**< HEIF */
     OUTPUT_FORMAT_OGG = 4, /**< Ogg */
     OUTPUT_FORMAT_WAV = 5, /**< WAV */
+    OUTPUT_FORMAT_MP3 = 6, /**< mp3 */
+    OUTPUT_FORMAT_SILK = 7, /* Silk */
     OUTPUT_FORMAT_INVALID /**< Invalid format */
 } OutputFormat;
 
index 7ff4c38..bd810e7 100644 (file)
@@ -28,6 +28,7 @@
 #include "gnss_nmea_parse.h"
 #include "pm_definition.h"
 #include "pm.h"
+#include "osal_task.h"
 
 namespace OHOS {
 namespace HDI {
@@ -45,25 +46,30 @@ namespace {
 #define MSG_TYPE_BINRY 0
 #define MSG_TYPE_ASCII 1
 #define LISTEN_DATA_MAX_LINES 1000
-#define REPORT_MAX_BYTES 10000
 #define LISTEN_TIME_THR 1000
+#define GNSS_TASK_CREATE_OK_WAIT_TIMEOUT          1000 // ms
+#define GNSS_TASK_CREATE_TICK_TIME                50   // ms
 
 std::string g_gnssNmeaFile = "/user/gnss_nmea.log";
 
 typedef struct {
     bool gnssEnabled;
     bool gnssStarted;
+    bool gnssRunning;
     GnssCallbackStruct *gnssCallback;
     GnssInfo gnssInfo;
     GnssLocation location;
     GnssSatelliteStatus satStatus;
     ThreadId listenGnssDataThreadId;
+#ifdef SUPPORT_FILE
     std::ifstream gnssNmeaFp;
+#endif
 } GnssServiceContext;
 
 static GnssServiceContext g_gnssServiceCtx = {
     .gnssEnabled = false,
     .gnssStarted = false,
+    .gnssRunning = false,
     .gnssCallback = nullptr,
     .gnssInfo = {0},
     .location = {0},
@@ -93,6 +99,7 @@ static void ResetGnssInfo(GnssServiceContext *gnssServiceCtx)
     }
 }
 
+#ifdef SUPPORT_FILE
 static void ListenGnssData(void *argv)
 {
     LBSLOGI(HDI_GNSS, "enter ListenGnssData");
@@ -101,6 +108,8 @@ static void ListenGnssData(void *argv)
         LBSLOGE(HDI_GNSS, "ListenGnssData argv invalid");
         return;
     }
+    GnssNmeaInit();
+    gnssServiceCtx->gnssRunning = true;
     while (gnssServiceCtx->gnssStarted && g_gnssServiceCtx.gnssNmeaFp.good()) {
         std::string nmeaLine;
         while (getline(gnssServiceCtx->gnssNmeaFp, nmeaLine)) {
@@ -141,8 +150,90 @@ static void ListenGnssData(void *argv)
         gnssServiceCtx->gnssNmeaFp.clear();
         gnssServiceCtx->gnssNmeaFp.seekg(0, std::ios::beg);
     }
+    gnssServiceCtx->gnssRunning = false;
     LBSLOGI(HDI_GNSS, "exit ListenGnssData");
 }
+#else
+constexpr uint32_t REPORT_MAX_CNT = 27;
+constexpr uint32_t REPORT_MAX_BYTES = 512;
+static char g_nmeaData[REPORT_MAX_CNT][REPORT_MAX_BYTES] = {
+    "$GNGGA,021707.00,3045.804990,N,10353.991346,E,1,37,1.2,597.4,M,,M,,*6D",
+    "$GNGLL,3045.804990,N,10353.991346,E,021707.00,A,A*7E",
+    "$GNGSA,A,3,10,12,15,18,23,25,32,,,,,,2.4,1.2,2.1,1*3F",
+    "$GNGSA,A,3,67,68,69,77,78,79,82,83,84,,,,2.4,1.2,2.1,2*38",
+    "$GNGSA,A,3,3,5,15,24,25,34,36,,,,,,2.4,1.2,2.1,3*34",
+    "$GNGSA,A,3,9,11,13,14,16,24,25,26,28,33,38,39,2.4,1.2,2.1,4*05",
+    "$GNGSA,A,3,2,3,,,,,,,,,,,2.4,1.2,2.1,5*32",
+    "$GPGSV,2,1,07,10,51,332,29,12,18,104,26,15,08,071,22,18,32,179,22,1*6A",
+    "$GPGSV,2,2,07,23,68,068,15,25,17,145,35,32,41,285,44,1*5A",
+    "$GLGSV,3,1,09,67,29,054,27,68,44,350,43,69,19,298,45,77,24,044,21,1*72",
+    "$GLGSV,3,2,09,78,43,117,22,79,15,168,19,82,18,200,27,83,41,242,18,1*75",
+    "$GLGSV,3,3,09,84,22,318,18,1*4E",
+    "$GBGSV,6,1,22,01,34,119,,02,51,217,,03,55,166,,04,20,108,,1*71",
+    "$GBGSV,6,2,22,05,31,245,,09,59,202,18,11,10,191,30,13,75,039,21,1*78",
+    "$GBGSV,6,3,22,14,58,018,30,16,79,185,23,21,05,092,,24,50,130,27,1*7C",
+    "$GBGSV,6,4,22,25,19,186,35,26,33,059,16,27,05,316,,28,24,276,28,1*7C",
+    "$GBGSV,6,5,22,33,50,329,40,38,61,107,28,39,85,183,17,41,11,293,,1*7A",
+    "$GBGSV,6,6,22,42,45,061,19,43,19,211,23,1*72",
+    "$GQGSV,1,1,03,02,16,127,30,03,20,157,19,04,56,083,,1*52",
+    "$GAGSV,2,1,08,03,53,293,29,05,50,030,31,08,10,259,,15,42,304,42,7*7B",
+    "$GAGSV,2,2,08,24,18,089,24,25,15,141,36,34,59,213,27,36,18,167,18,7*7A",
+    "$GNRMC,021707.00,A,3045.804990,N,10353.991346,E,000.9,159.3,071124,,E,A,V*70",
+    "$GNVTG,159.3,T,159.3,M,000.9,N,001.7,K,A*32",
+    "$GNZDA,021707.00,07,11,2024,00,00*78",
+    "$PNTH000,6,,-91,0,,,,,1,1*11",
+    "$PNTH001,1.226969,2.06,1.61,15.72,0,39,108*2E",
+    "$PNTH002,021707.00,N,243.524682,3,200,0.166667,12,0.270406*44",
+};
+
+static void ListenGnssData(void *argv)
+{
+    LBSLOGI(HDI_GNSS, "enter ListenGnssData");
+    GnssServiceContext *gnssServiceCtx = (GnssServiceContext *)argv;
+    if (gnssServiceCtx == nullptr || gnssServiceCtx->gnssCallback == nullptr) {
+        LBSLOGE(HDI_GNSS, "ListenGnssData argv invalid");
+        return;
+    }
+    GnssNmeaInit();
+    gnssServiceCtx->gnssRunning = true;
+    while (gnssServiceCtx->gnssStarted) {
+        for (uint32_t i = 0; i < REPORT_MAX_CNT; i++) {
+            const char *nmeaStr = g_nmeaData[i];
+            int32_t nmeaLen = strlen(g_nmeaData[i]);
+            GnssNmeaFrameType nmeaType = GnssNmeaGetFrameType(nmeaStr, nmeaLen);
+            LBSLOGD(HDI_GNSS, "nmeaType:%d nmeaStr:%s nmeaLen:%d", nmeaType, nmeaStr, nmeaLen);
+            if (nmeaType >= GNSS_NMEA_FRAME_MAX) {
+                LBSLOGW(HDI_GNSS, "invalid nmeaStr:%s", nmeaStr);
+                continue;
+            }
+            if (nmeaType == GNSS_NMEA_FRAME_GGA) {
+                ResetGnssInfo(gnssServiceCtx);
+            }
+            gnssServiceCtx->gnssCallback->gnssCallback.nmeaUpdate(LocationGnssUtilsGetTimestampMS(), nmeaStr, nmeaLen);
+            int32_t ret =
+                GnssNmeaDecodeFrame(nmeaStr, nmeaLen, &gnssServiceCtx->gnssInfo);
+            if (ret != GNSS_SUCCESS) {
+                LBSLOGW(HDI_GNSS, "GnssNmeaDecodeFrame failed:%d", ret);
+            }
+            if (nmeaType == GNSS_NMEA_FRAME_TH002) {
+                ResetLocationSatelliteStatus(gnssServiceCtx);
+
+                ret = LocationGnssUtilsFillGnssLocation(&gnssServiceCtx->gnssInfo, &gnssServiceCtx->location);
+                if (ret == GNSS_SUCCESS) {
+                    gnssServiceCtx->gnssCallback->gnssCallback.locationUpdate(&gnssServiceCtx->location);
+                }
+                ret = LocationGnssUtilsFillAllSatelliteStatus(&gnssServiceCtx->gnssInfo, &gnssServiceCtx->satStatus);
+                if (ret == GNSS_SUCCESS) {
+                    gnssServiceCtx->gnssCallback->gnssCallback.satelliteStatusUpdate(&gnssServiceCtx->satStatus);
+                }
+                osDelay(LISTEN_TIME_THR);
+            }
+        }
+    }
+    gnssServiceCtx->gnssRunning = false;
+    LBSLOGI(HDI_GNSS, "exit ListenGnssData");
+}
+#endif
 
 static int LocationStopGnss(uint32_t category)
 {
@@ -151,9 +242,16 @@ static int LocationStopGnss(uint32_t category)
         return GNSS_FAILURE;
     }
     g_gnssServiceCtx.gnssStarted = false;
+#ifdef SUPPORT_FILE
     if (g_gnssServiceCtx.gnssNmeaFp) {
         g_gnssServiceCtx.gnssNmeaFp.close();
     }
+#endif
+    uint16_t taskReadyWait = 0;
+    while ((taskReadyWait < GNSS_TASK_CREATE_OK_WAIT_TIMEOUT) && g_gnssServiceCtx.gnssRunning) {
+        osal_msleep(GNSS_TASK_CREATE_TICK_TIME);
+        taskReadyWait += GNSS_TASK_CREATE_TICK_TIME;
+    }
     g_gnssServiceCtx.listenGnssDataThreadId = nullptr;
     return GNSS_SUCCESS;
 }
@@ -200,6 +298,7 @@ static int LocationStartGnss(uint32_t category)
         LBSLOGI(HDI_GNSS, "Gnss has Started");
         return GNSS_SUCCESS;
     }
+#ifdef SUPPORT_FILE
     g_gnssServiceCtx.gnssNmeaFp.open(g_gnssNmeaFile, std::ifstream::in);
 
     if (!g_gnssServiceCtx.gnssNmeaFp.good() ||
@@ -208,6 +307,7 @@ static int LocationStartGnss(uint32_t category)
         LBSLOGI(HDI_GNSS, "Gnss open :%s failed", g_gnssNmeaFile.c_str());
         return GNSS_FAILURE;
     }
+#endif
     g_gnssServiceCtx.gnssStarted = true;
     ThreadAttr attr = {"ListenGnssDataTask", 0x2000, (uint8_t)osPriorityNormal, 0, 0};
     ThreadId threadId = (ThreadId)ThreadCreate(ListenGnssData, &g_gnssServiceCtx, &attr);
index 5f1d0a5..c3b78e8 100644 (file)
@@ -392,6 +392,15 @@ typedef struct {
     /* Bearing accuracy in degrees. */
     float bearingAccuracy;
 
+    /* Northward Velocity in m/s. */
+    float velocityNorth;
+
+    /* Eastward Velocity in m/s. */
+    float velocityEast;
+
+    /* Descent Velocity in m/s. */
+    float velocityDescend;
+
     /* Timestamp for the location fix. Number of milliseconds since January 1, 1970. */
     int64_t timeForFix;
 
@@ -400,6 +409,9 @@ typedef struct {
 
     /* Time uncertainty in nanosecond. */
     uint64_t timeUncertainty;
+
+    /* Signal status */
+    int32_t signal;
 } GnssLocation;
 
 /*
index 495ed69..a473917 100644 (file)
@@ -87,6 +87,9 @@ static void LocationUpdate(GnssLocation *location)
     locationNew.altitude = location->altitude;
     locationNew.horizontalAccuracy = location->horizontalAccuracy;
     locationNew.speed = location->speed;
+    locationNew.velocityNorth = location->velocityNorth;
+    locationNew.velocityEast = location->velocityEast;
+    locationNew.velocityDescend = location->velocityDescend;
     locationNew.bearing = location->bearing;
     locationNew.verticalAccuracy = location->verticalAccuracy;
     locationNew.speedAccuracy = location->speedAccuracy;
@@ -94,6 +97,7 @@ static void LocationUpdate(GnssLocation *location)
     locationNew.timeForFix = location->timeForFix;
     locationNew.timeSinceBoot = location->timeSinceBoot;
     locationNew.timeUncertainty = location->timeUncertainty;
+    locationNew.signal = location->signal;
     if (g_gnssCallback != nullptr) {
         g_gnssCallback->ReportLocation(locationNew);
     }
index 6150932..ee0129d 100644 (file)
@@ -23,7 +23,8 @@ extern "C" {
 #define GNSS_SAT_IN_MSG        4
 #define GNSS_NSAT_MSGS         (GNSS_SAT_NUM_MAX / GNSS_SAT_IN_MSG)
 
-#define GNSS_KNOTS              (1.852)
+#define GNSS_KNOTS              (0.514444 * 100) // knots to m/s
+#define GNSS_STRAIGHT_ANGLE      (180.0)
 
 #define NMEA_SENTENCE_START_BIT     (3)     // $-- 正式语句从第四位开始
 #define NMEA_SENTENCE_TYPE_BIT      (3)     // 语句类型标识长度
@@ -106,6 +107,7 @@ extern "C" {
 #define NMEA_HEX    16
 #define NMEA_ONE_SENTENCE_FOUR_SAT  4
 #define NMEA_GSV_OTHER_BIT  3
+#define NMEA_ERROR  (4.0) // 估算误差
 
 typedef enum {
     GNSS_SYSTEM_INVALID     = 0,
@@ -169,6 +171,12 @@ typedef enum {
     GNSS_NMEA_FIELD_TYPE_SATUSEDNUM     = 0x8000,
     GNSS_NMEA_FIELD_TYPE_SATINUSE       = 0x10000,
     GNSS_NMEA_FIELD_TYPE_SATINVIEW      = 0x20000,
+    GNSS_NMEA_FIELD_TYPE_HORIZONTAL_ACCURACY        = 0x40000,
+    GNSS_NMEA_FIELD_TYPE_VERTICAL_ACCURACY          = 0x80000,
+    GNSS_NMEA_FIELD_TYPE_SPEED_ACCURACY             = 0x100000,
+    GNSS_NMEA_FIELD_TYPE_NORTH_VELOCITY             = 0x200000,
+    GNSS_NMEA_FIELD_TYPE_EAST_VELOCITY              = 0x400000,
+    GNSS_NMEA_FIELD_TYPE_DESCEND_VELOCITY           = 0x800000,
 } GnssNmeaFieldType;
 
 typedef struct {
@@ -212,13 +220,28 @@ typedef struct {
     double  lat;                        // 纬度
     double  lon;                        // 经度
     double  altitude;                  // 天线海拔高度
-    double  speed;                     // 速度   千米/小时
+    float   speed;                     // 速度   千米/小时
     double  pdop;                      // 三维位置精度因子:为纬度、经度和高程等误差平方和的开根号值
     double  hdop;                      // 水平分量精度因子:为纬度和经度等误差平方和的开根号值
     double  vdop;                      // 垂直分量精度因子
     double  trackAng;                  // 跟踪角
     double  magneticTrackAng;          // 磁轨角
     double  magVariation;              // 磁场变化度
+    // Calculated Velocity Components
+    // 计算后的速度分量
+    float velocityNorth;    // Northward Velocity (m/s)
+                              // 向北速度 (米/秒)
+    float velocityEast;     // Eastward Velocity (m/s)
+                              // 向东速度 (米/秒)
+    float velocityDescend;  // Descent Velocity (m/s)
+                              // 下降速度 (米/秒)
+
+    float verticalAccuracy;    // Vertical accuracy estimate in mm
+                                   // 垂直精度估计 单位:mm
+    float horizontalAccuracy;  // Horizontal accuracy estimate in mm
+                                   // 水平精度估计 单位:mm
+    float speedAccuracy;       // Speed accuracy estimate in cm/s
+                                   // 速度精度估计 单位:cm/s
 
     GnssTime utc;                      // 世界标准时间
     GnssSatelliteList satelist;            // 卫星信息
@@ -303,6 +326,8 @@ typedef struct {
     char nmeaBuf[GNSS_NMEA_FRAME_MAX_SIZE];
 } GnssNmeaFrameProcess;
 
+void GnssNmeaInit();
+
 GnssNmeaFrameType GnssNmeaGetFrameType(const char* nmeaBuf, unsigned int length);
     
 int GnssNmeaDecodeFrame(const char* nmea, unsigned int nmeaLen, GnssInfo* gnssInfo);
index fd452f8..6a5c5a9 100644 (file)
@@ -24,7 +24,7 @@ typedef struct {
 \r
 #pragma pack()\r
 \r
-int32_t LocationGnssUtilsUtc2UnixTime(const GnssUtcTime *utcTime, uint32_t *unixTime);\r
+int32_t LocationGnssUtilsUtc2UnixTime(const GnssUtcTime *utcTime, int64_t *unixTime);\r
 \r
 int64_t LocationGnssUtilsGetTimestampMS(void);\r
 \r
index d33c77e..8fd985c 100644 (file)
@@ -130,10 +130,14 @@ static int NmeaGSA2GnssInfo(const GnssNmeaGSA *nmeaGSA, GnssSystem gnssSystem, G
 
     if (nmeaGSA->fieldType & GNSS_NMEA_FIELD_TYPE_HDOP) {
         gnssInfo->hdop = nmeaGSA->hdop;
+        gnssInfo->horizontalAccuracy = gnssInfo->hdop * NMEA_ERROR;  // 估算水平误差
+        gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_HORIZONTAL_ACCURACY;
     }
 
     if (nmeaGSA->fieldType & GNSS_NMEA_FIELD_TYPE_VDOP) {
         gnssInfo->vdop = nmeaGSA->vdop;
+        gnssInfo->verticalAccuracy = gnssInfo->vdop * NMEA_ERROR;  // 估算垂直误差
+        gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_VERTICAL_ACCURACY;
     }
     return GNSS_OK;
 }
@@ -148,9 +152,6 @@ static int NmeaVTG2GnssInfo(const GnssNmeaVTG *nmeaVTG, GnssInfo *gnssInfo)
     gnssInfo->field |= nmeaVTG->fieldType;
     gnssInfo->sentence |= GNSS_NMEA_FRAME_VTG;
 
-    if (nmeaVTG->fieldType & GNSS_NMEA_FIELD_TYPE_SPEED) {
-        gnssInfo->speed = nmeaVTG->speed;
-    }
     if (nmeaVTG->fieldType & GNSS_NMEA_FIELD_TYPE_TRACK) {
         gnssInfo->trackAng = nmeaVTG->trackAng;
     }
@@ -186,6 +187,32 @@ static void NmeaRMCUTC2GnssInfo(const GnssNmeaRMC *nmeaRMC, GnssInfo *gnssInfo)
     return;
 }
 
+#define NMEA_SPEEDS_SAMPLE_CNT (100)
+float g_speeds[NMEA_SPEEDS_SAMPLE_CNT];         // 存储速度样本
+int32_t g_sampleCnt = 0;
+bool g_isWriteinPlace = false;
+
+// 计算 RMSE
+static float NmeaComputeRmse(int32_t sampleCnt)
+{
+    if (sampleCnt == 0) {
+        return 0.0f;
+    }
+
+    float sum = 0.0, mean = 0.0, errorSum = 0.0;
+    for (int32_t i = 0; i < sampleCnt; i++) {
+        sum += g_speeds[i];
+    }
+    mean = sum / sampleCnt;
+
+    for (int32_t i = 0; i < sampleCnt; i++) {
+        float error = g_speeds[i] - mean;
+        errorSum += error * error;
+    }
+
+    return sqrtf(errorSum / sampleCnt);
+}
+
 static int NmeaRMC2GnssInfo(GnssNmeaRMC *nmeaRMC, GnssInfo *gnssInfo)
 {
     if (nmeaRMC == NULL || gnssInfo == NULL) {
@@ -224,11 +251,26 @@ static int NmeaRMC2GnssInfo(GnssNmeaRMC *nmeaRMC, GnssInfo *gnssInfo)
     }
 
     if (nmeaRMC->fieldType & GNSS_NMEA_FIELD_TYPE_SPEED) {
+        // knots to cm/s
         gnssInfo->speed = nmeaRMC->speedN * GNSS_KNOTS;
+        if (g_sampleCnt == NMEA_SPEEDS_SAMPLE_CNT) {
+            g_sampleCnt = 0;
+            g_isWriteinPlace = true;
+        }
+        g_speeds[g_sampleCnt++] = gnssInfo->speed;
+        gnssInfo->speedAccuracy = NmeaComputeRmse(g_isWriteinPlace ? NMEA_SPEEDS_SAMPLE_CNT : g_sampleCnt);
+        gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_SPEED_ACCURACY;
+        
     }
 
     if (nmeaRMC->fieldType & GNSS_NMEA_FIELD_TYPE_TRACK) {
         gnssInfo->trackAng = nmeaRMC->trackAng;
+        if (nmeaRMC->fieldType & GNSS_NMEA_FIELD_TYPE_SPEED) {
+            gnssInfo->velocityNorth = gnssInfo->speed * cos(gnssInfo->trackAng * M_PI / GNSS_STRAIGHT_ANGLE);
+            gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_NORTH_VELOCITY;
+            gnssInfo->velocityEast = gnssInfo->speed * sin(gnssInfo->trackAng * M_PI / GNSS_STRAIGHT_ANGLE);
+            gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_EAST_VELOCITY;
+        }
     }
 
     if (nmeaRMC->fieldType & GNSS_NMEA_FIELD_TYPE_MAGVAR) {
@@ -238,6 +280,53 @@ static int NmeaRMC2GnssInfo(GnssNmeaRMC *nmeaRMC, GnssInfo *gnssInfo)
     return GNSS_OK;
 }
 
+#define NMEA_HOUR_TO_SEC (3600)
+#define NMEA_MIN_TO_SEC (60)
+#define NMEA_12_HOUR_TO_SEC (43200)
+#define NMEA_24_HOUR_TO_SEC (86400)
+// Store previous altitude and time for velocity calculation
+// 用于存储前一时刻的高度和时间,用于计算速度
+static double g_previousAltitude = 0.0;
+static double g_previousTime = 0.0;
+
+static void CalculateVelocityDescend(const GnssNmeaGGA *nmeaGGA, GnssInfo *gnssInfo)
+{
+    // 计算下降速度 (需要上一高度和时间)
+    // Calculate descent velocity (needs previous altitude and time)
+    if (g_previousTime > 0.0) {
+        double currentTime =
+            gnssInfo->utc.hour * NMEA_HOUR_TO_SEC + gnssInfo->utc.min * NMEA_MIN_TO_SEC + gnssInfo->utc.sec;
+        double deltaTime = currentTime - g_previousTime;
+
+        // 处理跨天情况
+        // Handle day crossover
+        if (deltaTime < -NMEA_12_HOUR_TO_SEC) {        // 如果时间差小于-12小时,说明跨天了
+                                         // If time difference is less than -12 hours, day has changed
+            deltaTime += NMEA_24_HOUR_TO_SEC;          // 加上24小时
+                                         // Add 24 hours
+        } else if (deltaTime > NMEA_12_HOUR_TO_SEC) {  // 如果时间差大于12小时,说明是前一天的数据
+                                         // If time difference is more than 12 hours, it's previous day's data
+            deltaTime -= NMEA_24_HOUR_TO_SEC;
+        }
+
+        if (deltaTime > 0 && deltaTime < NMEA_TEN) {  // 只处理合理的时间差(比如小于10秒)
+                                                // Only process reasonable time differences (e.g., less than 10 seconds)
+            double deltaAltitude = gnssInfo->altitude - g_previousAltitude;
+            // 过滤异常值(比如高度差太大)
+            // Filter abnormal values (e.g., too large altitude differences)
+            if (fabs(deltaAltitude) < NMEA_NUM_100) {  // 假设最大垂直速度不超过100m/s
+                                              // Assume maximum vertical speed doesn't exceed 100m/s
+                gnssInfo->velocityDescend =
+                    -deltaAltitude / deltaTime;  // 注意符号:上升为负,下降为正
+                                                 // Note: negative for ascent, positive for descent
+                gnssInfo->field |= GNSS_NMEA_FIELD_TYPE_DESCEND_VELOCITY;
+            }
+        }
+    }
+    g_previousAltitude = gnssInfo->altitude;
+    g_previousTime = gnssInfo->utc.hour * NMEA_HOUR_TO_SEC + gnssInfo->utc.min * NMEA_MIN_TO_SEC + gnssInfo->utc.sec;
+}
+
 static int NmeaGGA2GnssInfo(const GnssNmeaGGA *nmeaGGA, GnssInfo *gnssInfo)
 {
     if (nmeaGGA == NULL || gnssInfo == NULL) {
@@ -273,6 +362,7 @@ static int NmeaGGA2GnssInfo(const GnssNmeaGGA *nmeaGGA, GnssInfo *gnssInfo)
 
     if (nmeaGGA->fieldType & GNSS_NMEA_FIELD_TYPE_ANTALT) {
         gnssInfo->altitude = nmeaGGA->antAltitude;
+        CalculateVelocityDescend(nmeaGGA, gnssInfo);
     }
     return GNSS_OK;
 }
@@ -1142,3 +1232,12 @@ int GnssNmeaDecodeFrame(const char *nmea, unsigned int nmeaLen, GnssInfo *gnssIn
     nmeaFrameType = GnssNmeaGetFrameType((const char *)&nmeaFrameProcess.nmeaBuf, nmeaFrameProcess.length);
     return NmeaFrameProc(nmeaFrameType, &nmeaFrameProcess, gnssInfo);
 }
+
+void GnssNmeaInit()
+{
+    (void)memset_s(g_speeds, sizeof(g_speeds), 0, sizeof(g_speeds));
+    g_isWriteinPlace = false;
+    g_sampleCnt = 0;
+    g_previousAltitude = 0.0;
+    g_previousTime = 0.0;
+}
index ea3d65f..cb4bb15 100644 (file)
@@ -66,7 +66,7 @@ static int32_t CheckIfLeapYear(uint16_t year)
 }\r
 \r
 /* 将日历时(年月日时分秒) 转换为 unix时间(1970年1月1日起的时间秒数) */\r
-int32_t LocationGnssUtilsUtc2UnixTime(const GnssUtcTime *utcTime, uint32_t *unixTime)\r
+int32_t LocationGnssUtilsUtc2UnixTime(const GnssUtcTime *utcTime, int64_t *unixTime)\r
 {\r
     if (utcTime == NULL || unixTime == NULL) {\r
         LBSLOGE(HDI_GNSS, "error: [Utc2UnixTime] null pointer!");\r
@@ -82,18 +82,18 @@ int32_t LocationGnssUtilsUtc2UnixTime(const GnssUtcTime *utcTime, uint32_t *unix
     int32_t *monthDays = (CheckIfLeapYear(utcTime->year) == 1) ? g_leapMonthDays : g_normMonthDays;\r
 \r
     // 计算从1970.01.01开始的unix 秒数\r
-    uint32_t timestamp = 0;\r
-    timestamp += (uint32_t)(utcTime->year - UNIX_TIME_START_YEAR) * SECONDS_PER_NORMAL_YEAR;\r
-    timestamp += (uint32_t)GetLeapYearNum(UNIX_TIME_START_YEAR, utcTime->year) * SECONDS_PER_DAY;\r
+    int64_t timestamp = 0;\r
+    timestamp += (int64_t)(utcTime->year - UNIX_TIME_START_YEAR) * SECONDS_PER_NORMAL_YEAR;\r
+    timestamp += (int64_t)GetLeapYearNum(UNIX_TIME_START_YEAR, utcTime->year) * SECONDS_PER_DAY;\r
 \r
     for (int32_t i = 1; i < utcTime->month; i++) {\r
-        timestamp += (uint32_t)monthDays[i - 1] * SECONDS_PER_DAY;\r
+        timestamp += (int64_t)monthDays[i - 1] * SECONDS_PER_DAY;\r
     }\r
 \r
-    timestamp += (uint32_t)(utcTime->day - 1) * SECONDS_PER_DAY;\r
-    timestamp += (uint32_t)utcTime->hour * SECONDS_PER_HOUR;\r
-    timestamp += (uint32_t)utcTime->minute * SECONDS_PER_MIN;\r
-    uint32_t timestampSec = (uint32_t)(utcTime->second + utcTime->ms / TIME_UNIT);\r
+    timestamp += (int64_t)(utcTime->day - 1) * SECONDS_PER_DAY;\r
+    timestamp += (int64_t)utcTime->hour * SECONDS_PER_HOUR;\r
+    timestamp += (int64_t)utcTime->minute * SECONDS_PER_MIN;\r
+    int64_t timestampSec = (int64_t)(utcTime->second * TIME_UNIT + utcTime->ms);\r
 \r
     *unixTime = timestamp + timestampSec;\r
     return GNSS_SUCCESS;\r
@@ -115,7 +115,7 @@ int32_t FillGnssLocationTimeInfo(const GnssInfo *gnssInfo, GnssLocation *locatio
         location->fieldValidity |= GNSS_LOCATION_TIME_VALID;\r
         GnssUtcTime utcTime = {gnssInfo->utc.year, gnssInfo->utc.month, gnssInfo->utc.day,      gnssInfo->utc.hour,\r
                                gnssInfo->utc.min,  gnssInfo->utc.sec,   gnssInfo->utc.centisec, 1};\r
-        uint32_t unixTime = 0;\r
+        int64_t unixTime = 0;\r
         LocationGnssUtilsUtc2UnixTime(&utcTime, &unixTime);\r
         location->timeForFix = unixTime;\r
         location->size++;\r
@@ -138,6 +138,11 @@ int32_t LocationGnssUtilsFillGnssLocation(const GnssInfo *gnssInfo, GnssLocation
         return GNSS_FAILURE;\r
     }\r
     location->fieldValidity = GNSS_NMEA_FIELD_TYPE_SMASK;\r
+    if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_SIGNAL) {\r
+        location->signal = (int32_t)gnssInfo->signal;\r
+        location->fieldValidity |= GNSS_LOCATION_SIGNAL_VALID;\r
+        location->size++;\r
+    }\r
     if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_LAT) {\r
         location->latitude = gnssInfo->lat;\r
         location->fieldValidity |= GNSS_LOCATION_LAT_VALID;\r
@@ -163,15 +168,47 @@ int32_t LocationGnssUtilsFillGnssLocation(const GnssInfo *gnssInfo, GnssLocation
         location->fieldValidity |= GNSS_LOCATION_BEARING_VALID;\r
         location->size++;\r
     }\r
+    if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_HORIZONTAL_ACCURACY) {\r
+        location->horizontalAccuracy = gnssInfo->horizontalAccuracy;\r
+        location->fieldValidity |= GNSS_LOCATION_HORIZONTAL_ACCURACY_VALID;\r
+        location->size++;\r
+    }\r
+    if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_VERTICAL_ACCURACY) {\r
+        location->verticalAccuracy = gnssInfo->verticalAccuracy;\r
+        location->fieldValidity |= GNSS_LOCATION_VERTICAL_ACCURACY_VALID;\r
+        location->size++;\r
+    }\r
+    if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_SPEED_ACCURACY) {\r
+        location->speedAccuracy = gnssInfo->speedAccuracy;\r
+        location->fieldValidity |= GNSS_LOCATION_SPEED_ACCURACY_VALID;\r
+        location->size++;\r
+    }\r
+    if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_NORTH_VELOCITY) {\r
+        location->velocityNorth = gnssInfo->velocityNorth;\r
+        location->fieldValidity |= GNSS_LOCATION_NORTH_VELOCITY_VALID;\r
+        location->size++;\r
+    }\r
+    if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_EAST_VELOCITY) {\r
+        location->velocityEast = gnssInfo->velocityEast;\r
+        location->fieldValidity |= GNSS_LOCATION_EAST_VELOCITY_VALID;\r
+        location->size++;\r
+    }\r
+    if (gnssInfo->field & GNSS_NMEA_FIELD_TYPE_DESCEND_VELOCITY) {\r
+        location->velocityDescend = gnssInfo->velocityDescend;\r
+        location->fieldValidity |= GNSS_LOCATION_DESCEND_VELOCITY_VALID;\r
+        location->size++;\r
+    }\r
 \r
     FillGnssLocationTimeInfo(gnssInfo, location);\r
 \r
     LBSLOGD(HDI_GNSS,\r
             "location size :%lu field:0x%x lat%.3f lon:%.3f alti:%.3f speed:%.3f bearing:%.3f "\r
-            "hAcc:%.3f vAcc:%.3f sAcc:%.3f bearingAcc:%.3f timeFix:%lld tSB:%llu",\r
+            "hAcc:%.3f vAcc:%.3f sAcc:%.3f bearingAcc:%.3f timeFix:%lld tSB:%llu velocityNorth:%.3f"\r
+            "velocityEast:%.3f velocityDescend:%.3f",\r
             location->size, location->fieldValidity, location->latitude, location->longitude, location->altitude,\r
             location->speed, location->bearing, location->horizontalAccuracy, location->verticalAccuracy,\r
-            location->speedAccuracy, location->bearingAccuracy, location->timeForFix, location->timeSinceBoot);\r
+            location->speedAccuracy, location->bearingAccuracy, location->timeForFix, location->timeSinceBoot, location->velocityNorth,\r
+            location->velocityEast, location->velocityDescend);\r
     return GNSS_SUCCESS;\r
 }\r
 \r
index 50761c9..b9f589b 100644 (file)
@@ -60,6 +60,10 @@ enum GnssLocationValidity : int32_t {
     GNSS_LOCATION_TIME_VALID = 512,
     GNSS_LOCATION_TIME_SINCE_BOOT_VALID = 1024,
     GNSS_LOCATION_TIME_UNCERTAINTY_VALID = 2048,
+    GNSS_LOCATION_NORTH_VELOCITY_VALID  = 4096,
+    GNSS_LOCATION_EAST_VELOCITY_VALID   = 8192,
+    GNSS_LOCATION_DESCEND_VELOCITY_VALID  = 16384,
+    GNSS_LOCATION_SIGNAL_VALID = 32768,
 };
 
 enum GnssWorkingMode : int32_t {
@@ -203,9 +207,13 @@ struct LocationInfo {
     float verticalAccuracy;
     float speedAccuracy;
     float bearingAccuracy;
+    float velocityNorth;
+    float velocityEast;
+    float velocityDescend;
     int64_t timeForFix;
     int64_t timeSinceBoot;
     int64_t timeUncertainty;
+    int32_t signal;
 } __attribute__ ((aligned(8)));
 
 struct GnssRefInfo {
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/CMakeLists.txt b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1700153
--- /dev/null
@@ -0,0 +1,13 @@
+#===============================================================================
+# @brief    cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved.
+#===============================================================================
+
+add_subdirectory_with_alias_if_exist(hal_lite/sensor_mgr ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/sensor_mgr)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/acc_simulator ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/acc_simulator)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/barometer ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/barometer)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/gyroscope ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/gyroscope)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/heart_rate_counter ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/heart_rate_counter)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/pedometer ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/pedometer)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/hsensor/wear_detection ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/hsensors/wear_detection)
+add_subdirectory_with_alias_if_exist(hal_lite/sensors/vsensor/acc_alg_simulator ${PROJECT_BINARY_DIR}/ohos/sensor_hdi_lite/vsensors)
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/CMakeLists.txt b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5f6f7e8
--- /dev/null
@@ -0,0 +1,79 @@
+set(COMPONENT_NAME "sensor_hdi")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../interfaces/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/hsensormgr_service/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/hsensor_data_service/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensor_task_common/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/task/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/include
+)
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/sensor_interface_impl.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/sensor_manager.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/hsensormgr_service/src/hsensormgr_service.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/hsensor_data_service/src/hsensor_data_service.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensormgr_service.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensor_task_mgr.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_class.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_comm.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_thread.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_log.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_utils.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_memory.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_msgqueue.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/task/src/sensor_task.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/task/src/sensor_tmsg.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_para_decision.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/src/sensor_state.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+set(AUTO_ADD_PATH
+    false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT" "ENABLE_INFO_LEVEL_LOG")
+set(PRIVATE_DEFINES
+    ${CDEFINES}
+)
+
+build_component()
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/include/sensor_common.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/include/sensor_common.h
new file mode 100644 (file)
index 0000000..d454a05
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor common
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+
+#ifndef HDI_SENSOR_COMMON_H
+#define HDI_SENSOR_COMMON_H
+
+#include <stdio.h>
+#include "sensor_log.h"
+#include "securec.h"
+
+/* err number 管理,约定mudule id为30 */
+#define SENSOR_ERRNO_MODULE_ID 30 /* 0x1e */
+
+/* start:0x801e0000  end:0x801effff 返回错误信息均为负数 */
+#define SENSOR_ERR_NUMBER(type, code) \
+    (int32_t)((((((0x80 << 8) | (SENSOR_ERRNO_MODULE_ID)) << 8) | (type)) << 8) | (code))
+
+typedef enum {
+    SENSOR_ETYPE_ALG            = 0x00,
+    SENSOR_ETYPE_VSENSOR_MGR    = 0x01,
+    SENSOR_ETYPE_DATA_SERVICE   = 0x02,
+    SENSOR_ETYPE_FRAME          = 0x03,
+    SENSOR_ETYPE_ENTRY_PARA     = 0x04,
+
+    SENSOR_ETYPE_MAX
+} SensorErrType;
+
+/* all return values of SENSOR Engine, partition by module */
+enum {
+    SENSOR_ERROR = -1,
+    SENSOR_OK = 0,
+
+    /* 算法错误码 SENSOR_ETYPE_ALG */
+    SENSOR_ALG_ERRNO = SENSOR_ERR_NUMBER(SENSOR_ETYPE_ALG, 0), /* 0x801e0000 */
+
+    /* 虚拟算法Sensor管理错误码 SENSOR_ETYPE_VSENSOR_MGR */
+    SENSOR_ALG_SERVICE_ERRNO = SENSOR_ERR_NUMBER(SENSOR_ETYPE_VSENSOR_MGR, 0), /* 0x801e0100 */
+    SENSOR_CHECK_RELY_SENSORS_NULL,                                            /* 0x801e0101 */
+    SENSOR_CHECK_RELY_SENSORS_SENSORIL,                                        /* 0x801e0102 */
+    SENSOR_CHECK_PROCESS_DATA_NULL,                                            /* 0x801e0103 */
+    SENSOR_CHECK_PROCESS_DATA_TS_ERR,                                          /* 0x801e0104 */
+    SENSOR_GET_RELY_SENSOR_INF_SENSORIL,                                       /* 0x801e0105 */
+    SENSOR_OPEN_RELY_SENSORS_CHECK_NULL,                                       /* 0x801e0106 */
+    SENSOR_VSENSOR_NOT_SUPPORT,                                                /* 0x801e01A1 */
+    SENSOR_PERSON_INFO_NULL,                                                   /* 0x801e01A2 */
+    SENSOR_VSENSOR_TASK_REG_VENSOR_NULL,                                       /* 0x801e01A5 */
+    SENSOR_TASK_SENSOR_DATA_UPDATE_NULL,                                      /* 0x801e01A6 */
+    SENSOR_TASK_CHECK_COMM_COMPONENT_NULL,                                    /* 0x801e01A7 */
+    SENSOR_TASK_LISTENER_FIND_NULL,                                           /* 0x801e01A8 */
+    SENSOR_TASK_SENSOR_NULL,                                                  /* 0x801e01A9 */
+    SENSOR_TASK_HSDATA_UPDATE_DATA_NULL,                                      /* 0x801e01AA */
+    SENSOR_TASK_VSENSOR_INFO_FIND_NULL,                                       /* 0x801e01AB */
+    SENSOR_UTIL_CANNOT_GET_ALG_TASK,                                           /* 0x801e01AC */
+    SENSOR_VSENSOR_NOT_REGISTER,                                               /* 0x801e01AD */
+    SENSOR_HSENSOR_REG_NULL,                                                   /* 0x801e01AF */
+    SENSOR_TASK_HLISTENER_REG_TYPE_ERR,                                       /* 0x801e01B1 */
+    SENSOR_TASK_RELY_SENSOR_NOT_REGISTERED,                                   /* 0x801e01B2 */
+    SENSOR_TASK_SENSOR_DECISION_PARA_ERROR,                                   /* 0x801e01B3 */
+    SENSOR_TASK_VSENSOR_OPEN_FAIL,                                            /* 0x801e01B4 */
+    SENSOR_TASK_VSENSOR_CLOSE_FAIL,                                           /* 0x801e01B5 */
+    SENSOR_TASK_VSENSOR_OPEN_NULL,                                            /* 0x801e01B6 */
+    SENSOR_TASK_VSENSOR_CLOSE_NULL,                                           /* 0x801e01B7 */
+    SENSOR_TASK_VSENSOR_PROCESS_NULL,                                         /* 0x801e01B8 */
+
+    /* 数据管理错误码 SENSOR_ETYPE_DATA_SERVICE */
+    SENSOR_DATA_SERVICE_ERRNO = SENSOR_ERR_NUMBER(SENSOR_ETYPE_DATA_SERVICE, 0), /* 0x801e0200 */
+    SENSOR_SENSOR_DECISION_PARA_NULL,                                            /* 0x801e0201 */
+    SENSOR_HSENSOR_CALIBRATE_INF_NULL,                                           /* 0x801e0202 */
+    SENSOR_HSENSOR_SELFTEST_INF_NULL,                                            /* 0x801e0203 */
+    SENSOR_HSENSOR_DRV_CALIBRATE_ERR,                                            /* 0x801e0204 */
+    SENSOR_HSENSOR_DRV_SELFTEST_ERR,                                             /* 0x801e0205 */
+
+    SENSOR_HSENSOR_PERIOD_BATCH_ERR,
+    SENSOR_HSENSOR_MODE_ERR,
+    SENSOR_HSENSOR_LISTENER_INFO_NULL,
+    SENSOR_HSENSOR_LISTENER_NULL,
+    SENSOR_HSENSOR_GET_SCB_SENSORIL,
+    SENSOR_HSENSOR_SCB_NULL,
+    SENSOR_HSENSOR_SCB_HSENSOR_NULL,
+    SENSOR_HSENSOR_SCB_LISTENER_EXIST,
+    SENSOR_HSENSOR_SCB_LISTENER_NOT_EXIST,
+    SENSOR_HSENSOR_SCB_REPORT_PERIOD_ZERO,
+    SENSOR_HSENSOR_NULL,
+    SENSOR_HSENSOR_NAME_NULL,
+    SENSOR_HSENSOR_INTERSENSORCE_NULL,
+    SENSOR_HSENSOR_READ_ERR,
+    SENSOR_HSENSOR_REGISTER_TYPE_DUPLICATE,
+
+    /* SENSOR基础框架,线程,消息队列等模块 错误码 SENSOR_ETYPE_FRAME */
+    SENSOR_FRAME_ERRNO = SENSOR_ERR_NUMBER(SENSOR_ETYPE_FRAME, 0), /* 0x801e0600 */
+    SENSOR_MEMSET_ERR,                                             /* 0x801e0601 */
+    SENSOR_SEND_TMSG_NULL,                                         /* 0x801e0602 */
+    SENSOR_SEND_TMSG_MSG_QUEUE_NULL,                               /* 0x801e0603 */
+    SENSOR_RECV_TMSG_NULL,                                         /* 0x801e0604 */
+    SENSOR_RECV_TMSG_MSG_QUEUE_NULL,                               /* 0x801e0605 */
+    SENSOR_RECV_TMSG_ERR,                                          /* 0x801e0606 */
+    SENSOR_FREE_TMSG_NULL,                                         /* 0x801e0607 */
+    SENSOR_MSG_QUEUE_CREATE_FAIL,                                  /* 0x801e0608 */
+    SENSOR_TASK_CREATE_FAIL,                                       /* 0x801e0609 */
+    SENSOR_SEND_TMSG_DEST_NOT_RUNNING,                             /* 0x801e060A */
+    SENSOR_SENSOR_NOT_INIT,                                        /* 0x801e060B */
+    SENSOR_SENSOR_SECUREC_FUNC_ERR,                                /* 0x801e060C */
+    SENSOR_VSENSOR_TASK_CLASS_NULL,                                /* 0x801e060D */
+    SENSOR_TASK_CREATE_ID_WRONG,                                   /* 0x801e060F */
+
+    /* SENSOR MGR 所有入参检验 */
+    SENSOR_ENTRY_PARA_ERROR = SENSOR_ERR_NUMBER(SENSOR_ETYPE_ENTRY_PARA, 0), /* 0x801e0900 */
+    SENSOR_ENTRY_HSENSOR_NULL,                                               /* 0x801e0901 */
+    SENSOR_ENTRY_HSENSOR_NAME_NULL,                                          /* 0x801e0902 */
+    SENSOR_ENTRY_HSENSOR_FUNC_NULL,                                          /* 0x801e0903 */
+    SENSOR_ENTRY_HSENSOR_TYPE_NULL,                                          /* 0x801e0904 */
+    SENSOR_ENTRY_VSENSOR_NULL,                                               /* 0x801e0905 */
+    SENSOR_ENTRY_VSENSOR_NAME_NULL,                                          /* 0x801e0906 */
+    SENSOR_ENTRY_VSENSOR_FUNC_NULL,                                          /* 0x801e0907 */
+    SENSOR_ENTRY_VSENSOR_TYPE_NULL,                                          /* 0x801e0908 */
+    SENSOR_ENTRY_VSENSOR_RELY_NULL,                                          /* 0x801e0909 */
+    SENSOR_ENTRY_VSENSOR_RELY_PARA_ERR,                                      /* 0x801e090A */
+    SENSOR_ENTRY_CALIBRATE_PARA_NULL,                                        /* 0x801e090B */
+    SENSOR_ENTRY_SELFTEST_PARA_NULL,                                         /* 0x801e090C */
+    SENSOR_ENTRY_SENSOR_TYPE_ILLEGAL,                                        /* 0x801e090D */
+
+    SENSOR_MAX
+};
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
+#ifndef SENSOR_MIN
+#define SENSOR_MIN(a, b) (((a) > (b)) ? (b) : (a))
+#endif
+#ifndef SENSOR_MAX
+#define SENSOR_MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#define CHECK_NULL_PTR_RETURN_VALUE(ptr, ret)                                        \
+    do {                                                                             \
+        if ((ptr) == NULL) {                                                         \
+            HILOG_ERROR(HILOG_MODULE_SEN, "pointer is null and return ret:%d", ret); \
+            return (ret);                                                            \
+        }                                                                            \
+    } while (0)
+
+#define CHECK_NULL_PTR_RETURN(ptr)                                       \
+    do {                                                                 \
+        if ((ptr) == NULL) {                                             \
+            HILOG_ERROR(HILOG_MODULE_SEN, "pointer is null and return"); \
+            return;                                                      \
+        }                                                                \
+    } while (0)
+
+#define CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, ret)                \
+    do {                                                               \
+        if ((type == SENSOR_TYPE_NONE) || (type >= SENSOR_TYPE_MAX)) { \
+            HILOG_ERROR(HILOG_MODULE_SEN, "type :%d illegal\n", type); \
+            return ret;                                                \
+        }                                                              \
+    } while (0)
+
+#define CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type)                         \
+    do {                                                               \
+        if ((type == SENSOR_TYPE_NONE) || (type >= SENSOR_TYPE_MAX)) { \
+            HILOG_ERROR(HILOG_MODULE_SEN, "type :%d illegal\n", type); \
+            return;                                                    \
+        }                                                              \
+    } while (0)
+
+#define SENSOR_CHECK_OK(x)                                         \
+    do {                                                           \
+        if ((int32_t)(x) != SENSOR_OK) {                           \
+            HILOG_ERROR(HILOG_MODULE_SEN, "ret err ret:%d!\n", x); \
+            return x;                                              \
+        }                                                          \
+    } while (0)
+#endif /* HDI_SENSOR_COMMON_H */
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/include/sensor_manager.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/include/sensor_manager.h
new file mode 100644 (file)
index 0000000..6f16505
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor mgr
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+
+#ifndef HDI_SENSOR_MANAGER_H
+#define HDI_SENSOR_MANAGER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sensor_typedef.h"
+
+int32_t SensorMgrInit(void);
+int32_t SensorMgrDeInit(void);
+
+int32_t SensorMgrRegistHsensor(const Hsensor *sensor);
+int32_t SensorMgrRegistVsensor(const Vsensor *sensor);
+
+int32_t SensorMgrGetAllSensors(struct SensorInformation **sensorInfo, int32_t *count);
+
+int32_t SensorMgrEnable(int32_t sensorTypeId);
+
+int32_t SensorMgrDisable(int32_t sensorTypeId);
+
+int32_t SensorMgrSetBatch(int32_t sensorTypeId, int64_t samplingInterval, int64_t reportInterval);
+
+int32_t SensorMgrSetMode(int32_t sensorTypeId, int32_t mode);
+
+int32_t SensorMgrSetOption(int32_t sensorTypeId, uint32_t option);
+
+int32_t SensorMgrRegistDataCallback(int32_t sensorTypeId, RecordDataCallback cb);
+
+int32_t SensorMgrUnregistDataCallback(int32_t sensorTypeId, RecordDataCallback cb);
+
+#endif /* HDI_SENSOR_MANAGER_H */
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/include/sensor_typedef.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/include/sensor_typedef.h
new file mode 100644 (file)
index 0000000..1e04066
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor type def
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef HDI_SENSOR_TYPEDEF_H
+#define HDI_SENSOR_TYPEDEF_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sensor_type.h"
+
+/* person info */
+#define MIN_USER_WEIGHT 10      /* 单位:公斤 */
+#define DEFAULT_USER_WEIGHT 60  /* 单位:公斤 */
+#define MAX_USER_WEIGHT 250     /* 单位:公斤 */
+#define MIN_USER_HEIGHT 50      /* 单位:厘米 */
+#define DEFAULT_USER_HEIGHT 170 /* 单位:厘米 */
+#define MAX_USER_HEIGHT 250     /* 单位:厘米 */
+#define DEFAULT_USER_AGE 30     /* 单位:年 */
+#define MAX_USER_AGE 150        /* 单位:年 */
+#define ALG_USER_SEX_WOMEN 0    /* 女 */
+#define ALG_USER_SEX_MAN 1      /* 男 */
+#define ALG_USER_SEX_UNKNOWN 2  /* UNKNOWN */
+#define MAX_USER_GENDER 2
+
+typedef struct {
+    uint8_t weight; /* kg */
+    uint8_t height; /* cm */
+    uint8_t age;    /* YEAR */
+    uint8_t gender; /* MALE为 1, FEMALE为 0, UNKNOWN 为2 */
+} SensorPersonInfo;
+
+typedef enum {
+    SENSOR_IOCTL_SET_PARA = 0,
+    SENSOR_IOCTL_GET_PARA,
+    SENSOR_IOCTL_GET_INTERVAL,
+    SENSOR_IOCTL_GET_INFO,
+    SENSOR_IOCTL_CURRENT_ADJUST,
+    SENSOR_IOCTL_GET_CHIP_TYPE,
+    SENSOR_IOCTL_GET_MAX_BATCHCOUNT,
+    SENSOR_IOCTL_GET_FW_VERSION,
+    SENSOR_IOCTL_GET_MAX_RANGE,
+    SENSOR_IOCTL_GET_PRECISION,
+    SENSOR_IOCTL_GET_SENSOR_DATA,
+    SENSOR_IOCTL_MAX
+} SensorIoctlCmd;
+
+typedef enum {
+    SENSOR_STATE_IDLE = 0,
+    SENSOR_STATE_OPEN,
+    SENSOR_STATE_CLOSE,
+
+    SENSOR_STATE_MAX
+} SensorState;
+
+typedef struct {
+    uint32_t period; /* 采样间隔单位 ms */
+    uint32_t batch;  /* 一次上报的数据组数 */
+    uint32_t option;
+    enum SensorModeType mode; /* fifo mode OR realtime mode */
+} SensorPara;
+
+typedef struct {
+    enum SensorTypeTag type;
+    SensorPara param;
+} RelySensorInfo;
+
+typedef struct {
+    RelySensorInfo *relySensorArray;
+    uint32_t relySensorCnt;
+    uint8_t reserve[3]; /* 4字节对齐,3个字节保留 */
+} RelySensorsInfo;
+
+/* sensor信息 */
+typedef struct {
+    enum SensorTypeTag type; /* sensor 类型 */
+    const char *name;        /* sensor 信息 “ACCEL” 、“HR v2.0” 等 */
+    const void *privateData; /* sensor 的私有信息,私有接口 */
+    uint32_t privateDataLen; /* sensor 的私有信息长度 */
+    SensorState state;       /* 当前传感器运行状态,开、关、使能、去使能、暂停等 */
+    SensorPara openPara;     /* 当前传感器运行参数 */
+} SensorInfo;
+
+/* sensor操作句柄结构 */
+typedef struct Sensor Sensor;
+struct Sensor {
+    SensorInfo sensorInfo;
+    /* 方法 */
+    int32_t (*open)(const Sensor *sensor, const SensorPara *openPara); /* 传感器开,设置传感器 */
+    int32_t (*close)(const Sensor *sensor);                            /* 传感器关 */
+    int32_t (*setBatch)(Sensor *sensor, int64_t samplingInterval, int64_t reportInterval);
+    int32_t (*setMode)(Sensor *sensor, int32_t mode);
+    int32_t (*setOption)(Sensor *sensor, uint32_t option);
+    int32_t (*registerResultCallback)(const Sensor *sensor, RecordDataCallback cb);
+    int32_t (*unregisterResultCallback)(const Sensor *sensor, RecordDataCallback cb);
+    int32_t (*calibrate)(const Sensor *sensor, void *para, uint32_t len); /* 物理传感器专用校准接口,暂不支持 */
+    int32_t (*selfTest)(
+        const Sensor *sensor, void *para, uint32_t len); /* 厂测模式下使用,物理传感器专用自检接口,暂不支持 */
+    int32_t (*ioctl)(const Sensor *sensor, SensorIoctlCmd cmd, void *data, uint32_t len); /* 其他io操作 */
+};
+
+typedef struct {
+    float maxRange;            /**< Maximum measurement range of the sensor, not support now */
+    float accuracy;            /**< Sensor accuracy, not support now */
+    int64_t minDelay;          /**< Minimum sample period allowed in microseconds, not support now */
+    int64_t maxDelay;          /**< Maxmum sample period allowed in microseconds, not support now */
+    uint32_t sampleElementlen; /**<  one sample len */
+    uint32_t maxBatchCount;    /**< Maxmum number of data of this sensor that could be batched */
+    uint32_t reserved;         /**< Reserved fields */
+} SensorCapability;
+
+/* 物理传感器数据结构定义,注册时需要实现 */
+typedef struct {
+    enum SensorTypeTag type; /* 传感器类型 */
+    const char *name;        /* sensor 信息 “ACCEL” “GYRO”等 */
+    SensorCapability caps;
+    const void *privateData; /* sensor 的私有信息,私有接口 */
+    uint32_t privateDataLen; /* sensor 的私有信息长度 */
+    /* 方法 */
+    int32_t (*init)(void);                        /* 上电,sensor初始化 */
+    int32_t (*deinit)(void);                      /* 下电,去初始化 */
+    int32_t (*open)(SensorPara *para);            /* 传感器开 */
+    int32_t (*close)(void);                       /* 传感器关 */
+    int32_t (*read)(uint8_t *data, uint32_t len); /* 从传感器读数据 */
+    /* 其他io操作 */
+    int32_t (*ioctl)(SensorIoctlCmd cmd, void *data, uint32_t len);
+} Hsensor;
+
+/* 虚拟传感器(算法)数据结构定义,注册时需要实现 */
+typedef struct {
+    enum SensorTypeTag type;      /* 虚拟传感器类型,注册时写明 */
+    const char *name;             /* 虚拟传感器信息,注册时写明 */
+    const void *privateData;      /* 虚拟传感器的私有信息 */
+    uint32_t privateDataLen;      /* 虚拟传感器的私有信息长度 */
+    RelySensorsInfo *relySensors; /* 注册时写明,写清依赖的传感器 */
+
+    int32_t (*registDataCb)(RecordDataCallback cb);   /* 注册结果回调函数 */
+    int32_t (*unRegistDataCb)(RecordDataCallback cb); /* 取消注册结果回调函数 */
+    /* 方法 */
+    int32_t (*open)(SensorPara *para); /* 算法开,模式设置 */
+    int32_t (*close)(void);            /* 算法关 */
+    /* 算法接收传感器(包括依赖的算法)数据的接口 ts 微秒 */
+    int32_t (*process)(enum SensorTypeTag type, uint8_t *data, uint64_t ts, uint32_t len);
+    int32_t (*ioctl)(SensorIoctlCmd cmd, void *data, uint32_t len);
+} Vsensor;
+
+#endif /* HDI_SENSOR_TYPEDEF_H */
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensor_data_service/include/hsensor_data_service.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensor_data_service/include/hsensor_data_service.h
new file mode 100644 (file)
index 0000000..bb1709d
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor data service
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef HSENSOR_DATA_SERVICE_H
+#define HSENSOR_DATA_SERVICE_H
+
+#include "sensor_typedef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t HsensorDataServiceInit(enum SensorTypeTag type);
+uint32_t HsensorDataServiceProcess(enum SensorTypeTag type);
+int32_t HsensorDataServiceDeInit(enum SensorTypeTag type);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* HSENSOR_DATA_SERVICE_H */
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensor_data_service/src/hsensor_data_service.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensor_data_service/src/hsensor_data_service.c
new file mode 100644 (file)
index 0000000..fabb3b2
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor data service impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "hsensor_data_service.h"
+#include "sensor_common.h"
+#include "sensor_utils.h"
+#include "sensor_log.h"
+#include "hsensormgr_service.h"
+
+struct SensorEvents g_sensorEvent = {};
+
+int32_t HsensorDataServiceInit(enum SensorTypeTag type)
+{
+    return SENSOR_OK;
+}
+
+/* ******************************************************************************
+  函 数 名          :  HsensorDataServiceNotifyResultData
+  功能描述         :  数据分发,目前尚未做降采样,直接将所有数据上报,
+                  目前将所有数据的batch和采样率设置为一样,等待缓冲区和降采样完成
+  输入参数         :  None
+  输出参数         :  None
+  返 回 值          :  None
+****************************************************************************** */
+static void HsensorDataServiceNotifyResultData(HsensorScb *hsensorScb, HsensorListener *listener)
+{
+    if (listener->resultDataCb == NULL) {
+        return;
+    }
+    g_sensorEvent.sensorId = hsensorScb->type;
+    g_sensorEvent.version = 0;
+    g_sensorEvent.timestamp = hsensorScb->sysTick;
+    g_sensorEvent.option = hsensorScb->decisionPara.option;
+    g_sensorEvent.mode = hsensorScb->decisionPara.mode;
+    g_sensorEvent.data = hsensorScb->dataBuf;
+    g_sensorEvent.dataLen = hsensorScb->dataPackSize;
+    HILOG_DEBUG(HILOG_MODULE_SEN, "hsensorScb->type:%d data:%x", hsensorScb->type, hsensorScb->dataBuf);
+
+    listener->resultDataCb(&g_sensorEvent);
+}
+
+static void HsensorDataServiceNotifyData(HsensorScb *hsensorScb, HsensorListener *listener)
+{
+    if (listener->notifyCallback == NULL) {
+        return;
+    }
+    SensorNotifyInfo notifyInfo = {
+        .type = hsensorScb->type,
+        .data = hsensorScb->dataBuf,
+        .dataLen = hsensorScb->dataPackSize,
+        .option = hsensorScb->decisionPara.option,
+        .timestamp = hsensorScb->sysTick,
+    };
+    listener->notifyCallback(&notifyInfo, listener->notifyArg);
+}
+
+static void HsensorDataServiceNotifyAll(HsensorScb *hsensorScb)
+{
+    HsensorListener *listenerIndex = NULL;
+    osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+    {
+        if (listenerIndex->status != SENSOR_LISTENER_WORKING) {
+            continue;
+        }
+        HsensorDataServiceNotifyResultData(hsensorScb, listenerIndex);
+        HsensorDataServiceNotifyData(hsensorScb, listenerIndex);
+    }
+}
+
+uint32_t HsensorDataServiceProcess(enum SensorTypeTag type)
+{
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(type);
+    uint32_t samplingInterval = hsensorScb->decisionPara.period;
+    CHECK_NULL_PTR_RETURN_VALUE(hsensorScb, samplingInterval);
+    CHECK_NULL_PTR_RETURN_VALUE(hsensorScb->batchDataBuf, samplingInterval);
+    HILOG_DEBUG(HILOG_MODULE_SEN,
+        "hsensor type:%d period:%u batch:%u option:%u mode:%d reportPeriod:%u",
+        type,
+        hsensorScb->decisionPara.period,
+        hsensorScb->decisionPara.batch,
+        hsensorScb->decisionPara.option,
+        hsensorScb->decisionPara.mode,
+        hsensorScb->reportPeriod);
+    int32_t dataLen = hsensorScb->hsensor->read(hsensorScb->batchDataBuf, hsensorScb->batchDataBufSize);
+    if (dataLen <= 0) {
+        HILOG_WARN(HILOG_MODULE_SEN, "type: %d read data fail.", type);
+        return samplingInterval;
+    }
+    hsensorScb->batchCount++;
+    hsensorScb->dataPackSize += dataLen;
+    hsensorScb->batchDataBuf += dataLen;
+    hsensorScb->batchDataBufSize -= dataLen;
+    HILOG_DEBUG(HILOG_MODULE_SEN, "batchCount: %d dataLen: %d", hsensorScb->batchCount, dataLen);
+    if (hsensorScb->batchCount < hsensorScb->decisionPara.batch) {
+        return samplingInterval;
+    }
+    hsensorScb->sysTick = SensorUtilsGetRtcTimeMs();
+    HsensorDataServiceNotifyAll(hsensorScb);
+    hsensorScb->batchDataBuf = hsensorScb->dataBuf;
+    hsensorScb->batchDataBufSize = hsensorScb->dataBufSize;
+    hsensorScb->dataPackSize = 0;
+    hsensorScb->batchCount = 0;
+    return samplingInterval;
+}
+
+int32_t HsensorDataServiceDeInit(enum SensorTypeTag type)
+{
+    return SENSOR_OK;
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensormgr_service/include/hsensormgr_service.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensormgr_service/include/hsensormgr_service.h
new file mode 100644 (file)
index 0000000..50219bb
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: hsensor mgr
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef HSENSOR_MGR_SERVICE_H
+#define HSENSOR_MGR_SERVICE_H
+#include "sensor_typedef.h"
+#include "soc_osal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define HSENSOR_LISTENER_NAME_MAX_LEN 64
+
+typedef enum {
+    SENSOR_LISTENER_REGISTER,
+    SENSOR_LISTENER_UNREGISTER,
+    SENSOR_LISTENER_ENABLE,
+    SENSOR_LISTENER_DISABLE,
+    SENSOR_LISTENER_WORKING,
+} HsensorListenerStatus;
+
+typedef struct {
+    enum SensorTypeTag type;
+    uint8_t *data;
+    uint32_t dataLen;
+    uint32_t option;
+    uint64_t timestamp;
+} SensorNotifyInfo;
+
+typedef void (*NotifyCallback)(const SensorNotifyInfo *info, void *notifyArg);
+
+typedef struct {
+    struct osal_list_head list;
+    char name[HSENSOR_LISTENER_NAME_MAX_LEN];
+    enum SensorTypeTag type;
+    uint16_t bufIndex;     /* listener的缓存索引 */
+    uint16_t sampleCnt;    /* 传感器的采样次数 */
+    uint16_t dispatchCnt;  /* 数据分发间隔次数 */
+    uint32_t notifyPeriod; /* listener数据需求周期 ms */
+    SensorPara openParam;
+    NotifyCallback notifyCallback;
+    void *notifyArg;
+    RecordDataCallback resultDataCb;
+    HsensorListenerStatus status;
+} HsensorListener;
+
+typedef enum {
+    HSENSOR_SCB_UNINITED,
+    HSENSOR_SCB_INITED,
+} HsensorScbStatus;
+
+typedef struct HsensorScb {
+    struct osal_list_head list;         /* scb link point */
+    struct osal_list_head listenerList; /* scb listener head */
+    uint16_t listenerNum;
+    enum SensorTypeTag type; /* scb sensor type */
+    HsensorScbStatus status;
+    uint8_t *dataBuf;          /* scb buffer */
+    uint8_t *batchDataBuf;     /* scb batch buffer */
+    uint32_t batchDataBufSize; /* scb batch buffer length */
+    uint32_t dataBufSize;      /* scb buffer length */
+    uint32_t dataPackSize;     /* scb data len for every batch */
+    uint32_t dataBufIndex;     /* scb buffer current index */
+    uint32_t reportPeriod;     /* 传感器采样的上报周期 */
+    uint32_t batchCount;       /* scb buffer current index */
+    uint64_t sysTick;
+    SensorPara decisionPara; /* scb decision param */
+    Hsensor *hsensor;
+} HsensorScb;
+
+typedef struct {
+    struct osal_list_head hsensorScbHead;
+    uint32_t hsensorScbNum;
+    uint8_t *dataBuf;
+    uint8_t *dataDispatchBuf;
+    bool inited;
+} HsensorMgr;
+
+int32_t HsensorMgrInit(void);
+int32_t HsensorMgrRegister(const Hsensor *hsensor);
+int32_t HsensorMgrRegisterListener(HsensorListener *listener);
+int32_t HsensorMgrUnRegisterListener(HsensorListener *listener);
+int32_t HsensorMgrOpenListener(HsensorListener *listener);
+int32_t HsensorMgrCloseListener(HsensorListener *listener);
+HsensorScb *HsensorMgrHsensorScbFind(const enum SensorTypeTag type);
+
+int32_t HsensorMgrIoctl(enum SensorTypeTag type, SensorIoctlCmd cmd, void *data, uint32_t len);
+int32_t HsensorMgrReadData(const enum SensorTypeTag type, const uint64_t *ts);
+void HsensorMgrPrintListener(enum SensorTypeTag type);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensormgr_service/src/hsensormgr_service.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/hsensormgr_service/src/hsensormgr_service.c
new file mode 100644 (file)
index 0000000..e59447a
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: hsensor mgr impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "hsensormgr_service.h"
+#include <string.h>
+#include <stdbool.h>
+#include "securec.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "sensor_memory.h"
+#include "sensor_tmsg.h"
+#include "sensor_utils.h"
+#include "sensor_para_decision.h"
+
+#define HSENSOR_SCB_MAX_NUM 10
+#define HSENSORMGR_MAX_DATA_LEN (1024 * 1024)
+static HsensorMgr g_hsensormgr = {0};
+static HsensorScb g_hsensorScb[HSENSOR_SCB_MAX_NUM] = {0};
+
+static HsensorMgr *HsensorMgrGetInstance(void)
+{
+    return &g_hsensormgr;
+}
+
+static int32_t HsensorScbMallocDataBuffer(HsensorScb *hsensorScb)
+{
+    if (hsensorScb == NULL) {
+        return SENSOR_ERROR;
+    }
+    uint32_t dataBufSize = hsensorScb->hsensor->caps.sampleElementlen * hsensorScb->decisionPara.batch;
+    if (dataBufSize >= HSENSORMGR_MAX_DATA_LEN) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorScb dataBufSize :%u is invalid.", dataBufSize);
+        return SENSOR_ERROR;
+    }
+    hsensorScb->dataBuf = SensorMalloc(dataBufSize);
+    if (hsensorScb->dataBuf == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorScb MallocDataBuffer NULL.");
+        return SENSOR_ERROR;
+    }
+    hsensorScb->batchDataBuf = hsensorScb->dataBuf;
+    hsensorScb->batchDataBufSize = dataBufSize;
+    hsensorScb->dataBufSize = dataBufSize;
+    return SENSOR_OK;
+}
+
+static int32_t HsensorScbFreeDataBuffer(HsensorScb *hsensorScb)
+{
+    if (hsensorScb == NULL) {
+        return SENSOR_ERROR;
+    }
+    if (hsensorScb->dataBuf == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorScb cDataBuffer NULL.");
+        return SENSOR_ERROR;
+    }
+    SensorFree(hsensorScb->dataBuf);
+    hsensorScb->dataBuf = NULL;
+    hsensorScb->batchDataBuf = NULL;
+    hsensorScb->batchDataBufSize = 0;
+    hsensorScb->dataBufSize = 0;
+    hsensorScb->dataPackSize = 0;
+    return SENSOR_OK;
+}
+
+static void HsensorScbInit(HsensorScb *hsensorScb)
+{
+    if (hsensorScb == NULL) {
+        return;
+    }
+    OSAL_INIT_LIST_HEAD(&(hsensorScb->list));
+    OSAL_INIT_LIST_HEAD(&(hsensorScb->listenerList));
+    hsensorScb->listenerNum = 0;
+    hsensorScb->type = SENSOR_TYPE_NONE;
+    hsensorScb->status = HSENSOR_SCB_UNINITED;
+    hsensorScb->dataBuf = NULL;
+    hsensorScb->dataBufSize = 0;
+    hsensorScb->dataBufIndex = 0;
+    hsensorScb->dataPackSize = 0;
+    hsensorScb->batchCount = 0;
+    SensorPara initDecisionPara = {0};
+    hsensorScb->decisionPara = initDecisionPara;
+    hsensorScb->hsensor = NULL;
+}
+
+static HsensorScb *HsensorScbRequest(uint16_t scbNum)
+{
+    return (scbNum >= HSENSOR_SCB_MAX_NUM) ? NULL : (&g_hsensorScb[scbNum]);
+}
+
+HsensorScb *HsensorMgrHsensorScbFind(const enum SensorTypeTag type)
+{
+    HsensorMgr *hsensorMgr = HsensorMgrGetInstance();
+    HsensorScb *hsensorScbIndex = NULL;
+    osal_list_for_each_entry(hsensorScbIndex, &hsensorMgr->hsensorScbHead, list)
+    {
+        if (type == hsensorScbIndex->type) {
+            return hsensorScbIndex;
+        }
+    }
+    return NULL;
+}
+
+int32_t HsensorMgrInit(void)
+{
+        HILOG_DEBUG(HILOG_MODULE_SEN, "in.");
+    HsensorMgr *hsensorMgr = HsensorMgrGetInstance();
+    if (hsensorMgr->inited) {
+        return SENSOR_OK;
+    }
+    OSAL_INIT_LIST_HEAD(&(hsensorMgr->hsensorScbHead));
+    hsensorMgr->hsensorScbNum = 0;
+    hsensorMgr->dataBuf = NULL;
+    hsensorMgr->dataDispatchBuf = NULL;
+    for (uint16_t i = 0; i < HSENSOR_SCB_MAX_NUM; i++) {
+        HsensorScb *hsensorScb = HsensorScbRequest(i);
+        HsensorScbInit(hsensorScb);
+    }
+    hsensorMgr->inited = true;
+        HILOG_DEBUG(HILOG_MODULE_SEN, "out.");
+    return SENSOR_OK;
+}
+
+/* ******************************************************************************
+  函 数 名          :  HsensormgrCheckListener
+  功能描述         :  检查listener是否存在于该scb中
+  输入参数         :  None
+  输出参数         :  None
+  返 回 值          :  None
+****************************************************************************** */
+static int32_t HsensormgrCheckListener(const HsensorScb *hsensorScb, const HsensorListener *listener)
+{
+    HsensorListener *listenerIndex = NULL;
+    osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+    {
+        if (memcmp(listenerIndex->name, listener->name, (uint32_t)HSENSOR_LISTENER_NAME_MAX_LEN) == 0) {
+            return SENSOR_OK;
+        }
+    }
+    return SENSOR_ERROR;
+}
+
+int32_t HsensorMgrRegisterListener(HsensorListener *listener)
+{
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(listener->type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", listener->type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    if (HsensormgrCheckListener(hsensorScb, listener) == SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name  %s already exits.", listener->name);
+        return SENSOR_HSENSOR_SCB_LISTENER_EXIST;
+    }
+
+    osal_list_add(&listener->list, &hsensorScb->listenerList);
+    hsensorScb->listenerNum++;
+    listener->status = SENSOR_LISTENER_REGISTER;
+    HILOG_DEBUG(HILOG_MODULE_SEN,
+        "hsensorListener name: %s type:%d listenerNum:%u",
+        listener->name,
+        listener->type,
+        hsensorScb->listenerNum);
+    return SENSOR_OK;
+}
+
+int32_t HsensorMgrUnRegisterListener(HsensorListener *listener)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "UnRegister hsensor type %d listener name:%s.",
+                listener->type, listener->name);
+    /* 表示vsensor 注册的 Listener 不需要 UnRegister */
+    if (listener->notifyCallback != NULL) {
+        return SENSOR_OK;
+    }
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(listener->type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", listener->type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    if (HsensormgrCheckListener(hsensorScb, listener) != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name  %s not exits.", listener->name);
+        return SENSOR_HSENSOR_SCB_LISTENER_NOT_EXIST;
+    }
+
+    osal_list_del(&listener->list);
+    hsensorScb->listenerNum--;
+    listener->status = SENSOR_LISTENER_UNREGISTER;
+    SensorUtilsFreeListener(listener);
+    HILOG_DEBUG(HILOG_MODULE_SEN, "UnRegister listenerNum: :%u", hsensorScb->listenerNum);
+    return SENSOR_OK;
+}
+
+static void HsensormgrCheckOpenParam(SensorPara *openParam)
+{
+    if (openParam->period == 0) {
+        openParam->period = SENSOR_PARA_REALTIME_PERIOD_MIN;
+    }
+    if (openParam->batch == 1 || openParam->batch == 0) {
+        openParam->batch = 1;
+        openParam->mode = SENSOR_MODE_REALTIME;
+    }
+    if (openParam->mode == SENSOR_MODE_REALTIME && (openParam->period < SENSOR_PARA_REALTIME_PERIOD_MIN)) {
+        openParam->period = SENSOR_PARA_REALTIME_PERIOD_MIN;
+    }
+}
+
+static void HsensormgrOpenCheckOpenParam(HsensorListener *listener, SensorPara *openParam, uint32_t *reportPeriod)
+{
+    HsensormgrCheckOpenParam(openParam);
+    listener->notifyPeriod = openParam->period * openParam->batch;
+    *reportPeriod = listener->notifyPeriod;
+}
+
+/* ******************************************************************************
+  函 数 名          :  HsensormgrCalculateGCD
+  功能描述         :  计算最大公约数
+  输入参数         :  None
+  输出参数         :  None
+  返 回 值          :  None
+****************************************************************************** */
+static uint32_t HsensormgrCalculateGCD(uint32_t a, uint32_t b)
+{
+    uint32_t c;
+    while (b) {
+        c = b;
+        b = a % b;
+        a = c;
+    }
+    return a;
+}
+
+/* ******************************************************************************
+  函 数 名          :  HsensormgrUpdateOpenParam
+  功能描述         :  更新 scb的 openParam ,遍历所有enable的listener
+  输入参数         :  None
+  输出参数         :  None
+  返 回 值          :  None
+****************************************************************************** */
+static bool HsensormgrUpdateOpenParam(HsensorScb *hsensorScb, SensorPara *openParam, uint32_t reportPeriod)
+{
+    uint8_t openMode = 0;
+    uint32_t reportPeriodGcd = reportPeriod;
+    uint32_t notifyPeriodTemp = 0;
+    bool needOpen = false;
+    uint32_t periodMin = openParam->period;
+    uint32_t notifyPeriodMin = reportPeriod;
+    HsensorListener *listenerIndex = NULL;
+    osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+    {
+        HsensorMgrPrintListener(listenerIndex->type);
+        if (listenerIndex->status == SENSOR_LISTENER_WORKING || listenerIndex->status == SENSOR_LISTENER_ENABLE) {
+            openMode |= (1 << listenerIndex->openParam.mode);
+            periodMin = (periodMin > listenerIndex->openParam.period) ? listenerIndex->openParam.period : periodMin;
+            notifyPeriodMin =
+                (notifyPeriodMin > listenerIndex->notifyPeriod) ? listenerIndex->notifyPeriod : notifyPeriodMin;
+            if (needOpen == false) {
+                reportPeriodGcd = listenerIndex->notifyPeriod;
+            }
+            reportPeriodGcd = HsensormgrCalculateGCD(reportPeriodGcd, notifyPeriodTemp);
+            notifyPeriodTemp = notifyPeriodMin;
+            needOpen = true;
+        }
+    }
+    if (openMode & (1 << SENSOR_MODE_REALTIME)) {
+        openParam->mode = SENSOR_MODE_REALTIME;
+    } else {
+        openParam->mode = SENSOR_MODE_FIFO_MODE;
+    }
+    openParam->period = periodMin;
+    if (periodMin != 0) {
+        openParam->batch = reportPeriodGcd / periodMin;
+    } else {
+        openParam->batch = 0;
+    }
+    HILOG_DEBUG(HILOG_MODULE_SEN, "needOpen: %d", needOpen);
+    return needOpen;
+}
+
+/* ******************************************************************************
+  函 数 名          :  HsensormgrUpdateListener
+  功能描述         :  更新 listener ,并决定是否重新打开 sensor
+                  1. 如果不重启sensor,只需要更新该listener的相关参数即可
+                  2. 如果需要重启sensor,则需要更新所有listener的相关参数
+                  参考6.22未合入的提交
+  输入参数         :  None
+  输出参数         :  None
+  返 回 值          :  None
+****************************************************************************** */
+int32_t HsensormgrUpdateListener(HsensorScb *hsensorScb, HsensorListener *listener, const SensorPara *openParam)
+{
+    if (memcmp(&(hsensorScb->decisionPara), openParam, sizeof(SensorPara)) == 0) {
+        /* 说明不需要重启,更新此次listener的相关参数 */
+        if (hsensorScb->reportPeriod != 0) {
+            listener->sampleCnt = 0;
+            listener->dispatchCnt = listener->notifyPeriod / hsensorScb->reportPeriod;
+            return SENSOR_OK;
+        } else {
+            HILOG_ERROR(HILOG_MODULE_SEN,
+                "hsensorListener name %s type %d open error, batch %d period %d.",
+                listener->name,
+                listener->type,
+                openParam->batch,
+                openParam->period);
+            return SENSOR_HSENSOR_SCB_REPORT_PERIOD_ZERO;
+        }
+    }
+    /* 需要重启hensor */
+    (void)memcpy_s(&hsensorScb->decisionPara, sizeof(SensorPara), openParam, sizeof(SensorPara));
+    hsensorScb->reportPeriod = openParam->batch * openParam->period;
+    if (hsensorScb->reportPeriod == 0) {
+        HILOG_ERROR(HILOG_MODULE_SEN,
+            "hsensorListener name %s type %d open error, batch %d period %d.",
+            listener->name,
+            listener->type,
+            openParam->batch,
+            openParam->period);
+        return SENSOR_HSENSOR_SCB_REPORT_PERIOD_ZERO;
+    }
+
+    int32_t ret = hsensorScb->hsensor->open(&hsensorScb->decisionPara);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN,
+            "hsensorListener name %s type %d open error, batch %u period %u.",
+            listener->name,
+            listener->type,
+            openParam->batch,
+            openParam->period);
+        return ret;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN,
+        "hsensor name %s type %d open batch %u period %u.",
+        hsensorScb->hsensor->name,
+        hsensorScb->type,
+        hsensorScb->decisionPara.batch,
+        hsensorScb->decisionPara.period);
+    return SENSOR_OK;
+}
+
+/* ******************************************************************************
+  函 数 名      : HsensorMgrOpenListener
+  功能描述      :  1.检查open 参数 2.更新所有listener 3.打开对应的hsensor
+
+  输入参数      :  None
+  输出参数      :  None
+  返 回 值      :  None
+****************************************************************************** */
+int32_t HsensorMgrOpenListener(HsensorListener *listener)
+{
+    if (listener == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "listener is null.", listener->type);
+        return SENSOR_HSENSOR_LISTENER_NULL;
+    }
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(listener->type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", listener->type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    // 检查该 listener 是否 存在于scb中
+    if (HsensormgrCheckListener(hsensorScb, listener) != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name  %s type %d not exits.", listener->name, listener->type);
+        return SENSOR_HSENSOR_SCB_LISTENER_NOT_EXIST;
+    }
+    listener->status = SENSOR_LISTENER_ENABLE;
+    SensorPara openParam = listener->openParam;
+    uint32_t reportPeriod = 0;
+    /* 计算此次listener的reportPeriod等 */
+    HILOG_DEBUG(HILOG_MODULE_SEN,
+        "open listener para period: %u batch: %u mode: %d option: %u ",
+        openParam.period,
+        openParam.batch,
+        openParam.mode,
+        openParam.option);
+    HsensormgrOpenCheckOpenParam(listener, &openParam, &reportPeriod);
+    /* 遍历所有使能的listener,更新全局的openParam */
+    if (HsensormgrUpdateOpenParam(hsensorScb, &openParam, reportPeriod) == false) {
+        HILOG_INFO(
+            HILOG_MODULE_SEN, "hsensor not need open, listener open type %d name %s ", listener->type, listener->name);
+        return SENSOR_OK;
+    }
+    if (HsensormgrUpdateListener(hsensorScb, listener, &openParam) != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name  %s type %d open error.", listener->name, listener->type);
+        return SENSOR_ERROR;
+    }
+    listener->status = SENSOR_LISTENER_WORKING;
+    uint32_t taskId = SensorUtilsGetRegisteredTaskId(listener->type);
+    if (taskId != SENSOR_FAILURE) {  // 已经创建线程
+        return SENSOR_OK;
+    }
+    int32_t ret = HsensorScbMallocDataBuffer(hsensorScb);
+    if (ret != SENSOR_OK) {
+        return ret;
+    }
+    ret = SensorTaskCreateHsensorTask(hsensorScb->hsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d CreateHsensorTask failed.", listener->type);
+        return ret;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "hsensor listener open type %d name %s ", listener->type, listener->name);
+    return SENSOR_OK;
+}
+
+/* ******************************************************************************
+  函 数 名          :  HsensormgrCloseCheckOpenParam
+  功能描述         :  遍历剩余的使能的listener,找到一个开启的openParam
+  输入参数         :  None
+  输出参数         :  None
+  返 回 值          :  None
+****************************************************************************** */
+static void HsensormgrCloseCheckOpenParam(HsensorScb *hsensorScb, SensorPara *openParam, uint32_t *reportPeriod)
+{
+    HsensorListener *listenerIndex = NULL;
+    osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+    {
+        if (listenerIndex->status == SENSOR_LISTENER_WORKING || listenerIndex->status == SENSOR_LISTENER_ENABLE) {
+            (void)memcpy_s(openParam, sizeof(SensorPara), &listenerIndex->openParam, sizeof(SensorPara));
+            HsensormgrCheckOpenParam(openParam);
+            *reportPeriod = openParam->period * openParam->batch;
+            break;
+        }
+    }
+}
+
+int32_t HsensorMgrCloseListener(HsensorListener *listener)
+{
+    if (listener == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "close listener is null.");
+        return SENSOR_HSENSOR_LISTENER_NULL;
+    }
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(listener->type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", listener->type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    if (HsensormgrCheckListener(hsensorScb, listener) != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorListener name  %s not exits.", listener->name);
+        return SENSOR_ERROR;
+    }
+    uint32_t reportPeriod = 0;
+    SensorPara openParam = {.period = 0, .batch = 0, .mode = SENSOR_MODE_REALTIME, .option = 0};
+    listener->status = SENSOR_LISTENER_DISABLE;
+
+    HsensormgrCloseCheckOpenParam(hsensorScb, &openParam, &reportPeriod);
+    /* 遍历所有使能的listener,更新全局的openParam */
+    if (HsensormgrUpdateOpenParam(hsensorScb, &openParam, reportPeriod) == false) {
+        /* 不存在打开的listener,关闭hsensor */
+        int32_t ret = SensorTaskDestroyHsensorTask(hsensorScb->type);
+        if (ret != SENSOR_OK) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d Destroy failed.", hsensorScb->type);
+        }
+        ret = HsensorScbFreeDataBuffer(hsensorScb);
+        if (ret != SENSOR_OK) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d FreeData failed.", hsensorScb->type);
+            return ret;
+        }
+        memset_s(&hsensorScb->decisionPara, sizeof(SensorPara), 0, sizeof(SensorPara));
+        hsensorScb->hsensor->close();
+        HILOG_INFO(HILOG_MODULE_SEN, "hsensor name %s type %d close.", hsensorScb->hsensor->name, hsensorScb->type);
+        return SENSOR_OK;
+    } else {
+        /* 还存在使能的listener, */
+        if (HsensormgrUpdateListener(hsensorScb, listener, &openParam) != SENSOR_OK) {
+            HILOG_ERROR(
+                HILOG_MODULE_SEN, "hsensorListener name  %s type %d open error.", listener->name, listener->type);
+            return SENSOR_ERROR;
+        }
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "hsensor listener close type %d name %s ", listener->type, listener->name);
+    return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorOpen(const Sensor *sensor, const SensorPara *openPara)
+{
+    HILOG_INFO(HILOG_MODULE_SEN,
+        "SensorOpen hsensor type:%d name:%s period:%u batch:%u option:%u mode:%d",
+        sensor->sensorInfo.type,
+        sensor->sensorInfo.name,
+        openPara->period,
+        openPara->batch,
+        openPara->option,
+        openPara->mode);
+    int32_t ret = SENSOR_OK;
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    HsensorMgrPrintListener(sensor->sensorInfo.type);
+    HsensorListener *listenerIndex = NULL;
+    osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+    {
+        HILOG_DEBUG(HILOG_MODULE_SEN,
+            "hsensor type: %d openParam:%d name:%s",
+            sensor->sensorInfo.type,
+            SensorParaIsClear(&listenerIndex->openParam),
+            listenerIndex->name);
+        /* 表示vsensor 注册的 Listener 不需要 APP open */
+        if (listenerIndex->notifyCallback != NULL) {
+            continue;
+        }
+        if (SensorParaIsClear(&listenerIndex->openParam)) {
+            SensorParaCopy(&listenerIndex->openParam, openPara);
+        }
+        ret = HsensorMgrOpenListener(listenerIndex);
+        if (ret != SENSOR_OK) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d OpenListener failed.", sensor->sensorInfo.type);
+        }
+    }
+    return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorClose(const Sensor *sensor)
+{
+    int32_t ret = SENSOR_OK;
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    HsensorMgrPrintListener(sensor->sensorInfo.type);
+    HsensorListener *listenerIndex = NULL;
+    HsensorListener *listenerIndexTemp = NULL;
+    osal_list_for_each_entry_safe(listenerIndex, listenerIndexTemp, &hsensorScb->listenerList, list)
+    {
+        ret = HsensorMgrCloseListener(listenerIndex);
+        if (ret != SENSOR_OK) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d CloseListener failed.", sensor->sensorInfo.type);
+        }
+
+        ret = HsensorMgrUnRegisterListener(listenerIndex);
+        if (ret != SENSOR_OK) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "UnRegisterListener fail.");
+        }
+    }
+    HILOG_DEBUG(HILOG_MODULE_SEN, "close sensorInfo type : %d", sensor->sensorInfo.type);
+    return SENSOR_OK;
+}
+
+/* samplingInterval Indicates the sensor data sampling interval to set, in millisecond. 数据采样间隔 */
+/* reportInterval Indicates the sensor data reporting interval, in millisecond.数据上报间隔 */
+static int32_t HsensorMgrSensorSetBatch(Sensor *sensor, int64_t samplingInterval, int64_t reportInterval)
+{
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    if (samplingInterval < SENSOR_PARA_REALTIME_PERIOD_MIN || samplingInterval > SENSOR_PARA_REALTIME_PERIOD_MAX) {
+        HILOG_ERROR(HILOG_MODULE_SEN,
+            "samplingInterval is max: %d to min: %d, samplingInterval: %d ",
+            SENSOR_PARA_REALTIME_PERIOD_MAX,
+            SENSOR_PARA_REALTIME_PERIOD_MIN,
+            samplingInterval,
+            reportInterval);
+        return SENSOR_HSENSOR_PERIOD_BATCH_ERR;
+    }
+    uint32_t batch = reportInterval / samplingInterval;
+    uint32_t maxBatchCount = hsensorScb->hsensor->caps.maxBatchCount;
+    if (batch < SENSOR_PARA_BATCH_MIN || batch > maxBatchCount) {
+        HILOG_ERROR(
+            HILOG_MODULE_SEN, "batch is max: %d to min: %d, batch: %u ", maxBatchCount, SENSOR_PARA_BATCH_MIN, batch);
+        return SENSOR_HSENSOR_PERIOD_BATCH_ERR;
+    }
+    sensor->sensorInfo.openPara.period = samplingInterval;
+    sensor->sensorInfo.openPara.batch = batch;
+    HILOG_INFO(HILOG_MODULE_SEN,
+        "samplingInterval: %lld reportInterval: %lld batch: %u",
+        samplingInterval,
+        reportInterval,
+        batch);
+    return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorSetMode(Sensor *sensor, int32_t mode)
+{
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    if (mode < 0 || mode >= SENSOR_MODE_MAX) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d set mode error %d", hsensorScb->type, mode);
+        return SENSOR_HSENSOR_MODE_ERR;
+    }
+    sensor->sensorInfo.openPara.mode = mode;
+    HILOG_INFO(HILOG_MODULE_SEN, "mode: %d ", mode);
+    return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorSetOption(Sensor *sensor, uint32_t option)
+{
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    hsensorScb->decisionPara.option = option;
+    return SENSOR_OK;
+}
+
+static HsensorListener *HsensorMgrHlistenerInit(const Sensor *sensor, RecordDataCallback cb)
+{
+    HsensorListener *listener = SensorUtilsRequestListener();
+    if (listener == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d listener get fail.", sensor->sensorInfo.type);
+        return NULL;
+    }
+    errno_t err = memset_s(listener, sizeof(HsensorListener), 0, sizeof(HsensorListener));
+    if (err != EOK) {
+        SensorUtilsFreeListener(listener);
+        HILOG_ERROR(HILOG_MODULE_SEN, "ResultCallback memset failed! type:%d", sensor->sensorInfo.type);
+        return NULL;
+    }
+    err = strcat_s(listener->name, sizeof(listener->name), "APP");
+    if (err != EOK) {
+        SensorUtilsFreeListener(listener);
+        HILOG_ERROR(HILOG_MODULE_SEN, "ResultCallback init name strcat full! type:%d", sensor->sensorInfo.type);
+        return NULL;
+    }
+    err = strcat_s(listener->name, sizeof(listener->name), sensor->sensorInfo.name);
+    if (err != EOK) {
+        SensorUtilsFreeListener(listener);
+        HILOG_ERROR(HILOG_MODULE_SEN, "ResultCallback init name strcat full! type:%d", sensor->sensorInfo.type);
+        return NULL;
+    }
+    listener->type = sensor->sensorInfo.type;
+    listener->resultDataCb = cb;
+    HILOG_INFO(HILOG_MODULE_SEN,
+        "HlistenerInit hsensor type:%d name:%s period:%u batch:%u option:%u mode:%u",
+        sensor->sensorInfo.type,
+        sensor->sensorInfo.name,
+        sensor->sensorInfo.openPara.period,
+        sensor->sensorInfo.openPara.batch,
+        sensor->sensorInfo.openPara.option,
+        sensor->sensorInfo.openPara.mode);
+    return listener;
+}
+
+static int32_t HsensorMgrSensorRegisterResultCallback(const Sensor *sensor, RecordDataCallback cb)
+{
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb or simpleName get fail.", sensor->sensorInfo.type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    HsensorListener *listener = HsensorMgrHlistenerInit(sensor, cb);
+    if (listener == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "RegisterListener failed! type:%d", sensor->sensorInfo.type);
+        return SENSOR_HSENSOR_LISTENER_NULL;
+    }
+    int32_t ret = HsensorMgrRegisterListener(listener);
+    if (ret != SENSOR_OK) {
+        SensorUtilsFreeListener(listener);
+        HILOG_ERROR(HILOG_MODULE_SEN, "RegisterListener failed! type:%d", sensor->sensorInfo.type);
+        return ret;
+    }
+    return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorUnregisterResultCallback(const Sensor *sensor, RecordDataCallback cb)
+{
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", sensor->sensorInfo.type);
+        return SENSOR_HSENSOR_SCB_NULL;
+    }
+    HsensorListener *listenerIndex = NULL;
+    HsensorListener *listener = NULL;
+    osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+    {
+        if (listenerIndex->resultDataCb == cb) {
+            listener = listenerIndex;
+            HILOG_INFO(HILOG_MODULE_SEN, "hsensor type %d RecordDataCallback exits.", sensor->sensorInfo.type);
+            break;
+        }
+    }
+    if (listener == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "HsensorListener get fail.");
+        return SENSOR_HSENSOR_LISTENER_NULL;
+    }
+    int32_t ret = HsensorMgrCloseListener(listener);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d CloseListener failed.", sensor->sensorInfo.type);
+    }
+    ret = HsensorMgrUnRegisterListener(listener);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "UnRegisterListener fail.");
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "hsensor type: %d Unregister Success", sensor->sensorInfo.type);
+    return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorCalibrate(const Sensor *sensor, void *para, uint32_t len)
+{
+    HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+    return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorSelfTest(const Sensor *sensor, void *para, uint32_t len)
+{
+    HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+    return SENSOR_OK;
+}
+
+static int32_t HsensorMgrSensorIoctl(const Sensor *sensor, SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    if (cmd >= SENSOR_IOCTL_MAX || cmd < SENSOR_IOCTL_SET_PARA) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "invalid command!");
+        return SENSOR_ERROR;
+    }
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(sensor->sensorInfo.type);
+    if (hsensorScb->hsensor->ioctl == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "invalid ioctl function!");
+        return SENSOR_ERROR;
+    }
+    return hsensorScb->hsensor->ioctl(cmd, data, len);
+}
+
+static int32_t HsensorMgrSensorRegisterProc(const Hsensor *hsensor)
+{
+    Sensor *sensor = SensorUtilsRequestSensor(hsensor->type);
+    if (sensor == NULL || sensor->sensorInfo.state != SENSOR_STATE_IDLE) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "sensor type %d name %s request fail.", hsensor->type, hsensor->name);
+        return SENSOR_ERROR;
+    }
+    sensor->sensorInfo.type = hsensor->type;
+    sensor->sensorInfo.name = hsensor->name;
+    SensorParaDefaultInit(&sensor->sensorInfo.openPara);
+    sensor->open = HsensorMgrSensorOpen;
+    sensor->close = HsensorMgrSensorClose;
+    sensor->setBatch = HsensorMgrSensorSetBatch;
+    sensor->setMode = HsensorMgrSensorSetMode;
+    sensor->setOption = HsensorMgrSensorSetOption;
+    sensor->registerResultCallback = HsensorMgrSensorRegisterResultCallback;
+    sensor->unregisterResultCallback = HsensorMgrSensorUnregisterResultCallback;
+    sensor->calibrate = HsensorMgrSensorCalibrate;
+    sensor->selfTest = HsensorMgrSensorSelfTest;
+    sensor->ioctl = HsensorMgrSensorIoctl;
+    HILOG_INFO(HILOG_MODULE_SEN,
+        "hsensor type:%d name:%s period:%u batch:%u option:%u mode:%d",
+        hsensor->type,
+        hsensor->name,
+        sensor->sensorInfo.openPara.period,
+        sensor->sensorInfo.openPara.batch,
+        sensor->sensorInfo.openPara.option,
+        sensor->sensorInfo.openPara.mode);
+    return SENSOR_OK;
+}
+
+int32_t HsensorMgrRegister(const Hsensor *hsensor)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "register hsensor type:%d name:%s ", hsensor->type, hsensor->name);
+    HsensorMgr *hsensorMgr = HsensorMgrGetInstance();
+    if (!hsensorMgr->inited && (HsensorMgrInit() != SENSOR_OK)) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorMgr inited failed.");
+        return SENSOR_ERROR;
+    }
+    HsensorScb *hsensorScbIndex = NULL;
+    osal_list_for_each_entry(hsensorScbIndex, &hsensorMgr->hsensorScbHead, list)
+    {
+        if (hsensorScbIndex->type == hsensor->type) {
+            HILOG_WARN(HILOG_MODULE_SEN, "hsensor type %d already exits.", hsensorScbIndex->type);
+            return SENSOR_HSENSOR_REGISTER_TYPE_DUPLICATE;
+        }
+    }
+    HsensorScb *hsensorScb = HsensorScbRequest(hsensorMgr->hsensorScbNum);
+    if (hsensorScb == NULL || hsensorScb->status != HSENSOR_SCB_UNINITED) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensorScb type %d name %s request fail.", hsensor->type, hsensor->name);
+        return SENSOR_ERROR;
+    }
+    if (hsensor->init() != SENSOR_OK) {
+        hsensor->deinit();
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d name %s init fail.", hsensor->type, hsensor->name);
+        return SENSOR_ERROR;
+    }
+    hsensorScb->hsensor = (Hsensor *)hsensor;
+    hsensorScb->type = hsensor->type;
+    int32_t ret = SensorUtilsAddHsensorList(hsensorScb);
+    if (ret != SENSOR_OK) {
+        hsensorScb->type = SENSOR_TYPE_NONE;
+        hsensor->deinit();
+        HILOG_ERROR(
+            HILOG_MODULE_SEN, "hsensor type %d name %s SensorUtilsAddSensorList fail", hsensor->type, hsensor->name);
+        return SENSOR_ERROR;
+    }
+    ret = HsensorMgrSensorRegisterProc(hsensor);
+    if (ret != SENSOR_OK) {
+        hsensorScb->type = SENSOR_TYPE_NONE;
+        hsensor->deinit();
+        HILOG_ERROR(HILOG_MODULE_SEN, "hsensor type %d name %s SensorRegisterProc fail", hsensor->type, hsensor->name);
+        return SENSOR_ERROR;
+    }
+    hsensorScb->status = HSENSOR_SCB_INITED;
+    osal_list_add(&hsensorScb->list, &hsensorMgr->hsensorScbHead);
+    hsensorMgr->hsensorScbNum++;
+    HILOG_INFO(HILOG_MODULE_SEN, "register hsensor type %d name  %s success.", hsensor->type, hsensor->name);
+    return SENSOR_OK;
+}
+
+int32_t HsensorMgrIoctl(enum SensorTypeTag type, SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(type);
+    if (hsensorScb == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d hsensorScb get fail.", type);
+        return SENSOR_ERROR;
+    }
+    if (hsensorScb->hsensor != NULL && hsensorScb->hsensor->ioctl != NULL) {
+        return hsensorScb->hsensor->ioctl(cmd, data, len);
+    }
+    return SENSOR_ERROR;
+}
+
+void HsensorMgrPrintListener(enum SensorTypeTag type)
+{
+    HsensorScb *hsensorScb = HsensorMgrHsensorScbFind(type);
+    if (hsensorScb == NULL) {
+        return;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "type: %d listenerNum:%u", type, hsensorScb->listenerNum);
+    HsensorListener *listenerIndex = NULL;
+    osal_list_for_each_entry(listenerIndex, &hsensorScb->listenerList, list)
+    {
+        HILOG_INFO(HILOG_MODULE_SEN,
+            "type %d name %s period %u batch %u mode %d option %u status %d",
+            listenerIndex->type,
+            listenerIndex->name,
+            listenerIndex->openParam.period,
+            listenerIndex->openParam.batch,
+            listenerIndex->openParam.mode,
+            listenerIndex->openParam.option,
+            listenerIndex->status);
+    }
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/sensor_interface_impl.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/sensor_interface_impl.c
new file mode 100644 (file)
index 0000000..ff45f32
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor interface impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include "securec.h"
+#include "sensor_thread.h"
+#include "sensor_common.h"
+#include "sensor_if.h"
+#include "sensor_manager.h"
+
+struct SensorInterfaceContext {
+    bool inited;
+    MutexId mutex;
+};
+
+struct SensorInterfaceContext g_sensorInterfaceCtx = {
+    .inited = false,
+    .mutex = NULL,
+};
+
+static void GetSensorDeviceMethods(struct SensorInterface *device);
+
+const struct SensorInterface *NewSensorInterfaceInstance(void)
+{
+        HILOG_ERROR(HILOG_MODULE_SEN, "in");
+    g_sensorInterfaceCtx.mutex = SensorMutexCreate(NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(g_sensorInterfaceCtx.mutex, NULL);
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    static struct SensorInterface sensorDevInstance;
+    if (g_sensorInterfaceCtx.inited) {
+        SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+        return &sensorDevInstance;
+    }
+    int32_t ret = SensorMgrInit();
+    if (ret != SENSOR_OK) {
+        SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+        HILOG_ERROR(HILOG_MODULE_SEN, "SensorMgrInit failed");
+        return NULL;
+    }
+
+    // Construct device interface instance
+    GetSensorDeviceMethods(&sensorDevInstance);
+
+    g_sensorInterfaceCtx.inited = true;
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    HILOG_DEBUG(HILOG_MODULE_APP, "Get sensor instance success");
+    return &sensorDevInstance;
+}
+
+int32_t FreeSensorInterfaceInstance(void)
+{
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    if (!g_sensorInterfaceCtx.inited) {
+        SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+        return SENSOR_OK;
+    }
+    SensorMgrDeInit();
+    g_sensorInterfaceCtx.inited = false;
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    SensorMutexDestroy(&g_sensorInterfaceCtx.mutex);
+    return SENSOR_OK;
+}
+
+static int32_t GetSensorInfo(struct SensorInformation **sensorInfo, int32_t *count)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    int32_t ret = SensorMgrGetAllSensors(sensorInfo, count);
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    return ret;
+}
+
+static int32_t EnableSensor(int32_t sensorTypeId)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    int32_t ret = SensorMgrEnable(sensorTypeId);
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    return ret;
+}
+
+static int32_t DisableSensor(int32_t sensorTypeId)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    int32_t ret = SensorMgrDisable(sensorTypeId);
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    return ret;
+}
+
+static int32_t RegisterSensorDataCb(int32_t sensorTypeId, RecordDataCallback cb)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "enter sensorId:%d", sensorTypeId);
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    int32_t ret = SensorMgrRegistDataCallback(sensorTypeId, cb);
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    return ret;
+}
+
+static int32_t UnregisterSensorDataCb(int32_t sensorTypeId, RecordDataCallback cb)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "enter sensorId:%d", sensorTypeId);
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    int32_t ret = SensorMgrUnregistDataCallback(sensorTypeId, cb);
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    return ret;
+}
+
+static int32_t SetSensorBatch(int32_t sensorTypeId, int64_t samplingInterval, int64_t interval)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    int32_t ret = SensorMgrSetBatch(sensorTypeId, samplingInterval, interval);
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    return ret;
+}
+
+static int32_t SetSensorMode(int32_t sensorTypeId, int32_t mode)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    int32_t ret = SensorMgrSetMode(sensorTypeId, mode);
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    return ret;
+}
+
+static int32_t SetSensorOption(int32_t sensorTypeId, uint32_t option)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+    SensorMutexLock(g_sensorInterfaceCtx.mutex);
+    int32_t ret = SensorMgrSetOption(sensorTypeId, option);
+    SensorMutexUnLock(g_sensorInterfaceCtx.mutex);
+    return ret;
+}
+
+static int32_t SensorIfGetData(int32_t sensorTypeId, SensorData *sensorData)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "enter");
+    return SensorMgrGetData(sensorTypeId, sensorData);
+}
+
+void GetSensorDeviceMethods(struct SensorInterface *device)
+{
+    CHECK_NULL_PTR_RETURN(device);
+    device->GetAllSensors = GetSensorInfo;
+    device->Enable = EnableSensor;
+    device->Disable = DisableSensor;
+    device->SetBatch = SetSensorBatch;
+    device->SetMode = SetSensorMode;
+    device->SetOption = SetSensorOption;
+    device->Register = RegisterSensorDataCb;
+    device->Unregister = UnregisterSensorDataCb;
+    device->GetSensorData = SensorIfGetData;
+}
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/sensor_manager.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/sensor_manager.c
new file mode 100644 (file)
index 0000000..0a69d8a
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor mgr
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_manager.h"
+#include "sensor_common.h"
+#include "sensor_utils.h"
+#include "sensor_if.h"
+#include "hsensormgr_service.h"
+#include "vsensormgr_service.h"
+
+int32_t SensorMgrInit(void)
+{
+    int32_t ret = HsensorMgrInit();
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "HsensorMgrInit err!", ret);
+        return ret;
+    }
+    ret = VsensorMgrInit();
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "VsensorMgrInit err!", ret);
+        return ret;
+    }
+    SensorUtilsInit();
+    return SENSOR_OK;
+}
+
+int32_t SensorMgrDeInit(void)
+{
+    return SENSOR_OK;
+}
+
+int32_t SensorMgrRegistHsensor(const Hsensor *sensor)
+{
+    int32_t ret = SensorUtilsHsensorCheck(sensor);
+    if (ret != SENSOR_OK) {
+        HILOG_INFO(HILOG_MODULE_SEN, "hsensor:%d entry check err!", sensor->type);
+        return ret;
+    }
+    return HsensorMgrRegister(sensor);
+}
+
+int32_t SensorMgrRegistVsensor(const Vsensor *sensor)
+{
+    int32_t ret = SensorUtilsVsensorCheck(sensor);
+    if (ret != SENSOR_OK) {
+        HILOG_INFO(HILOG_MODULE_SEN, "vsensor:%d entry check err!", sensor->type);
+        return ret;
+    }
+    return VsensorMgrRegister(sensor);
+}
+
+int32_t SensorMgrGetAllSensors(struct SensorInformation **sensorInfo, int32_t *count)
+{
+    return SensorUtilsGetAllSensors(sensorInfo, count);
+}
+
+int32_t SensorMgrEnable(int32_t sensorTypeId)
+{
+    Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+    if (sensor == NULL || sensor->open == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+        return SENSOR_ENTRY_PARA_ERROR;
+    }
+    return sensor->open(sensor, &sensor->sensorInfo.openPara);
+}
+
+int32_t SensorMgrDisable(int32_t sensorTypeId)
+{
+    Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+    if (sensor == NULL || sensor->close == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+        return SENSOR_ENTRY_PARA_ERROR;
+    }
+    return sensor->close(sensor);
+}
+
+int32_t SensorMgrSetBatch(int32_t sensorTypeId, int64_t samplingInterval, int64_t reportInterval)
+{
+    Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+    if (sensor == NULL || sensor->setBatch == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+        return SENSOR_ENTRY_PARA_ERROR;
+    }
+    return sensor->setBatch(sensor, samplingInterval, reportInterval);
+}
+
+int32_t SensorMgrSetMode(int32_t sensorTypeId, int32_t mode)
+{
+    Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+    if (sensor == NULL || sensor->setMode == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+        return SENSOR_ENTRY_PARA_ERROR;
+    }
+    return sensor->setMode(sensor, mode);
+}
+
+int32_t SensorMgrSetOption(int32_t sensorTypeId, uint32_t option)
+{
+    Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+    if (sensor == NULL || sensor->setOption == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[INF] sensor NULL!\n");
+        return SENSOR_ENTRY_PARA_ERROR;
+    }
+    return sensor->setOption(sensor, option);
+}
+
+int32_t SensorMgrRegistDataCallback(int32_t sensorTypeId, RecordDataCallback cb)
+{
+    Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+    CHECK_NULL_PTR_RETURN_VALUE(sensor, SENSOR_ENTRY_PARA_ERROR);
+    CHECK_NULL_PTR_RETURN_VALUE(sensor->registerResultCallback, SENSOR_ENTRY_PARA_ERROR);
+    return sensor->registerResultCallback(sensor, cb);
+}
+
+int32_t SensorMgrUnregistDataCallback(int32_t sensorTypeId, RecordDataCallback cb)
+{
+    Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+    CHECK_NULL_PTR_RETURN_VALUE(sensor, SENSOR_ENTRY_PARA_ERROR);
+    CHECK_NULL_PTR_RETURN_VALUE(sensor->unregisterResultCallback, SENSOR_ENTRY_PARA_ERROR);
+    return sensor->unregisterResultCallback(sensor, cb);
+}
+
+int32_t SensorMgrGetData(int32_t sensorTypeId, SensorData *sensorData)
+{
+    Sensor *sensor = SensorUtilsFindSensor(sensorTypeId);
+    CHECK_NULL_PTR_RETURN_VALUE(sensor, SENSOR_ENTRY_PARA_ERROR);
+    CHECK_NULL_PTR_RETURN_VALUE(sensor->ioctl, SENSOR_ENTRY_PARA_ERROR);
+    return sensor->ioctl(sensor, SENSOR_IOCTL_GET_SENSOR_DATA, sensorData, sizeof(SensorData));
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/include/sensor_task.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/include/sensor_task.h
new file mode 100644 (file)
index 0000000..b8ee814
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor task
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_TASK_H
+#define SENSOR_TASK_H
+
+#include <stdbool.h>
+#include "sensor_typedef.h"
+#include "sensor_thread.h"
+#include "sensor_msgqueue.h"
+#include "soc_osal.h"
+
+typedef struct {
+    struct osal_list_head list;          /* SensorTaskCfg link point */
+    uint32_t taskId;
+    SensorThreadCfg threadCfg;
+    SensorMsgQueueCfg msgQueueCfg;
+    bool runningFlag;
+    ThreadId *task;
+    bool taskExited;
+} SensorTaskCfg;
+
+typedef enum {
+    SENSOR_TASK_PRIORITY_HIGH = osPriorityHigh,
+    SENSOR_TASK_PRIORITY_MIDDLE = osPriorityNormal,
+    SENSOR_TASK_PRIORITY_LOW = osPriorityLow6
+} SensorTaskPriority;
+
+#define SENSORMGR_TASK_MSG_QUEUE_LENGTH         32
+#define TASK_MSG_QUEUE_LENGTH_DEFAULT           32
+#ifdef JS_ENABLE
+#define HSENSOR_TASK_STACK_SIZE               8192
+#define VSENSOR_TASK_STACK_SIZE               8192
+#else
+#define HSENSOR_TASK_STACK_SIZE               2048
+#define VSENSOR_TASK_STACK_SIZE               4096
+#endif
+
+#define SENSOR_TASK_CREATE_OK_WAIT_TIMEOUT          1000 // ms
+#define SENSOR_TASK_CREATE_TICK_TIME                50   // ms
+
+#define SENSOR_TASK_MAX_CNT                10
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t SensorTaskInit(void);
+
+/* 创建vsensor任务 */
+int32_t SensorTaskCreateVsensorTask(const Vsensor *vsensor);
+
+/* 创建hsensor任务 */
+int32_t SensorTaskCreateHsensorTask(const Hsensor *hsensor);
+
+/* 销毁vsensor任务 */
+int32_t SensorTaskDestroyVsensorTask(enum SensorTypeTag type);
+
+/* 销毁hsensor任务 */
+int32_t SensorTaskDestroyHsensorTask(enum SensorTypeTag type);
+
+/* 获取任务消息队列句柄 */
+SensorMsgQueueCfg *SensorTaskGetTaskMsgqueueHandle(uint32_t taskId);
+
+/* 判断任务运行状态(true和false) */
+bool SensorTaskGetRunningFlag(uint32_t taskId);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/include/sensor_tmsg.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/include/sensor_tmsg.h
new file mode 100644 (file)
index 0000000..a9d7db4
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor msg
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_TMSG_H
+#define SENSOR_TMSG_H
+
+#include "sensor_typedef.h"
+#include "sensor_task.h"
+
+/* FA线程间消息定义 */
+typedef enum {
+    SENSOR_TMSG_INVALID = 0,
+
+    /* 虚拟vsensor管理消息 */
+    SENSOR_TMSG_HSENSOR_DATA_UPDATE,
+    SENSOR_TMSG_VSENSOR_DATA_UPDATE,
+    SENSOR_TMSG_VSENSOR_REG_EVENT,
+    SENSOR_TMSG_VSENSOR_OPEN_EVENT,
+    SENSOR_TMSG_VSENSOR_CLOSE_EVENT,
+    SENSOR_TMSG_VSENSOR_RELY_OPEN_EVENT,
+    SENSOR_TMSG_VSENSOR_RELY_CLOSE_EVENT,
+
+    SENSOR_TMSG_MAX_ID
+} SensorTmsgId;
+
+typedef struct {
+    SensorTmsgId id;
+    uintptr_t value;
+    uint64_t ts;
+    void *info;
+    uint32_t infoSize;
+} SensorTmsg;
+
+typedef struct {
+    SensorTmsgId tmsgId;
+    int32_t (*tmsgProc)(const SensorTmsg* tmsg);
+} SensorTmsgProcMap;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t SensorTmsgSend(uint32_t taskId, SensorTmsg* tmsg);
+int32_t SensorTmsgRecv(uint32_t taskId, SensorTmsg* tmsg);
+int32_t SensorTmsgFree(SensorTmsg* tmsg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/src/sensor_task.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/src/sensor_task.c
new file mode 100644 (file)
index 0000000..1a6381c
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor task impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_task.h"
+#include "sensor_tmsg.h"
+#include "vsensor_task_mgr.h"
+#include "securec.h"
+#include "sensor_log.h"
+#include "sensor_utils.h"
+#include "sensor_common.h"
+#include "sensor_memory.h"
+#include "hsensor_data_service.h"
+
+static void VsensorTaskFunc(void* param);
+static void HsensorTaskFunc(void* param);
+
+typedef struct {
+    struct osal_list_head sensorTaskHead; // SensorTaskCfg
+    uint32_t sensorTaskNum;
+    bool sensorTaskId[SENSOR_TASK_MAX_CNT];
+} SensorTaskContext;
+
+static SensorTaskContext g_sensorTaskCxt = {
+    .sensorTaskNum = 0,
+    .sensorTaskId = {0}
+};
+
+static SensorTaskContext *SensorTaskGetInstance(void)
+{
+    return &g_sensorTaskCxt;
+}
+
+int32_t SensorTaskInit(void)
+{
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    OSAL_INIT_LIST_HEAD(&(ctx->sensorTaskHead));
+    ctx->sensorTaskNum = 0;
+    return SENSOR_OK;
+}
+
+SensorMsgQueueCfg *SensorTaskGetTaskMsgqueueHandle(uint32_t taskId)
+{
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    SensorTaskCfg *sensorTaskIndex = NULL;
+    osal_list_for_each_entry(sensorTaskIndex, &ctx->sensorTaskHead, list)
+    {
+        if (taskId == sensorTaskIndex->taskId) {
+            return &(sensorTaskIndex->msgQueueCfg);
+        }
+    }
+    return NULL;
+}
+
+static void SensorTaskAddTaskCfg(SensorTaskCfg *sensorTask)
+{
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    osal_list_add(&sensorTask->list, &ctx->sensorTaskHead);
+    ctx->sensorTaskNum++;
+    HILOG_INFO(HILOG_MODULE_SEN, "[task] add task:%u!", sensorTask->taskId);
+}
+
+static SensorTaskCfg *SensorTaskFindTaskCfg(enum SensorTypeTag type)
+{
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    uint32_t taskId = SensorUtilsGetRegisteredTaskId(type);
+    if (taskId == SENSOR_FAILURE) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] TaskSync not found taskId type:%d", type);
+        return NULL;
+    }
+    SensorTaskCfg *sensorTaskIndex = NULL;
+    SensorTaskCfg *sensorTask = NULL;
+    osal_list_for_each_entry(sensorTaskIndex, &ctx->sensorTaskHead, list)
+    {
+        if (sensorTaskIndex->taskId != taskId) {
+            continue;
+        }
+        sensorTask = sensorTaskIndex;
+        break;
+    }
+    return sensorTask;
+}
+
+static void SensorTaskRemoveTaskCfg(SensorTaskCfg *sensorTask)
+{
+    CHECK_NULL_PTR_RETURN(sensorTask);
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    SensorTaskCfg *sensorTaskIndex = NULL;
+    bool found = false;
+    osal_list_for_each_entry(sensorTaskIndex, &ctx->sensorTaskHead, list)
+    {
+        if (sensorTask->taskId == sensorTaskIndex->taskId) {
+            found = true;
+        }
+    }
+    if (found) {
+        g_sensorTaskCxt.sensorTaskId[sensorTask->taskId] = false;
+        osal_list_del(&sensorTask->list);
+        ctx->sensorTaskNum--;
+    }
+    SensorFree(sensorTask);
+}
+
+bool SensorTaskGetRunningFlag(uint32_t taskId)
+{
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    SensorTaskCfg *sensorTaskIndex = NULL;
+    osal_list_for_each_entry(sensorTaskIndex, &ctx->sensorTaskHead, list)
+    {
+        if (taskId == sensorTaskIndex->taskId) {
+            return sensorTaskIndex->runningFlag;
+        }
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "[task] run_flag cannot find task:%d!", taskId);
+    return false;
+}
+
+static void VsensorTaskFunc(void* param)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "[task] in");
+    SensorTmsg tmsg = {0};
+    SensorTaskCfg *taskCfg = (SensorTaskCfg *)param;
+    CHECK_NULL_PTR_RETURN(taskCfg);
+    int32_t ret = VsensorTaskMgrInit(taskCfg->taskId);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[task] VsensorTaskMgrInit FAIL! ret:0x%X, taskId:%d", ret, taskCfg->taskId);
+        return;
+    }
+    taskCfg->runningFlag = true;
+    while (taskCfg->runningFlag) {
+        int32_t ret = SensorTmsgRecv(taskCfg->taskId, &tmsg);
+        if ((ret != SENSOR_OK) || (tmsg.id == SENSOR_TMSG_INVALID)) {
+            SensorTmsgFree(&tmsg);
+            continue;
+        }
+        (void)VsensorTaskMgrMsgProcess(taskCfg->taskId, &tmsg);
+
+        SensorTmsgFree(&tmsg);
+    }
+    (void)VsensorTaskMgrDeInit(taskCfg->taskId);
+    taskCfg->taskExited = true;
+    HILOG_DEBUG(HILOG_MODULE_SEN, "[task] out");
+}
+
+static void HsensorTaskFunc(void* param)
+{
+    SensorTaskCfg *taskCfg = (SensorTaskCfg *)param;
+    CHECK_NULL_PTR_RETURN(taskCfg);
+    enum SensorTypeTag type = SensorUtilsGetRegisteredType(taskCfg->taskId);
+    CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type);
+    int32_t ret = HsensorDataServiceInit(type);
+    if (ret != SENSOR_OK) {
+        return;
+    }
+    taskCfg->runningFlag = true;
+
+    while (taskCfg->runningFlag) {
+        uint32_t delayTime = HsensorDataServiceProcess(type);
+        osDelay(delayTime);
+    }
+    (void)HsensorDataServiceDeInit(type);
+    taskCfg->taskExited = true;
+}
+
+/* 创建任务接口(异步接口) */
+static int32_t SensorCreateTaskAsync(SensorTaskCfg *taskCfg, enum SensorTypeTag type)
+{
+    /* 创建消息队列 */
+    int32_t ret = SensorMsgQueueCreate(&(taskCfg->msgQueueCfg), (uint32_t)(taskCfg->taskId));
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] msg queue create FAIL! ret:0x%X, taskId:%d", ret, taskCfg->taskId);
+        return SENSOR_MSG_QUEUE_CREATE_FAIL;
+    }
+    SensorUtilsRegisterTaskTable(type, taskCfg->taskId);
+    /* 创建工作线程 */
+    ThreadId *task = SensorThreadCreate((const SensorThreadCfg*)(&(taskCfg->threadCfg)));
+    if (task == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] task create FAIL! task:%d", taskCfg->taskId);
+        SensorUtilsUnRegisterTaskTable(type, taskCfg->taskId);
+        return SENSOR_TASK_CREATE_FAIL;
+    }
+    taskCfg->task = task;
+    taskCfg->taskExited = false;
+
+    HILOG_INFO(HILOG_MODULE_SEN, "[SYS] task:%d prio:%d.", taskCfg->taskId, taskCfg->threadCfg.priority);
+    return SENSOR_OK;
+}
+
+/* 销毁任务接口(同步接口,阻塞等待任务销毁完成) */
+static void SensorTaskDestoryTaskSync(SensorTaskCfg *taskCfg)
+{
+    if (taskCfg->taskExited) {
+        return;
+    }
+
+    taskCfg->runningFlag = false;
+
+    uint16_t taskReadyWait = 0;
+    while ((taskReadyWait < SENSOR_TASK_CREATE_OK_WAIT_TIMEOUT) && (!taskCfg->taskExited)) {
+        osal_msleep(SENSOR_TASK_CREATE_TICK_TIME);
+        taskReadyWait += SENSOR_TASK_CREATE_TICK_TIME;
+    }
+    SensorMsgQueueDelete((uint32_t)(taskCfg->msgQueueCfg.queueId));
+}
+
+static int32_t GetSensorTaskId(SensorTaskCfg *taskCfg)
+{
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    for (int32_t index = 0; index < SENSOR_TASK_MAX_CNT; ++index) {
+        if (!ctx->sensorTaskId[index]) {
+            taskCfg->taskId = index;
+            ctx->sensorTaskId[index] = true;
+            return index;
+        }
+    }
+    return SENSOR_FAILURE;
+}
+
+static SensorTaskCfg *SensorTaskCreateVsensorTaskCfg(const Vsensor *vsensor)
+{
+    SensorTaskCfg *taskCfg = (SensorTaskCfg *)SensorMalloc(sizeof(SensorTaskCfg));
+    CHECK_NULL_PTR_RETURN_VALUE(taskCfg, NULL);
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    OSAL_INIT_LIST_HEAD(&(taskCfg->list));
+    SensorThreadCfg threadCfg = {
+        vsensor->name,
+        VSENSOR_TASK_STACK_SIZE,
+        SENSOR_TASK_PRIORITY_HIGH,
+        VsensorTaskFunc,
+        taskCfg
+    };
+    taskCfg->threadCfg = threadCfg;
+    SensorMsgQueueCfg msgQueueCfg = {
+        vsensor->name,
+        SENSORMGR_TASK_MSG_QUEUE_LENGTH,
+        sizeof(SensorTmsg),
+        0,
+        0
+    };
+    taskCfg->msgQueueCfg = msgQueueCfg;
+    taskCfg->runningFlag = false;
+    taskCfg->task = NULL;
+    taskCfg->taskId = GetSensorTaskId(taskCfg);
+    if (taskCfg->taskId < 0) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "no free taskID!");
+        return NULL;
+    }
+    SensorTaskAddTaskCfg(taskCfg);
+    HILOG_INFO(HILOG_MODULE_SEN, "TaskSync create type:%d name:%s", vsensor->type, threadCfg.name);
+    return taskCfg;
+}
+
+static SensorTaskCfg *SensorTaskCreateHsensorTaskCfg(const Hsensor *hsensor)
+{
+    SensorTaskCfg *taskCfg = (SensorTaskCfg *)SensorMalloc(sizeof(SensorTaskCfg));
+    CHECK_NULL_PTR_RETURN_VALUE(taskCfg, NULL);
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    OSAL_INIT_LIST_HEAD(&(taskCfg->list));
+    SensorThreadCfg threadCfg = {
+        hsensor->name,
+        HSENSOR_TASK_STACK_SIZE,
+        SENSOR_TASK_PRIORITY_HIGH,
+        HsensorTaskFunc,
+        taskCfg
+    };
+    taskCfg->threadCfg = threadCfg;
+    SensorMsgQueueCfg msgQueueCfg = {
+        hsensor->name,
+        SENSORMGR_TASK_MSG_QUEUE_LENGTH,
+        sizeof(SensorTmsg),
+        0,
+        0
+    };
+    taskCfg->msgQueueCfg = msgQueueCfg;
+    taskCfg->runningFlag = false;
+    taskCfg->task = NULL;
+    taskCfg->taskId = GetSensorTaskId(taskCfg);
+    if (taskCfg->taskId < 0) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "no free taskID!");
+        return NULL;
+    }
+    SensorTaskAddTaskCfg(taskCfg);
+    return taskCfg;
+}
+
+/* 创建Vsensor算法任务(同步接口,阻塞等待任务创建完成) */
+int32_t SensorTaskCreateVsensorTask(const Vsensor *vsensor)
+{
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    SensorTaskCfg *taskCfg = SensorTaskCreateVsensorTaskCfg(vsensor);
+    CHECK_NULL_PTR_RETURN_VALUE(taskCfg, SENSOR_ERROR);
+    int32_t ret = SensorCreateTaskAsync(taskCfg, vsensor->type);
+    if (ret != SENSOR_OK) {
+        SensorTaskRemoveTaskCfg(taskCfg);
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] TaskSync create FAIL! ret:0x%X, type:%d", ret, vsensor->type);
+        return SENSOR_TASK_CREATE_FAIL;
+    }
+    SensorUtilsRegisterTaskTable(vsensor->type, taskCfg->taskId);
+    return SENSOR_OK;
+}
+
+/* 销毁vsensor任务 */
+int32_t SensorTaskDestroyVsensorTask(enum SensorTypeTag type)
+{
+    SensorTaskCfg *sensorTask = SensorTaskFindTaskCfg(type);
+    if (sensorTask == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] vsensorTask not found type:%d", type);
+        return SENSOR_ERROR;
+    }
+    SensorTaskDestoryTaskSync(sensorTask);
+    SensorUtilsUnRegisterTaskTable(type, sensorTask->taskId);
+    SensorTaskRemoveTaskCfg(sensorTask);
+    return SENSOR_OK;
+}
+
+int32_t SensorTaskCreateHsensorTask(const Hsensor *hsensor)
+{
+    SensorTaskContext *ctx = SensorTaskGetInstance();
+    SensorTaskCfg *taskCfg = SensorTaskCreateHsensorTaskCfg(hsensor);
+    CHECK_NULL_PTR_RETURN_VALUE(taskCfg, SENSOR_ERROR);
+    int32_t ret = SensorCreateTaskAsync(taskCfg, hsensor->type);
+    if (ret != SENSOR_OK) {
+        SensorTaskRemoveTaskCfg(taskCfg);
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] TaskSync create FAIL! ret:0x%X, type:%d", ret, hsensor->type);
+        return SENSOR_TASK_CREATE_FAIL;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "[SYS] TaskSync create sensorTaskNum:%u, type:%d", ctx->sensorTaskNum, hsensor->type);
+    return SENSOR_OK;
+}
+
+/* 销毁hsensor任务 */
+int32_t SensorTaskDestroyHsensorTask(enum SensorTypeTag type)
+{
+    SensorTaskCfg *sensorTask = SensorTaskFindTaskCfg(type);
+    if (sensorTask == NULL) {
+        HILOG_DEBUG(HILOG_MODULE_SEN, "[SYS] hsensorTask not found type:%d", type);
+        return SENSOR_ERROR;
+    }
+    SensorTaskDestoryTaskSync(sensorTask);
+    SensorUtilsUnRegisterTaskTable(type, sensorTask->taskId);
+    SensorTaskRemoveTaskCfg(sensorTask);
+    return SENSOR_OK;
+}
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/src/sensor_tmsg.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/task/src/sensor_tmsg.c
new file mode 100644 (file)
index 0000000..8427652
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor tmsg impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_tmsg.h"
+#include "sensor_typedef.h"
+#include "sensor_msgqueue.h"
+#include "sensor_task.h"
+#include "securec.h"
+#include "sensor_memory.h"
+#include "sensor_common.h"
+#include "sensor_log.h"
+
+#define FTMSG_WAIT_FOREVER                  0xFFFFFFFF  /* 接收消息永久等待 */
+
+int32_t SensorTmsgSend(uint32_t taskId, SensorTmsg *tmsg)
+{
+    uint32_t tmsgSize = (uint32_t)sizeof(SensorTmsg);
+
+    if (tmsg == NULL) {
+        return SENSOR_SEND_TMSG_NULL;
+    }
+
+    if (SensorTaskGetRunningFlag(taskId) == false) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "taskId :%u NOT RUNNING", taskId);
+        return SENSOR_SEND_TMSG_DEST_NOT_RUNNING;
+    }
+
+    SensorMsgQueueCfg *msgqueueHandle = SensorTaskGetTaskMsgqueueHandle(taskId);
+    if (msgqueueHandle == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "msgqueueHandle null");
+        return SENSOR_SEND_TMSG_MSG_QUEUE_NULL;
+    }
+
+    int32_t ret = SensorMsgQueueWriteCopy(msgqueueHandle->queueId, tmsg, tmsgSize, 0);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "SensorMsgQueueWriteCopy error ret:0x%X\n", ret);
+        return ret;
+    }
+
+    return SENSOR_OK;
+}
+
+int32_t SensorTmsgRecv(uint32_t taskId, SensorTmsg *tmsg)
+{
+    uint32_t tmsgSize = (uint32_t)sizeof(SensorTmsg);
+
+    if (tmsg == NULL) {
+        return SENSOR_RECV_TMSG_NULL;
+    }
+    SensorMsgQueueCfg *msgqueueHandle = SensorTaskGetTaskMsgqueueHandle(taskId);
+    if (msgqueueHandle == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "SensorTmsgRecv msgqueueHandle NULL");
+        return SENSOR_RECV_TMSG_MSG_QUEUE_NULL;
+    }
+    int32_t ret = SensorMsgQueueReadCopy(msgqueueHandle->queueId, tmsg, &tmsgSize, FTMSG_WAIT_FOREVER);
+    if (ret != 0) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "SensorTmsgRecv error ret:0x%X\n", ret);
+        return SENSOR_RECV_TMSG_ERR;
+    }
+    return SENSOR_OK;
+}
+
+int32_t SensorTmsgFree(SensorTmsg *tmsg)
+{
+    if (tmsg == NULL) {
+        return SENSOR_FREE_TMSG_NULL;
+    }
+
+    if (tmsg->info != NULL) {
+        SensorFree(tmsg->info);
+    }
+
+    memset_s(tmsg, sizeof(SensorTmsg), 0, sizeof(SensorTmsg));
+
+    return SENSOR_OK;
+}
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_memory.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_memory.h
new file mode 100644 (file)
index 0000000..9d7367b
--- /dev/null
@@ -0,0 +1,28 @@
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.\r
+ * Description: sensor memory\r
+ * Author: Media Software Group\r
+ * Create: 2025-06-06\r
+ */\r
+\r
+#ifndef SENSOR_MEMORY_H\r
+#define SENSOR_MEMORY_H\r
+\r
+#include <stdlib.h>\r
+\r
+#define MEM_ALLOC_MIN_SIZE     1\r
+#define MEM_ALLOC_MAX_SIZE     10000  // ????10k\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+\r
+void *SensorMalloc(unsigned long size);\r
+void SensorFree(void *addr);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+ \r
+#endif /* SENSOR_MEMORY_H */\r
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_msgqueue.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_msgqueue.h
new file mode 100644 (file)
index 0000000..3a3f6be
--- /dev/null
@@ -0,0 +1,35 @@
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.\r
+ * Description: sensor msgqueue\r
+ * Author: Media Software Group\r
+ * Create: 2025-06-06\r
+ */\r
+\r
+#ifndef SENSOR_MSGQUEUE_H\r
+#define SENSOR_MSGQUEUE_H\r
+\r
+#include <stdint.h>\r
+#include "soc_osal.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+\r
+typedef struct {\r
+    const char *name;\r
+    uint16_t queueLen;\r
+    uint16_t maxMsgSize;\r
+    unsigned long queueId;\r
+    uint32_t flags;\r
+} SensorMsgQueueCfg;\r
+\r
+int32_t SensorMsgQueueCreate(SensorMsgQueueCfg *cfg, uint32_t taskId);\r
+int32_t SensorMsgQueueWriteCopy(unsigned int queueId, void *bufferAddr, unsigned int bufferSize, unsigned int timeout);\r
+int32_t SensorMsgQueueReadCopy(unsigned int queueId, void *bufferAddr, unsigned int *bufferSize, unsigned int timeout);\r
+void SensorMsgQueueDelete(unsigned int queueId);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+#endif /* SENSOR_MSGQUEUE_H */\r
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_para_decision.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_para_decision.h
new file mode 100644 (file)
index 0000000..8d6d2bb
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor para
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+#ifndef SENSOR_PARA_DECISION_H
+#define SENSOR_PARA_DECISION_H
+
+#include "sensor_typedef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define SENSOR_PARA_REALTIME_PERIOD_MIN 1
+#define SENSOR_PARA_REALTIME_PERIOD_MAX 1000000
+#define SENSOR_PARA_BATCH_MIN 1
+#define SENSOR_PARA_BATCH_MAX 100
+
+void SensorParaDefaultInit(SensorPara *sensorPara);
+void SensorParaClear(SensorPara *para);
+void SensorParaCopy(SensorPara *dest, const SensorPara *src);
+int32_t SensorOpenParaDecision(
+    enum SensorTypeTag type, const SensorPara *cur, const SensorPara *require, SensorPara *result);
+int32_t SensorOptionDecision(enum SensorTypeTag type, int32_t cur, int32_t require);
+bool SensorParaIsClear(const SensorPara *para);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SENSOR_PARA_DECISION_H */
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_state.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_state.h
new file mode 100644 (file)
index 0000000..256c8b6
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor state
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_STATE_H
+#define SENSOR_STATE_H
+
+#include "sensor_typedef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void SensorSetState(enum SensorTypeTag type, SensorState state);
+void SensorSetPara(enum SensorTypeTag type, const SensorPara *para);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SENSOR_STATE_H */
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_thread.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_thread.h
new file mode 100644 (file)
index 0000000..178b09f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor thread
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_THREAD_H
+#define SENSOR_THREAD_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <cmsis_os.h>
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif
+
+typedef struct {
+    bool isRecursive;
+} MutexAttr;
+
+typedef void *MutexId;
+
+MutexId SensorMutexCreate(MutexAttr *attr);
+
+void SensorMutexDestroy(MutexId *mutex);
+
+void SensorMutexLock(MutexId mutex);
+
+void SensorMutexUnLock(MutexId mutex);
+
+void SensorMutexGlobalLock(void);
+
+void SensorMutexGlobalUnLock(void);
+
+void SensorInitStaticMutexLock(MutexId *mutex);
+
+typedef void *ThreadId;
+typedef void (*ThreadFunc)(void *argv);
+
+typedef struct {
+    const char *name;    // name of the thread
+    uint32_t stackSize;  // size of stack
+    uint8_t priority;    // initial thread priority
+    ThreadFunc func;
+    void *argv;
+} SensorThreadCfg;
+
+ThreadId SensorThreadCreate(const SensorThreadCfg *cfg);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif
+#endif  // SENSOR_THREAD_H
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_utils.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/include/sensor_utils.h
new file mode 100644 (file)
index 0000000..a0014c4
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor utils
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_HAL_UTILS_H
+#define SENSOR_HAL_UTILS_H
+
+#include "sensor_typedef.h"
+#include "hsensormgr_service.h"
+#include "vsensormgr_service.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define RELY_SENSOR_CNT_MAX 10
+#define SENSOR_MAX_NUM 10       /* 支持的最大的传感器数量 */
+#define VSENSOR_MAX_NUM 10      /* 虚拟传感器的最大数目 */
+
+/* 初始化util模块 */
+void SensorUtilsInit(void);
+Sensor *SensorUtilsFindSensor(enum SensorTypeTag type);
+Sensor *SensorUtilsRequestSensor(enum SensorTypeTag type);
+char *SensorUtilsGetSimpleName(enum SensorTypeTag type);
+HsensorListener *SensorUtilsRequestListener(void);
+void SensorUtilsFreeListener(HsensorListener *listener);
+int32_t SensorUtilsAddHsensorList(HsensorScb *hsensorScb);
+int32_t SensorUtilsAddVsensorList(enum SensorTypeTag type);
+int32_t SensorUtilsHsensorCheck(const Hsensor *hsensor);
+int32_t SensorUtilsVsensorCheck(const Vsensor *vsensor);
+bool SensorUtilsCheckHSensorType(enum SensorTypeTag type);
+void SensorUtilsRegisterVsensorType(enum SensorTypeTag type);
+bool SensorUtilsCheckVSensorType(enum SensorTypeTag type);
+bool SensorUtilsIsVSensor(enum SensorTypeTag type);
+int32_t SensorUtilsUserInfoCheck(SensorPersonInfo *info);
+/* 获取全部sensor */
+int32_t SensorUtilsGetAllSensors(struct SensorInformation **sensorInfo, int32_t *count);
+
+void SensorUtilsRegisterTaskTable(enum SensorTypeTag type, uint32_t taskId);
+void SensorUtilsUnRegisterTaskTable(enum SensorTypeTag type, uint32_t taskId);
+uint32_t SensorUtilsGetRegisteredTaskId(enum SensorTypeTag type);
+enum SensorTypeTag SensorUtilsGetRegisteredType(uint32_t taskId);
+/* 判断sensor有没有被注册 */
+bool SensorUtilsSensorIsRegistered(enum SensorTypeTag type);
+uint64_t SensorUtilsGetRtcTimeMs(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_log.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_log.c
new file mode 100644 (file)
index 0000000..5d44175
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor log
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_log.h"
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include "sensor_type.h"
+#ifdef SUPPORT_AT_UART_PRINT
+#include "app_at_uart.h"
+#endif
+
+#ifdef ENABLE_INFO_LEVEL_LOG
+static SENSOR_LOG_LEVEL g_enabledLevel = SENSOR_LOG_DEBUG;
+#else
+static SENSOR_LOG_LEVEL g_enabledLevel = SENSOR_LOG_ERR;
+#endif
+
+#define MAX_BUFFER_SZ 256
+
+static void LogTime(void)
+{
+    struct timeval tv = {0};
+    gettimeofday(&tv, NULL);
+    struct tm tm = {};
+    localtime_r(&tv.tv_sec, &tm);
+    const int64_t usecToMsec = 1000;
+    printf("[%02d:%02d:%02d:%03lld]", tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec / usecToMsec);
+}
+
+int32_t SensorLogPrintf(SENSOR_LOG_LEVEL level, const char *fmt, ...)
+{
+    if (level < g_enabledLevel) {
+        return SENSOR_SUCCESS;
+    }
+    if (fmt == NULL) {
+        return SENSOR_INVALID_PARAM;
+    }
+    const char *levelStr = NULL;
+    char out[MAX_BUFFER_SZ] = {0};
+    switch (level) {
+        case SENSOR_LOG_DEBUG:
+            levelStr = "D";
+            break;
+        case SENSOR_LOG_INFO:
+            levelStr = "I";
+            break;
+        case SENSOR_LOG_WARN:
+            levelStr = "W";
+            break;
+        case SENSOR_LOG_ERR:
+            levelStr = "E";
+            break;
+        default:
+            levelStr = "E";
+            break;
+    }
+    LogTime();
+    va_list args;
+#ifdef SUPPORT_AT_UART_PRINT
+    at_uart_printf("[%s]", levelStr);
+#else
+    printf("[%s]", levelStr);
+#endif
+    va_start(args, fmt);
+    int result = vsnprintf_s(out, MAX_BUFFER_SZ, MAX_BUFFER_SZ - 1, fmt, args);
+    if (result == -1) {
+        printf("vsnprintf_s failed!\n");
+        va_end(args);
+        return SENSOR_INVALID_PARAM;
+    }
+    va_end(args);
+#ifdef SUPPORT_AT_UART_PRINT
+    at_uart_printf("%s \n", out);
+#else
+    printf("%s \n", out);
+#endif
+    return SENSOR_SUCCESS;
+}
+
+int32_t SetSensorLogEnabledLevel(SENSOR_LOG_LEVEL level)
+{
+    if (level < SENSOR_LOG_DEBUG ||
+        level > SENSOR_LOG_ERR) {
+        return SENSOR_INVALID_PARAM;
+    }
+    g_enabledLevel = level;
+    return SENSOR_SUCCESS;
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_memory.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_memory.c
new file mode 100644 (file)
index 0000000..84cd8c4
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.\r
+ * Description: Sensor Malloc impl\r
+ * Create: 2025-6-6\r
+ */\r
+\r
+#include "sensor_memory.h"\r
+#include "sensor_log.h"\r
+\r
+void *SensorMalloc(unsigned long size)\r
+{\r
+    return malloc(size);\r
+}\r
+\r
+void SensorFree(void *addr)\r
+{\r
+    free(addr);\r
+}\r
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_msgqueue.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_msgqueue.c
new file mode 100644 (file)
index 0000000..76c4302
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.\r
+ * Description: sensor msgqueue impl\r
+ * Author: Media Software Group\r
+ * Create: 2025-06-06\r
+ */\r
+\r
+#include "sensor_msgqueue.h"\r
+#include "sensor_log.h"\r
+\r
+int32_t SensorMsgQueueCreate(SensorMsgQueueCfg* cfg, uint32_t taskId)\r
+{\r
+    if (cfg == NULL) {\r
+        return 0;\r
+    }\r
+    HILOG_INFO(HILOG_MODULE_SEN, "task:%u create msgqueue.\n", taskId);\r
+    return osal_msg_queue_create(cfg->name, cfg->queueLen, &(cfg->queueId), cfg->flags, cfg->maxMsgSize);\r
+}\r
+\r
+int32_t SensorMsgQueueWriteCopy(unsigned int queueId, void *bufferAddr, unsigned int bufferSize, unsigned int timeout)\r
+{\r
+    return osal_msg_queue_write_copy(queueId, bufferAddr, bufferSize, timeout);\r
+}\r
+\r
+int32_t SensorMsgQueueReadCopy(unsigned int queueId, void *bufferAddr, unsigned int *bufferSize, unsigned int timeout)\r
+{\r
+    return osal_msg_queue_read_copy(queueId, bufferAddr, bufferSize, timeout);\r
+}\r
+\r
+void SensorMsgQueueDelete(unsigned int queueId)\r
+{\r
+    osal_msg_queue_delete(queueId);\r
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_para_decision.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_para_decision.c
new file mode 100644 (file)
index 0000000..bee6085
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor para impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+
+#include "sensor_para_decision.h"
+#include "sensor_log.h"
+#include "sensor_utils.h"
+#include "sensor_common.h"
+
+#define OPTION_DEFAULT_VAL 0 /* OPTION初始值 0 */
+#define DEFAULT_REALTIME_PERIOD (SENSOR_PARA_REALTIME_PERIOD_MIN * 1000)
+
+void SensorParaDefaultInit(SensorPara *sensorPara)
+{
+    sensorPara->period = DEFAULT_REALTIME_PERIOD;
+    sensorPara->batch = SENSOR_PARA_BATCH_MIN;
+    sensorPara->mode = SENSOR_MODE_REALTIME; /* fifo mode OR realtime mode */
+    sensorPara->option = 0;
+}
+
+
+void SensorParaClear(SensorPara *para)
+{
+    if (para == NULL) {
+        return;
+    }
+
+    para->period = 0;
+    para->batch = 0;
+    para->mode = SENSOR_MODE_MAX;
+    para->option = OPTION_DEFAULT_VAL;
+}
+
+void SensorParaCopy(SensorPara *dest, const SensorPara *src)
+{
+    if (dest == NULL || src == NULL) {
+        return;
+    }
+
+    dest->period = src->period;
+    dest->batch = src->batch;
+    dest->mode = src->mode;
+    dest->option = src->option;
+}
+
+bool SensorParaIsClear(const SensorPara *para)
+{
+    if (para == NULL) {
+        return true;
+    }
+
+    if (para->period == 0) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+int32_t SensorOptionDecision(enum SensorTypeTag type, int32_t cur, int32_t require)
+{
+    return OPTION_DEFAULT_VAL;
+}
+
+int32_t SensorOpenParaDecision(
+    enum SensorTypeTag type, const SensorPara *cur, const SensorPara *require, SensorPara *result)
+{
+    if (cur == NULL || require == NULL || result == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d para null", type);
+        return SENSOR_SENSOR_DECISION_PARA_NULL;
+    }
+
+    if (SensorParaIsClear(cur)) {
+        SensorParaCopy(result, require);
+        return SENSOR_OK;
+    }
+
+    result->period = SENSOR_MIN(cur->period, require->period);
+    if (result->period == 0) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type %d period == 0", type);
+        return SENSOR_ERROR;
+    }
+    result->batch = SENSOR_MIN(cur->batch * cur->period, require->batch * require->period) / result->period;
+    result->mode = SENSOR_MIN(cur->mode, require->mode);
+    result->option = SensorOptionDecision(type, cur->option, require->option);
+
+    return SENSOR_OK;
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_state.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_state.c
new file mode 100644 (file)
index 0000000..dc1a5b7
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor state impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_state.h"
+#include "sensor_log.h"
+#include "sensor_utils.h"
+#include "sensor_common.h"
+
+void SensorSetState(enum SensorTypeTag type, SensorState state)
+{
+    Sensor *sensor = NULL;
+
+    sensor = SensorUtilsFindSensor(type);
+    if (sensor == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[STATE] cannot get sensor:%d, sensor may be not registered\n", type);
+        return;
+    }
+
+    sensor->sensorInfo.state = state;
+}
+
+void SensorSetPara(enum SensorTypeTag type, const SensorPara *para)
+{
+    Sensor *sensor = NULL;
+    sensor = SensorUtilsFindSensor(type);
+    if (sensor == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[STATE] cannot get sensor:%d, sensor may be not registered\n", type);
+        return;
+    }
+
+    if (para == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[ATASK] sensor open para NULL!");
+        return;
+    }
+    sensor->sensorInfo.openPara.period = para->period;
+    sensor->sensorInfo.openPara.batch = para->batch;
+    sensor->sensorInfo.openPara.mode = para->mode;
+    sensor->sensorInfo.openPara.option = para->option;
+
+    HILOG_INFO(HILOG_MODULE_SEN,
+        "[UTIL][storge msg] period:%d batch:%d mode:%d option:%d\n",
+        sensor->sensorInfo.openPara.period,
+        sensor->sensorInfo.openPara.batch,
+        sensor->sensorInfo.openPara.mode,
+        sensor->sensorInfo.openPara.option);
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_thread.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_thread.c
new file mode 100644 (file)
index 0000000..8030c17
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor thread impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_thread.h"
+#include <unistd.h>
+#include <sys/time.h>
+#include "securec.h"
+
+#ifndef CMSIS_SUPPORT
+pthread_mutex_t g_globalMutexLock = PTHREAD_MUTEX_INITIALIZER;
+static void *ThreadMallocZ(uint32_t len)
+{
+    if (len == 0) {
+        return NULL;
+    }
+
+    void *value = malloc(len);
+    if (value ==  NULL) {
+        return  NULL;
+    }
+
+    if (memset_s(value, len, 0, len) != EOK) {
+        free(value);
+        value =  NULL;
+    }
+
+    return value;
+}
+#endif
+
+MutexId SensorMutexCreate(MutexAttr *attr)
+{
+#ifdef CMSIS_SUPPORT
+    osMutexAttr_t mutexAttr = {  NULL, 0,  NULL, 0 };
+    osMutexAttr_t *pAttr =  NULL;
+    if (attr !=  NULL && attr->isRecursive) {
+        mutexAttr.attr_bits |= osMutexRecursive;
+        pAttr = &mutexAttr;
+    }
+    osMutexId_t mutex = osMutexNew(pAttr);
+    return mutex;
+#else
+    pthread_mutex_t *mutexId = (pthread_mutex_t *)ThreadMallocZ(sizeof(pthread_mutex_t));
+    if (mutexId ==  NULL) {
+        return  NULL;
+    }
+    pthread_mutexattr_t mutexAttr = {0};
+    pthread_mutexattr_t *pAttr =  NULL;
+    bool needSetAttr = (attr !=  NULL && attr->isRecursive && pthread_mutexattr_init(&mutexAttr) == 0);
+    if (needSetAttr) {
+        if (pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE) == 0) {
+            pAttr = &mutexAttr;
+        }
+    }
+    (void)pthread_mutex_init(mutexId, pAttr);
+    if (needSetAttr) {
+        pthread_mutexattr_destroy(&mutexAttr);
+    }
+    return mutexId;
+#endif
+}
+
+void SensorMutexDestroy(MutexId *mutex)
+{
+    if (mutex ==  NULL || *mutex ==  NULL) {
+        return;
+    }
+#ifdef CMSIS_SUPPORT
+    (void)osMutexDelete(*mutex);
+#else
+    if (*mutex ==  NULL) {
+        return;
+    }
+
+    (void)pthread_mutex_destroy((pthread_mutex_t *)*mutex);
+    free(*mutex);
+#endif
+    *mutex =  NULL;
+}
+
+void SensorMutexLock(MutexId mutex)
+{
+    if (mutex ==  NULL) {
+        return;
+    }
+
+#ifdef CMSIS_SUPPORT
+    (void)osMutexAcquire(mutex, osWaitForever);
+#else
+    (void)pthread_mutex_lock((pthread_mutex_t *)mutex);
+#endif
+}
+
+void SensorMutexUnLock(MutexId mutex)
+{
+    if (mutex ==  NULL) {
+        return;
+    }
+
+#ifdef CMSIS_SUPPORT
+    (void)osMutexRelease(mutex);
+#else
+    (void)pthread_mutex_unlock((pthread_mutex_t *)mutex);
+#endif
+}
+
+void SensorMutexGlobalLock(void)
+{
+#ifdef CMSIS_SUPPORT
+    osKernelLock();
+#else
+    pthread_mutex_lock(&g_globalMutexLock);
+#endif
+}
+
+void SensorMutexGlobalUnLock(void)
+{
+#ifdef CMSIS_SUPPORT
+    osKernelUnlock();
+#else
+    pthread_mutex_unlock(&g_globalMutexLock);
+#endif
+}
+
+void SensorInitStaticMutexLock(MutexId *mutex)
+{
+    if (mutex ==  NULL || *mutex !=  NULL) {
+        return;
+    }
+
+    SensorMutexGlobalLock();
+    if (*mutex == NULL) {
+        MutexAttr attr = { false };
+        *mutex = SensorMutexCreate(&attr);
+    }
+    SensorMutexGlobalUnLock();
+}
+
+ThreadId SensorThreadCreate(const SensorThreadCfg *cfg)
+{
+    osThreadAttr_t taskAttr = {cfg->name, 0, NULL, 0, NULL, cfg->stackSize, (osPriority_t)(cfg->priority), 0, 0};
+    return (ThreadId)osThreadNew((osThreadFunc_t)cfg->func, cfg->argv, &taskAttr);
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_utils.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/utils/src/sensor_utils.c
new file mode 100644 (file)
index 0000000..54c4b42
--- /dev/null
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: sensor utils impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_utils.h"
+#include <sys/time.h>
+#include "sensor_log.h"
+#include "sensor_task.h"
+#include "sensor_memory.h"
+#include "sensor_common.h"
+
+#define MS_TO_US 1000
+
+typedef struct {
+    enum SensorTypeTag type;
+    const char* simpleName;
+} SensorSimpleNameInfo;
+
+typedef struct {
+    enum SensorTypeTag type;
+    uint32_t taskId;
+} SensorTaskTable;
+
+static SensorTaskTable g_registeredSensorTaskTable[SENSOR_MAX_NUM] = {0};
+
+static struct SensorInformation g_sensorList[SENSOR_MAX_NUM] = {0};
+static Sensor g_sensorPool[SENSOR_MAX_NUM] = {0};
+static enum SensorTypeTag g_registeredVSensorTable[VSENSOR_MAX_NUM] = {0};
+
+const SensorSimpleNameInfo g_sensorSimpleNameInfoDefines[] = {
+    {SENSOR_TYPE_NONE, "none"},
+    {SENSOR_TYPE_ACCELEROMETER, "acc"},
+    {SENSOR_TYPE_GYROSCOPE, "gyro"},
+    {SENSOR_TYPE_PHOTOPLETHYSMOGRAPH, "ppg"},
+    {SENSOR_TYPE_ELECTROCARDIOGRAPH, "ecg"},
+    {SENSOR_TYPE_AMBIENT_LIGHT, "amblitght"},
+    {SENSOR_TYPE_MAGNETIC_FIELD, "magn"},
+    {SENSOR_TYPE_CAPACITIVE, "cap"},
+    {SENSOR_TYPE_BAROMETER, "bar"},
+    {SENSOR_TYPE_TEMPERATURE, "temp"},
+    {SENSOR_TYPE_HALL, "hall"},
+    {SENSOR_TYPE_GESTURE, "gest"},
+    {SENSOR_TYPE_PROXIMITY, "prox"},
+    {SENSOR_TYPE_HUMIDITY, "humi"},
+    {SENSOR_TYPE_PHYSICAL_MAX, "phymax"},
+    {SENSOR_TYPE_ORIENTATION, "ori"},
+    {SENSOR_TYPE_GRAVITY, "grav"},
+    {SENSOR_TYPE_LINEAR_ACCELERATION, "lacc"},
+    {SENSOR_TYPE_ROTATION_VECTOR, "rvec"},
+    {SENSOR_TYPE_AMBIENT_TEMPERATURE, "atemp"},
+    {SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, "magnu"},
+    {SENSOR_TYPE_GAME_ROTATION_VECTOR, "grvec"},
+    {SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, "gyrou"},
+    {SENSOR_TYPE_SIGNIFICANT_MOTION, "smo"},
+    {SENSOR_TYPE_PEDOMETER_DETECTION, "pedde"},
+    {SENSOR_TYPE_PEDOMETER, "ped"},
+    {SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR, "grvec"},
+    {SENSOR_TYPE_HEART_RATE, "hr"},
+    {SENSOR_TYPE_DEVICE_ORIENTATION, "devor"},
+    {SENSOR_TYPE_WEAR_DETECTION, "wd"},
+    {SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED, "accu"},
+    {SENSOR_TYPE_VSENSOR_ACCELEROMETER_ALG_SIMU, "accalgsimu"},
+ 
+    {SENSOR_TYPE_MAX, "max"}
+};
+
+void SensorUtilsInit(void)
+{
+}
+
+char *SensorUtilsGetSimpleName(enum SensorTypeTag type)
+{
+    char* ret = NULL;
+    for (uint32_t i = 0; i < (sizeof(g_sensorSimpleNameInfoDefines) / sizeof(SensorSimpleNameInfo)); i++) {
+        if (g_sensorSimpleNameInfoDefines[i].type == type) {
+            ret = (char*)(g_sensorSimpleNameInfoDefines[i].simpleName);
+            break;
+        }
+    }
+    return ret;
+}
+
+Sensor *SensorUtilsFindSensor(enum SensorTypeTag type)
+{
+    CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, NULL);
+
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        Sensor *sensor = &(g_sensorPool[i]);
+        if (type == sensor->sensorInfo.type) {
+            return sensor;
+        }
+    }
+
+    return NULL;
+}
+
+Sensor *SensorUtilsRequestSensor(enum SensorTypeTag type)
+{
+    Sensor *sensor = SensorUtilsFindSensor(type);
+    if (sensor != NULL) {
+        /* sensor已存在,不允许重复注册 */
+        HILOG_ERROR(HILOG_MODULE_SEN, "[util] find sensor:%d exit!", sensor->sensorInfo.type);
+        return NULL;
+    }
+
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        sensor = &(g_sensorPool[i]);
+        if (sensor->sensorInfo.type == SENSOR_TYPE_NONE) {
+            return sensor;
+        }
+    }
+    HILOG_WARN(HILOG_MODULE_SEN, "[util] find sensor:%d Exceed max!", sensor->sensorInfo.type);
+    return NULL;
+}
+
+/* 获取全部sensor */
+int32_t SensorUtilsGetAllSensors(struct SensorInformation **sensorInfo, int32_t *count)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "in!");
+    if (sensorInfo == NULL || count == NULL) {
+        return SENSOR_ENTRY_PARA_ERROR;
+    }
+    *count = 0;
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        HILOG_DEBUG(HILOG_MODULE_SEN, "index:%d sensorID:%d sensorTypeId:%d", i, g_sensorList[i].sensorId, g_sensorList[i].sensorTypeId);
+        if (g_sensorList[i].sensorTypeId == (int32_t)SENSOR_TYPE_NONE) {
+            break;
+        }
+        (*count)++;
+    }
+    *sensorInfo = g_sensorList;
+    HILOG_DEBUG(HILOG_MODULE_SEN, "find sensorlist:%d! list addr:%x", *count, g_sensorList);
+    return SENSOR_OK;
+}
+
+static struct SensorInformation *SensorUtilsFindSensorsList(enum SensorTypeTag type)
+{
+    CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, NULL);
+
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        struct SensorInformation *sensorList = &(g_sensorList[i]);
+        if (type == (enum SensorTypeTag)sensorList->sensorTypeId) {
+            return sensorList;
+        }
+    }
+
+    return NULL;
+}
+
+static struct SensorInformation *SensorUtilsRequestSensorList(enum SensorTypeTag type)
+{
+    struct SensorInformation *sensorList = SensorUtilsFindSensorsList(type);
+    if (sensorList != NULL) {
+        /* sensor已存在,不允许重复注册 */
+        HILOG_ERROR(HILOG_MODULE_SEN, "[util] find sensorlist:%d exit!", sensorList->sensorTypeId);
+        return NULL;
+    }
+
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        sensorList = &(g_sensorList[i]);
+        if (sensorList->sensorTypeId == (int32_t)SENSOR_TYPE_NONE) {
+            return sensorList;
+        }
+    }
+    return NULL;
+}
+
+int32_t SensorUtilsAddHsensorList(HsensorScb *hsensorScb)
+{
+    struct SensorInformation *sensorList = SensorUtilsRequestSensorList(hsensorScb->type);
+    if (sensorList == NULL) {
+        return SENSOR_ERROR;
+    }
+
+    sensorList->sensorTypeId = hsensorScb->type;
+    // sensorList->sensorName = hsensorScb->hsensor->name;
+    return SENSOR_OK;
+}
+
+int32_t SensorUtilsAddVsensorList(enum SensorTypeTag type)
+{
+    struct SensorInformation *sensorList = SensorUtilsRequestSensorList(type);
+    if (sensorList == NULL) {
+        return SENSOR_ERROR;
+    }
+
+    sensorList->sensorTypeId = type;
+    return SENSOR_OK;
+}
+
+HsensorListener *SensorUtilsRequestListener(void)
+{
+    return (HsensorListener *)SensorMalloc(sizeof(HsensorListener));
+}
+
+void SensorUtilsFreeListener(HsensorListener *listener)
+{
+    if (listener) {
+        SensorFree(listener);
+    }
+}
+
+/* 用户信息有效性检查 */
+int32_t SensorUtilsUserInfoCheck(SensorPersonInfo *info)
+{
+    /* 参数检查 */
+    if ((info->weight > MAX_USER_WEIGHT) || (info->weight < MIN_USER_WEIGHT)) {
+        HILOG_INFO(HILOG_MODULE_SEN, "user weight out range!");
+        info->weight = DEFAULT_USER_WEIGHT;
+    }
+
+    if ((info->height > MAX_USER_HEIGHT) || (info->height < MIN_USER_HEIGHT)) {
+        HILOG_INFO(HILOG_MODULE_SEN, "user height out range!");
+        info->height = DEFAULT_USER_HEIGHT;
+    }
+
+    if ((info->age > MAX_USER_AGE) || (info->age == 0)) {
+        HILOG_INFO(HILOG_MODULE_SEN, "user age out range!");
+        info->age = DEFAULT_USER_AGE;
+    }
+
+    if (info->gender > ALG_USER_SEX_UNKNOWN) {
+        HILOG_INFO(HILOG_MODULE_SEN, "user gender out range!");
+        info->gender = ALG_USER_SEX_MAN;
+    }
+
+    return SENSOR_OK;
+}
+
+static int32_t SensorUtilsVsensorRelyCheck(const RelySensorsInfo *relySensors)
+{
+    if (relySensors->relySensorCnt == 0) {
+        return SENSOR_ENTRY_VSENSOR_RELY_NULL;
+    }
+    return SENSOR_OK;
+}
+
+bool SensorUtilsCheckHSensorType(enum SensorTypeTag type)
+{
+    if ((type == SENSOR_TYPE_NONE) || (type >= SENSOR_TYPE_VSENSOR_EXPAND_START)) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type :%d illegal", type);
+        return false;
+    }
+    return true;
+}
+
+bool SensorUtilsCheckVSensorType(enum SensorTypeTag type)
+{
+    if ((type <= SENSOR_TYPE_VSENSOR_EXPAND_START) || (type >= SENSOR_TYPE_MAX)) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "type :%d illegal", type);
+        return false;
+    }
+    return true;
+}
+
+void SensorUtilsRegisterVsensorType(enum SensorTypeTag type)
+{
+    CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type);
+
+    for (uint8_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+        if (type == g_registeredVSensorTable[i]) {
+            return;
+        }
+        if (g_registeredVSensorTable[i] == SENSOR_TYPE_NONE) {
+            g_registeredVSensorTable[i] = type;
+            return;
+        }
+    }
+}
+
+bool SensorUtilsIsVSensor(enum SensorTypeTag type)
+{
+    for (uint8_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+        if (type == g_registeredVSensorTable[i]) {
+            return true;
+        }
+    }
+    return false;
+}
+
+int32_t SensorUtilsHsensorCheck(const Hsensor *hsensor)
+{
+    CHECK_NULL_PTR_RETURN_VALUE(hsensor, SENSOR_ENTRY_HSENSOR_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(hsensor->name, SENSOR_ENTRY_HSENSOR_NAME_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(hsensor->init, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(hsensor->deinit, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(hsensor->close, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(hsensor->read, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(hsensor->ioctl, SENSOR_ENTRY_HSENSOR_FUNC_NULL);
+    if (hsensor->caps.maxBatchCount == 0 || hsensor->caps.sampleElementlen == 0) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "maxBatchCount :%u sampleElementlen :%u illegal",
+            hsensor->caps.maxBatchCount, hsensor->caps.sampleElementlen);
+        return SENSOR_HSENSOR_PERIOD_BATCH_ERR;
+    }
+
+    if (!SensorUtilsCheckHSensorType(hsensor->type)) {
+        return SENSOR_ENTRY_SENSOR_TYPE_ILLEGAL;
+    }
+
+    return SENSOR_OK;
+}
+
+int32_t SensorUtilsVsensorCheck(const Vsensor *vsensor)
+{
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ENTRY_VSENSOR_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor->name, SENSOR_ENTRY_VSENSOR_NAME_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor->relySensors, SENSOR_ENTRY_VSENSOR_RELY_NULL);
+
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor->registDataCb, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor->unRegistDataCb, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor->open, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor->close, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor->process, SENSOR_ENTRY_VSENSOR_FUNC_NULL);
+
+    if (!SensorUtilsCheckVSensorType(vsensor->type)) {
+        return SENSOR_ENTRY_SENSOR_TYPE_ILLEGAL;
+    }
+
+    int32_t ret = SensorUtilsVsensorRelyCheck(vsensor->relySensors);
+    if (ret != SENSOR_OK) {
+        return ret;
+    }
+
+    return SENSOR_OK;
+}
+
+void SensorUtilsRegisterTaskTable(enum SensorTypeTag type, uint32_t taskId)
+{
+    CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type);
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        if (type == g_registeredSensorTaskTable[i].type) {
+            g_registeredSensorTaskTable[i].taskId = taskId;
+            return;
+        }
+    }
+
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        if (g_registeredSensorTaskTable[i].type == SENSOR_TYPE_NONE) {
+            g_registeredSensorTaskTable[i].type = type;
+            g_registeredSensorTaskTable[i].taskId = taskId;
+            return;
+        }
+    }
+}
+
+void SensorUtilsUnRegisterTaskTable(enum SensorTypeTag type, uint32_t taskId)
+{
+    CHECK_SENSOR_TYPE_ILLEGAL_RETURN(type);
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        if (type == g_registeredSensorTaskTable[i].type && taskId == g_registeredSensorTaskTable[i].taskId) {
+            g_registeredSensorTaskTable[i].taskId = 0;
+            g_registeredSensorTaskTable[i].type = SENSOR_TYPE_NONE;
+            return;
+        }
+    }
+}
+
+uint32_t SensorUtilsGetRegisteredTaskId(enum SensorTypeTag type)
+{
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        if (type == g_registeredSensorTaskTable[i].type) {
+            return g_registeredSensorTaskTable[i].taskId;
+        }
+    }
+    return SENSOR_FAILURE;
+}
+
+enum SensorTypeTag SensorUtilsGetRegisteredType(uint32_t taskId)
+{
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        if (taskId == g_registeredSensorTaskTable[i].taskId) {
+            return g_registeredSensorTaskTable[i].type;
+        }
+    }
+    return SENSOR_TYPE_MAX;
+}
+
+bool SensorUtilsSensorIsRegistered(enum SensorTypeTag type)
+{
+    for (uint32_t i = 0; i < SENSOR_MAX_NUM; i++) {
+        Sensor *sensor = &(g_sensorPool[i]);
+        if (sensor->sensorInfo.type == type) {
+            return true;
+        }
+    }
+    return false;
+}
+
+uint64_t SensorUtilsGetRtcTimeMs(void)
+{
+    struct timeval tv;
+    (void)gettimeofday(&tv, NULL);
+    return (tv.tv_sec * MS_TO_US + tv.tv_usec / MS_TO_US);
+}
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/include/vsensor_task_mgr.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/include/vsensor_task_mgr.h
new file mode 100644 (file)
index 0000000..f44c6bb
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task mgr
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef VENSOR_TASK_MGR_H
+#define VENSOR_TASK_MGR_H
+
+#include <stdbool.h>
+#include "sensor_typedef.h"
+#include "sensor_tmsg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t VsensorTaskMgrInit(uint32_t taskId);
+void VsensorTaskMgrDeInit(uint32_t taskId);
+int32_t VsensorTaskMgrMsgProcess(uint32_t taskId, const SensorTmsg *tmsg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/include/vsensormgr_service.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/include/vsensormgr_service.h
new file mode 100644 (file)
index 0000000..844649d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task mgr service
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef VSENSOR_MGR_SEVICE_H
+#define VSENSOR_MGR_SEVICE_H
+
+#include "sensor_typedef.h"
+#include "soc_osal.h"
+#include "hsensormgr_service.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t VsensorMgrInit(void);
+int32_t VsensorMgrRegister(const Vsensor *vsensor);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/include/vsensor_task_class.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/include/vsensor_task_class.h
new file mode 100644 (file)
index 0000000..07f59c0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task class
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef VSENSOR_TASK_CLASS_H
+#define VSENSOR_TASK_CLASS_H
+
+#include "vsensor_task_comm.h"
+
+typedef struct {
+    VsensorTaskComm component;
+    SensorTmsgProcMap *tmsgProcMap;
+    uint16_t tmsgProcMapLen;
+} VsensorTaskClass;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* aclass对象创建 */
+VsensorTaskClass *VsensorTaskClassInit(uint32_t taskId, const char *taskPrefix, NotifyCallback hdataCb,
+    const SensorTmsgProcMap *tmsgProcMap, uint16_t tmsgProcMapLen);
+
+/* aclass对象销毁 */
+void VsensorTaskClassDestruct(VsensorTaskClass *vSensorClass);
+
+/* 通过 taskid 查找 aclass 对象 */
+VsensorTaskClass *VsensorTaskClassGetByTaskid(uint32_t taskId);
+
+/* aclass类公用的消息处理函数 */
+int32_t VsensorTaskClassMsgProcess(VsensorTaskClass *vSensorClass, const SensorTmsg *tmsg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/include/vsensor_task_comm.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/include/vsensor_task_comm.h
new file mode 100644 (file)
index 0000000..8d22ca3
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task common
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef SENSOR_TASK_COMM_H
+#define SENSOR_TASK_COMM_H
+
+#include <stdbool.h>
+#include "sensor_typedef.h"
+#include "hsensormgr_service.h"
+#include "sensor_task.h"
+#include "sensor_tmsg.h"
+#include "sensor_utils.h"
+
+#define VSENSOR_TASK_HLISTENER_MAX_NUM 10    /* FA算法线程支持的物理传感器listener的最大数量设置 */
+#define FA_VSENSOR_BE_RELYED_NUM 10      /* 虚拟sensor被依赖的任务最大个数 */
+#define VSENSOR_RESULT_TS_OFFSET 1000 /* 虚拟传感器上报的时间戳与获取的时间戳的矫正间隔值 */
+
+enum {
+    APP_CTRL = 0,
+    RELY_CTRL,
+};
+
+typedef struct {
+    bool appOpenFlag;
+    uint32_t relyedCnt; /* 被其他算法依赖的次数 */
+} VsensorTaskRelyedInfo;
+
+typedef struct {
+    enum SensorTypeTag type;
+    SensorState state;
+    Vsensor *vsensor;
+    VsensorTaskRelyedInfo relyedInfo;
+} VsensorTaskInfo;
+
+typedef struct {
+    enum SensorTypeTag type;
+    HsensorListener hlistener;
+} VsensorTaskHlistener;
+
+typedef struct {
+    enum SensorTypeTag sensor;
+    uint32_t dataLen;
+    uint64_t timestamp;
+    uint8_t sensordata[];
+} VsensorProcessData;
+
+typedef struct {
+    uint32_t taskId;
+    char *taskPrefix;
+    NotifyCallback hdataCb; /* hlistener中的数据回调函数,若为NULL,将直接使用atask类默认的数据回调函数 */
+    VsensorTaskHlistener hlistenersList[VSENSOR_TASK_HLISTENER_MAX_NUM];
+    VsensorTaskInfo vsensorInfo[VSENSOR_MAX_NUM];
+} VsensorTaskComm;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int32_t VsensorTaskCheckCommComponents(const VsensorTaskComm *component);
+bool VsensorTaskVsensorIsRunning(const VsensorTaskInfo *vsensorInfo);
+void VsensorTaskCommInit(VsensorTaskComm *component);
+int32_t VsensorTaskVsensorRegEvent(VsensorTaskComm *component, Vsensor *vsensor);
+int32_t VsensorTaskSensorDataUpdateEvent(VsensorTaskComm *component, VsensorProcessData *data);
+
+int32_t VsensorTaskVsensorOpenEvent(
+    VsensorTaskComm *component, enum SensorTypeTag type, SensorPara *para, uint32_t openType);
+int32_t VsensorTaskVsensorCloseEvent(VsensorTaskComm *component, enum SensorTypeTag type, uint32_t closeType);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* VSENSOR_TASK_COMM_H */
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_class.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_class.c
new file mode 100644 (file)
index 0000000..975530f
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task class impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "vsensor_task_class.h"
+#include "securec.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "sensor_utils.h"
+#include "sensor_memory.h"
+#include "sensor_tmsg.h"
+
+/* 存储 taskid 和 aclass 对象的对应表 */
+static VsensorTaskClass *g_vsensorTaskObjArray[SENSOR_TASK_MAX_CNT] = {NULL};
+
+/* aclass对象创建 */
+VsensorTaskClass *VsensorTaskClassInit(uint32_t taskId, const char *taskPrefix, NotifyCallback hdataCb,
+    const SensorTmsgProcMap *tmsgProcMap, uint16_t tmsgProcMapLen)
+{
+    if (taskPrefix == NULL) {
+        return NULL;
+    }
+
+    VsensorTaskClass *vsensorTaskObj = (VsensorTaskClass *)SensorMalloc(sizeof(VsensorTaskClass));
+    if (vsensorTaskObj == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "aclass:%d malloc fail!\n", taskId);
+        return NULL;
+    }
+
+    memset_s(vsensorTaskObj, sizeof(VsensorTaskClass), 0, sizeof(VsensorTaskClass));
+
+    vsensorTaskObj->component.taskId = taskId;
+    vsensorTaskObj->component.taskPrefix = (char *)taskPrefix;
+    vsensorTaskObj->component.hdataCb = hdataCb;
+    vsensorTaskObj->tmsgProcMap = (SensorTmsgProcMap *)tmsgProcMap;
+    vsensorTaskObj->tmsgProcMapLen = tmsgProcMapLen;
+    VsensorTaskCommInit(&(vsensorTaskObj->component));
+    g_vsensorTaskObjArray[taskId] = vsensorTaskObj;
+
+    return vsensorTaskObj;
+}
+
+/* aclass对象销毁 */
+void VsensorTaskClassDestruct(VsensorTaskClass *vSensorClass)
+{
+    if (vSensorClass == NULL) {
+        return;
+    }
+    g_vsensorTaskObjArray[vSensorClass->component.taskId] = NULL;
+    SensorFree(vSensorClass);
+}
+
+/* 通过 taskid 查找 aclass 对象 */
+VsensorTaskClass *VsensorTaskClassGetByTaskid(uint32_t taskId)
+{
+    if (taskId < SENSOR_TASK_MAX_CNT) {
+        return g_vsensorTaskObjArray[taskId];
+    } else {
+        return NULL;
+    }
+}
+
+/* aclass类公用的消息处理函数,当aclass对象没有指定消息处理函数时,会使用此函数的消息处理流程 */
+static int32_t VsensorTaskGenericMsgProcess(VsensorTaskComm *component, const SensorTmsg *tmsg)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "msg:%d task:%d proc", tmsg->id, component->taskId);
+    /* 无需多重校验入参指针,在函数上下文中,已经判断了,提升代码运行效率 */
+    int32_t ret = SENSOR_OK;
+    switch (tmsg->id) {
+        case SENSOR_TMSG_VSENSOR_REG_EVENT: {
+            Vsensor *vsensor = (Vsensor *)(tmsg->value);
+            CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_VSENSOR_TASK_REG_VENSOR_NULL);
+            ret = VsensorTaskVsensorRegEvent(component, (Vsensor *)(tmsg->value));
+            break;
+        }
+        case SENSOR_TMSG_HSENSOR_DATA_UPDATE:
+        case SENSOR_TMSG_VSENSOR_DATA_UPDATE: {
+            ret = VsensorTaskSensorDataUpdateEvent(component, (VsensorProcessData *)(tmsg->info));
+            break;
+        }
+        case SENSOR_TMSG_VSENSOR_OPEN_EVENT: {
+            ret = VsensorTaskVsensorOpenEvent(
+                component, (enum SensorTypeTag)(tmsg->value), (SensorPara *)(tmsg->info), APP_CTRL);
+            break;
+        }
+        case SENSOR_TMSG_VSENSOR_CLOSE_EVENT: {
+            ret = VsensorTaskVsensorCloseEvent(component, (enum SensorTypeTag)(tmsg->value), APP_CTRL);
+            break;
+        }
+        case SENSOR_TMSG_VSENSOR_RELY_OPEN_EVENT: {
+            ret = VsensorTaskVsensorOpenEvent(
+                component, (enum SensorTypeTag)(tmsg->value), (SensorPara *)(tmsg->info), RELY_CTRL);
+            break;
+        }
+        case SENSOR_TMSG_VSENSOR_RELY_CLOSE_EVENT: {
+            ret = VsensorTaskVsensorCloseEvent(component, (enum SensorTypeTag)(tmsg->value), RELY_CTRL);
+            break;
+        }
+        default:
+            HILOG_INFO(HILOG_MODULE_SEN, "cannot get msg:%d task:%d proc.\n", tmsg->id, component->taskId);
+    }
+    HILOG_DEBUG(HILOG_MODULE_SEN, "msg:%d task:%d proc ret:%d", tmsg->id, component->taskId, ret);
+    return ret;
+}
+
+/* aclass类公用的消息处理函数 */
+int32_t VsensorTaskClassMsgProcess(VsensorTaskClass *vSensorClass, const SensorTmsg *tmsg)
+{
+    VsensorTaskComm *component = &(vSensorClass->component);
+
+    CHECK_NULL_PTR_RETURN_VALUE(vSensorClass, SENSOR_VSENSOR_TASK_CLASS_NULL);
+    int32_t ret = VsensorTaskCheckCommComponents(component);
+    SENSOR_CHECK_OK(ret);
+
+    if (tmsg == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "VsensorTaskClassMsgProcess tmsg NULL\r\n");
+        return SENSOR_RECV_TMSG_NULL;
+    }
+
+    if (vSensorClass->tmsgProcMap == NULL || vSensorClass->tmsgProcMapLen == 0) {
+        return VsensorTaskGenericMsgProcess(component, tmsg);
+    }
+
+    for (uint32_t i = 0; i < vSensorClass->tmsgProcMapLen; i++) {
+        if (vSensorClass->tmsgProcMap[i].tmsgId == tmsg->id && vSensorClass->tmsgProcMap[i].tmsgProc != NULL) {
+            return vSensorClass->tmsgProcMap[i].tmsgProc(tmsg);
+        }
+    }
+    return VsensorTaskGenericMsgProcess(component, tmsg);
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_comm.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_common/src/vsensor_task_comm.c
new file mode 100644 (file)
index 0000000..de4e2b6
--- /dev/null
@@ -0,0 +1,728 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task common impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "vsensor_task_comm.h"
+#include "sensor_log.h"
+#include "sensor_memory.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_tmsg.h"
+#include "sensor_para_decision.h"
+#include "sensor_state.h"
+
+int32_t VsensorTaskCheckCommComponents(const VsensorTaskComm *component)
+{
+    if (component == NULL || component->taskPrefix == NULL) {
+        return SENSOR_TASK_CHECK_COMM_COMPONENT_NULL;
+    }
+    return SENSOR_OK;
+}
+
+static VsensorTaskHlistener *VsensorTaskFindHlistener(
+    const VsensorTaskHlistener *hlistenerPool, uint16_t hlistenerPoolLen, enum SensorTypeTag type)
+{
+    CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, NULL);
+
+    for (uint32_t i = 0; i < VSENSOR_TASK_HLISTENER_MAX_NUM; i++) {
+        VsensorTaskHlistener *hlistener = (VsensorTaskHlistener *)(&(hlistenerPool[i]));
+        if (hlistener->type == type) {
+            return hlistener;
+        }
+    }
+
+    return NULL;
+}
+
+static VsensorTaskHlistener *VsensorTaskRequestHlistener(
+    const VsensorTaskHlistener *hlistenerPool, uint16_t hlistenerPoolLen, enum SensorTypeTag type)
+{
+    VsensorTaskHlistener *hlistener = VsensorTaskFindHlistener(hlistenerPool, hlistenerPoolLen, type);
+    if (hlistener != NULL) {
+        return hlistener;
+    }
+
+    for (uint32_t i = 0; i < VSENSOR_TASK_HLISTENER_MAX_NUM; i++) {
+        hlistener = (VsensorTaskHlistener *)(&(hlistenerPool[i]));
+        if (hlistener->type == SENSOR_TYPE_NONE) {
+            return hlistener;
+        }
+    }
+
+    return NULL;
+}
+
+static int32_t VsensorTaskDataUpdateCheck(const SensorNotifyInfo *events, const void *notifyArg)
+{
+    if ((events == NULL) || (events->data == NULL) || (notifyArg == NULL)) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]dataupdate para null %d\r\n", (int32_t)events->dataLen);
+        return SENSOR_TASK_HSDATA_UPDATE_DATA_NULL;
+    }
+
+    if (events->type >= SENSOR_TYPE_MAX) {
+        HILOG_ERROR(HILOG_MODULE_SEN,
+            "[VTASK]dataupdate sensor type or len err,type:%d, len:%u\r\n",
+            events->type,
+            events->dataLen);
+        return SENSOR_TASK_HSDATA_UPDATE_DATA_NULL;
+    }
+
+    return SENSOR_OK;
+}
+
+static void VsensorTaskSensorDataUpdate(const SensorNotifyInfo *events, void *notifyArg)
+{
+    int32_t ret;
+    ret = VsensorTaskDataUpdateCheck(events, notifyArg);
+    if (ret != SENSOR_OK) {
+        return;
+    }
+
+    VsensorTaskComm *component = (VsensorTaskComm *)notifyArg;
+
+    /* 计算实际需要的存储空间 */
+    uint32_t dataSize = (uint32_t)(sizeof(VsensorProcessData)) + events->dataLen;
+    VsensorProcessData *processData = (VsensorProcessData *)SensorMalloc(dataSize);
+    if (processData == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN,
+            "[VTASK]cannot malloc for hsensor:%d data!, taskId:%d\n",
+            events->type,
+            component->taskId);
+        return;
+    }
+    int32_t err = memset_s(processData, dataSize, 0, dataSize);
+    if (err != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]dataupdate: memset fail\r\n");
+    }
+
+    processData->timestamp = events->timestamp;
+    processData->sensor = events->type;
+    processData->dataLen = events->dataLen;
+
+    uint32_t i = 0;
+    while (i < events->dataLen) {
+        processData->sensordata[i] = events->data[i];
+        i++;
+    }
+    SensorTmsg tmsgSend = {
+        .id = SENSOR_TMSG_HSENSOR_DATA_UPDATE, .value = 0, .ts = 0, .info = processData, .infoSize = dataSize};
+
+    ret = SensorTmsgSend(component->taskId, &tmsgSend);
+    if (ret != SENSOR_OK) {
+        SensorFree((void *)processData);
+        processData = NULL;
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]dataupdate send msg error 0x%x\r\n", ret);
+    }
+
+    return;
+}
+
+static int32_t VsensorTaskHlistenerInit(
+    VsensorTaskComm *component, VsensorTaskHlistener *hlistener, enum SensorTypeTag type)
+{
+    HsensorListener *listener = &(hlistener->hlistener);
+    Sensor *sensor = SensorUtilsFindSensor(type);
+    if (sensor == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]init sensor NULL! type:%d", type);
+        return SENSOR_TASK_SENSOR_NULL;
+    }
+
+    errno_t err = memset_s(listener->name, HSENSOR_LISTENER_NAME_MAX_LEN, 0, HSENSOR_LISTENER_NAME_MAX_LEN);
+    if (err != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener init name memset full! type:%d", type);
+        return SENSOR_SENSOR_SECUREC_FUNC_ERR;
+    }
+    err = strcat_s(listener->name, sizeof(listener->name), component->taskPrefix);
+    if (err != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener init name strcat full! type:%d", type);
+        return SENSOR_SENSOR_SECUREC_FUNC_ERR;
+    }
+    err = strcat_s(listener->name, sizeof(listener->name), sensor->sensorInfo.name);
+    if (err != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener init name strcat full! type:%d", type);
+        return SENSOR_SENSOR_SECUREC_FUNC_ERR;
+    }
+
+    listener->type = type;
+    hlistener->type = type;
+
+    /* 如果没有指定物理传感器数据更新函数,默认直接采用 标准通道函数 */
+    if (component->hdataCb == NULL) {
+        listener->notifyCallback = VsensorTaskSensorDataUpdate;
+    } else {
+        listener->notifyCallback = component->hdataCb;
+    }
+    listener->notifyArg = (void *)component;
+    HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]Hlistener init type :%d", type);
+    return SENSOR_OK;
+}
+
+static int32_t VsensorTaskHlistenerRegister(HsensorListener *listener)
+{
+    int32_t ret = HsensorMgrRegisterListener(listener);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hsensormgr reg listener:%d return FAIL!\n", listener->type);
+        return ret;
+    }
+
+    return SENSOR_OK;
+}
+
+static VsensorTaskInfo *VsensorTaskFindVsensorInfo(
+    const VsensorTaskInfo *vsensorPool, uint16_t vsensorPoolLen, enum SensorTypeTag type)
+{
+    CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, NULL);
+
+    for (uint32_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+        VsensorTaskInfo *vsensorInfo = (VsensorTaskInfo *)(&(vsensorPool[i]));
+        if (vsensorInfo->type == type) {
+            if (vsensorInfo->vsensor == NULL) {
+                vsensorInfo->type = (enum SensorTypeTag)0;
+                vsensorInfo->state = SENSOR_STATE_IDLE;
+                continue;
+            }
+            return vsensorInfo;
+        }
+    }
+
+    return NULL;
+}
+
+static VsensorTaskInfo *VsensorTaskRequestVsensorInfo(
+    const VsensorTaskInfo *vsensorPool, uint16_t vsensorPoolLen, enum SensorTypeTag type)
+{
+    VsensorTaskInfo *vsensorInfo = VsensorTaskFindVsensorInfo(vsensorPool, vsensorPoolLen, type);
+    if (vsensorInfo != NULL) {
+        return vsensorInfo;
+    }
+
+    for (uint32_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+        vsensorInfo = (VsensorTaskInfo *)(&(vsensorPool[i]));
+        if (vsensorInfo->type == (enum SensorTypeTag)0) {
+            return vsensorInfo;
+        }
+    }
+
+    return NULL;
+}
+
+static int32_t VsensorTaskVsensorReg(const VsensorTaskComm *component, Vsensor *vsensor)
+{
+    VsensorTaskInfo *vsensorInfo =
+        VsensorTaskRequestVsensorInfo(component->vsensorInfo, VSENSOR_MAX_NUM, vsensor->type);
+    if (vsensorInfo == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]init find vsensorInfo NULL! type:%d", vsensor->type);
+        return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+    }
+
+    vsensorInfo->type = vsensor->type;
+    vsensorInfo->vsensor = vsensor;
+    HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]Reg type:%d", vsensor->type);
+    return SENSOR_OK;
+}
+
+static int32_t VsensorTaskOpenRelyHSensor(VsensorTaskComm *component, enum SensorTypeTag type, const SensorPara *para)
+{
+    VsensorTaskHlistener *hlistenerPool = component->hlistenersList;
+    HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]Open Rely hsensor:%d ", type);
+    VsensorTaskHlistener *var = VsensorTaskFindHlistener(hlistenerPool, VSENSOR_TASK_HLISTENER_MAX_NUM, type);
+    if ((var == NULL) || (var->type == SENSOR_TYPE_NONE)) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]rely hlistener NULL! type:%d", type);
+        return SENSOR_TASK_LISTENER_FIND_NULL;
+    }
+
+    SensorPara curDecisionPara = var->hlistener.openParam;
+    int32_t ret = SensorOpenParaDecision(type, &curDecisionPara, para, &(var->hlistener.openParam));
+    if (ret != SENSOR_OK) {
+        return ret;
+    }
+
+    if (SensorParaIsClear(&(var->hlistener.openParam))) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]sensor decision para err! type:%d", type);
+        return SENSOR_TASK_SENSOR_DECISION_PARA_ERROR;
+    }
+
+    ret = HsensorMgrOpenListener(&(var->hlistener));
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hsensor:%d enable err 0x%04x!\n", type, ret);
+        return ret;
+    }
+    HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]Open Rely hsensor:%d sucess", type);
+    return SENSOR_OK;
+}
+
+int32_t VsensorTaskOpenRelySensors(VsensorTaskComm *component, const RelySensorInfo *relySensors, uint8_t relyCnt)
+{
+    int32_t ret = SENSOR_OK;
+    if ((relySensors == NULL) || (relyCnt <= 0)) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[RELY] rely sensor is NULL!\n");
+        return SENSOR_OPEN_RELY_SENSORS_CHECK_NULL;
+    }
+
+    for (uint8_t i = 0; i < relyCnt; i++) {
+        enum SensorTypeTag type = relySensors[i].type;
+
+        if (!SensorUtilsSensorIsRegistered(type)) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "[RELY] rely sensor:%d not registed!\n", type);
+            return SENSOR_TASK_RELY_SENSOR_NOT_REGISTERED;
+        }
+
+        uint32_t taskId = SensorUtilsGetRegisteredTaskId(type);
+        bool isVsensor = SensorUtilsIsVSensor(type);
+        if (isVsensor == true) {
+            // 打开虚拟sensor
+            SensorTmsg tmsgSend = {.id = SENSOR_TMSG_VSENSOR_RELY_OPEN_EVENT,
+                .value = (uintptr_t)type,
+                .ts = 0,
+                .info = NULL,
+                .infoSize = 0};
+
+            ret = SensorTmsgSend(taskId, &tmsgSend);
+            if (ret != SENSOR_OK) {
+                HILOG_ERROR(HILOG_MODULE_SEN, "vsensor:%d send open msg FAIL!\r\n", type);
+                return ret;
+            }
+        } else {
+            /* 打开物理sensor, type 为物理sensor的类型 */
+            ret = VsensorTaskOpenRelyHSensor(component, type, (SensorPara *)&(relySensors[i].param));
+            if (ret != SENSOR_OK) {
+                return ret;
+            }
+        }
+    }
+    HILOG_DEBUG(HILOG_MODULE_SEN, "Open Rely Sensors sucess");
+    return SENSOR_OK;
+}
+
+static int32_t SensorCloseParaDecision(enum SensorTypeTag type, VsensorTaskComm *component, SensorPara *result)
+{
+    SensorPara *temp = NULL;
+    VsensorTaskInfo *vsensorInfo = NULL;
+    Vsensor *vsensor = NULL;
+
+    if (component == NULL || result == NULL) {
+        return SENSOR_TASK_CHECK_COMM_COMPONENT_NULL;
+    }
+
+    SensorParaClear(result);
+
+    for (uint32_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+        vsensorInfo = (VsensorTaskInfo *)(&(component->vsensorInfo[i]));
+        if (vsensorInfo->type == (enum SensorTypeTag)0 || vsensorInfo->vsensor == NULL) {
+            continue;
+        }
+
+        vsensor = vsensorInfo->vsensor;
+        temp = NULL;
+        for (uint32_t cnt = 0; cnt < vsensor->relySensors->relySensorCnt; cnt++) {
+            if (type == vsensor->relySensors->relySensorArray[cnt].type && vsensorInfo->state == SENSOR_STATE_OPEN) {
+                temp = &(vsensor->relySensors->relySensorArray[cnt].param);
+                HILOG_INFO(
+                    HILOG_MODULE_SEN, "close sensor:%d decision, vsensor:%d still running\n", type, vsensor->type);
+            }
+        }
+
+        if (temp == NULL) {
+            continue;
+        }
+
+        if (SensorParaIsClear(result)) {
+            SensorParaCopy(result, temp);
+        } else {
+            SensorPara cur = *result;
+            result->period = SENSOR_MIN(cur.period, temp->period);
+            if (result->period == 0) {
+                return SENSOR_ERROR;
+            }
+            result->batch = SENSOR_MIN(cur.batch * cur.period, temp->batch * temp->period) / result->period;
+            result->mode = SENSOR_MIN(cur.mode, temp->mode);
+            result->option = SensorOptionDecision(type, cur.option, temp->option);
+        }
+    }
+
+    return SENSOR_OK;
+}
+
+static int32_t VsensorTaskCloseRelyHsensor(VsensorTaskComm *component, enum SensorTypeTag type)
+{
+    VsensorTaskHlistener *hlistenerPool = component->hlistenersList;
+
+    VsensorTaskHlistener *var = VsensorTaskFindHlistener(hlistenerPool, VSENSOR_TASK_HLISTENER_MAX_NUM, type);
+    if ((var == NULL) || (var->type == (enum SensorTypeTag)0)) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]rely hlistenerInfo NULL! type:%d", type);
+        return SENSOR_TASK_LISTENER_FIND_NULL;
+    }
+
+    int32_t ret = SensorCloseParaDecision(type, component, &(var->hlistener.openParam));
+    if (ret != SENSOR_OK) {
+        return ret;
+    }
+
+    if (!SensorParaIsClear(&(var->hlistener.openParam))) {
+        HILOG_INFO(HILOG_MODULE_SEN,
+            "[VTASK]do not close rely sensor:%d, decision para,period:%d, batch:%d, mode:%d, option:%d\n",
+            type,
+            var->hlistener.openParam.period,
+            var->hlistener.openParam.batch,
+            var->hlistener.openParam.mode,
+            var->hlistener.openParam.option);
+        ret = HsensorMgrOpenListener(&(var->hlistener));
+        if (ret != SENSOR_OK) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hsensor:%d enable err %d!\n", type, ret);
+            return ret;
+        }
+        return SENSOR_OK;
+    }
+
+    ret = HsensorMgrCloseListener(&(var->hlistener));
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hsensor:%d close err!\n", type);
+        return ret;
+    }
+
+    return SENSOR_OK;
+}
+
+static int32_t VsensorTaskCloseRelySensors(
+    VsensorTaskComm *component, const RelySensorInfo *relySensors, uint8_t relyCnt)
+{
+    int32_t ret = SENSOR_OK;
+
+    if ((relySensors == NULL) || (relyCnt <= 0)) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[RELY] rely sensor is NULL!\n");
+        return SENSOR_OPEN_RELY_SENSORS_CHECK_NULL;
+    }
+
+    for (uint8_t i = 0; i < relyCnt; i++) {
+        enum SensorTypeTag type = relySensors[i].type;
+
+        if (!SensorUtilsSensorIsRegistered(type)) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "[RELY] rely sensor:%d not registed!\n", type);
+            return SENSOR_TASK_RELY_SENSOR_NOT_REGISTERED;
+        }
+
+        uint32_t taskId = SensorUtilsGetRegisteredTaskId(type);
+        bool isVsensor = SensorUtilsIsVSensor(type);
+        if (isVsensor == true) {
+            // 关闭虚拟sensor
+            SensorTmsg tmsgSend = {.id = SENSOR_TMSG_VSENSOR_RELY_CLOSE_EVENT,
+                .value = (uintptr_t)type,
+                .ts = 0,
+                .info = NULL,
+                .infoSize = 0};
+
+            ret = SensorTmsgSend(taskId, &tmsgSend);
+            if (ret != SENSOR_OK) {
+                HILOG_ERROR(HILOG_MODULE_SEN, "[UTIL] fa vsensor:%d send open msg FAIL!\r\n", type);
+                return ret;
+            }
+        } else {
+            /* 关闭物理sensor */
+            ret = VsensorTaskCloseRelyHsensor(component, type);
+            if (ret != SENSOR_OK) {
+                return ret;
+            }
+        }
+    }
+
+    return SENSOR_OK;
+}
+
+static bool VsensorTaskSensorBeRelied(enum SensorTypeTag type, const RelySensorInfo *relySensors, uint8_t relyCnt)
+{
+    if ((relySensors == NULL) || (relyCnt <= 0)) {
+        return false;
+    }
+
+    for (uint8_t i = 0; i < relyCnt; i++) {
+        if (relySensors[i].type == type) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+static int32_t VsensorTaskHlistenerRegEvent(VsensorTaskComm *component, enum SensorTypeTag type)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "[VTASK]type:%d Hlistener RegEvent ", type);
+
+    VsensorTaskHlistener *var =
+        VsensorTaskRequestHlistener(component->hlistenersList, VSENSOR_TASK_HLISTENER_MAX_NUM, type);
+    if (var == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]VsensorTaskHlistenerRegEvent find hlistener NULL! type:%d", type);
+        return SENSOR_TASK_LISTENER_FIND_NULL;
+    }
+    int32_t ret = VsensorTaskHlistenerInit(component, var, type);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener:%d init FAIL!\n", type);
+        return ret;
+    }
+
+    ret = VsensorTaskHlistenerRegister(&(var->hlistener));
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]hlistener:%d reg FAIL!\n", type);
+        return ret;
+    }
+    return SENSOR_OK;
+}
+
+static int32_t VsensorTaskVsensorRelyReg(VsensorTaskComm *component, enum SensorTypeTag type)
+{
+    CHECK_SENSOR_TYPE_ILLEGAL_RETURN_RET(type, SENSOR_TASK_HLISTENER_REG_TYPE_ERR);
+    if (SensorUtilsIsVSensor(type)) {
+        /* 依赖虚拟传感器,do nothing */
+        HILOG_INFO(HILOG_MODULE_SEN, "[VTASK]type:%d IsVSensor do nothing", type);
+        return SENSOR_OK;
+    }
+    /* 依赖物理传感器 */
+    int32_t ret = VsensorTaskHlistenerRegEvent(component, type);
+    if (ret != SENSOR_OK) {
+        return ret;
+    }
+    return SENSOR_OK;
+}
+
+bool VsensorTaskVsensorIsRunning(const VsensorTaskInfo *vsensorInfo)
+{
+    if (vsensorInfo == NULL || vsensorInfo->vsensor == NULL) {
+        return false;
+    }
+    if (vsensorInfo->type == SENSOR_TYPE_NONE) {
+        return false;
+    }
+    if (vsensorInfo->state == SENSOR_STATE_OPEN) {
+        return true;
+    }
+    return false;
+}
+
+void VsensorTaskCommInit(VsensorTaskComm *component)
+{
+    int32_t ret = VsensorTaskCheckCommComponents(component);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]init :component is NULL!\n");
+        return;
+    }
+
+    for (uint32_t i = 0; i < VSENSOR_TASK_HLISTENER_MAX_NUM; i++) {
+        ret = memset_s(&component->hlistenersList[i].hlistener, sizeof(HsensorListener), 0, sizeof(HsensorListener));
+        if (ret != EOK) {
+            HILOG_WARN(HILOG_MODULE_SEN, "init :component memset_s hlistener failed!\n");
+        }
+        SensorPara *openParam = &(component->hlistenersList[i].hlistener.openParam);
+        SensorParaClear(openParam);
+    }
+    return;
+}
+
+int32_t VsensorTaskVsensorRegEvent(VsensorTaskComm *component, Vsensor *vsensor)
+{
+    int32_t ret = VsensorTaskCheckCommComponents(component);
+    SENSOR_CHECK_OK(ret);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_VSENSOR_TASK_REG_VENSOR_NULL);
+
+    HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]vsensor:%d reg task:%d start", vsensor->type, component->taskId);
+
+    ret = VsensorTaskVsensorReg(component, vsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN,
+            "[VTASK]vsensor:%d reg task:%d FAIL!, ret:0x%04x",
+            vsensor->type,
+            component->taskId,
+            ret);
+        return ret;
+    }
+
+    RelySensorsInfo *relySensors = vsensor->relySensors;
+    CHECK_NULL_PTR_RETURN_VALUE(relySensors, SENSOR_OPEN_RELY_SENSORS_CHECK_NULL);
+    HILOG_DEBUG(
+        HILOG_MODULE_SEN, "[VTASK]vsensor:%d relySensorCnt:%u", vsensor->type, relySensors->relySensorCnt);
+    for (uint8_t i = 0; i < relySensors->relySensorCnt; i++) {
+        enum SensorTypeTag type = relySensors->relySensorArray[i].type;
+        HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]vsensor:%d relySensor :%u", vsensor->type, type);
+        ret = VsensorTaskVsensorRelyReg(component, type);
+        if (ret != SENSOR_OK) {
+            HILOG_ERROR(HILOG_MODULE_SEN,
+                "[VTASK]vsensor:%d rely sensor:%d FAIL!, ret:0x%04x\n",
+                vsensor->type,
+                type,
+                ret);
+            return ret;
+        }
+    }
+    HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]vsensor:%d reg task:%d SUCCESS", vsensor->type, component->taskId);
+    return SENSOR_OK;
+}
+
+int32_t VsensorTaskSensorDataUpdateEvent(VsensorTaskComm *component, VsensorProcessData *data)
+{
+    int32_t ret;
+    enum SensorTypeTag type;
+    Vsensor *vsensor = NULL;
+    VsensorTaskInfo *vsensorInfo = NULL;
+
+    ret = VsensorTaskCheckCommComponents(component);
+    SENSOR_CHECK_OK(ret);
+    CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_TASK_HSDATA_UPDATE_DATA_NULL);
+
+    type = data->sensor;
+
+    for (uint32_t i = 0; i < VSENSOR_MAX_NUM; i++) {
+        vsensorInfo = &(component->vsensorInfo[i]);
+        vsensor = vsensorInfo->vsensor;
+
+        /* 判断算法是否在运行 */
+        if (!VsensorTaskVsensorIsRunning(vsensorInfo)) {
+            continue;
+        }
+
+        /* 检查数据依赖 */
+        if (!VsensorTaskSensorBeRelied(type, vsensor->relySensors->relySensorArray,
+            vsensor->relySensors->relySensorCnt)) {
+            continue;
+        }
+
+        if (vsensor->process == NULL) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]vsensor_process NULL! type:%d", vsensor->type);
+            return SENSOR_TASK_VSENSOR_PROCESS_NULL;
+        }
+        ret = vsensor->process(type, data->sensordata, data->timestamp, data->dataLen);
+        if (ret != SENSOR_OK) {
+            HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]alg:%d process err:%x\n", vsensorInfo->type, ret);
+            continue;
+        }
+    }
+
+    return SENSOR_OK;
+}
+
+static int32_t VsensorTaskVsensorOpenRely(
+    VsensorTaskComm *component, VsensorTaskInfo *vsensorInfo, SensorPara *para, uint32_t openType)
+{
+    /* 在前面的处理中,不可能出现空指针现象 */
+    Vsensor *vsensor = vsensorInfo->vsensor;
+    if (vsensor == NULL) {
+        return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+    }
+
+    if (vsensor->open == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]vsensor_open NULL! type:%d", vsensorInfo->type);
+        return SENSOR_TASK_VSENSOR_OPEN_NULL;
+    }
+    int32_t ret = vsensor->open(para);
+    if (ret != SENSOR_OK) {
+        return SENSOR_TASK_VSENSOR_OPEN_FAIL;
+    }
+    vsensorInfo->state = SENSOR_STATE_OPEN;
+    if (openType == APP_CTRL) {
+        SensorSetState(vsensor->type, SENSOR_STATE_OPEN);
+        if (para != NULL) {
+            SensorSetPara(vsensor->type, para);
+        }
+    }
+
+    RelySensorsInfo *relySensors = vsensor->relySensors;
+    ret = VsensorTaskOpenRelySensors(component, relySensors->relySensorArray, relySensors->relySensorCnt);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(
+            HILOG_MODULE_SEN, "[VTASK]vsensor:%d open rely sensor FAIL 0x%04x!\n", vsensorInfo->type, ret);
+        return ret;
+    }
+    HILOG_DEBUG(
+        HILOG_MODULE_SEN, "[VTASK]VsensorOpenRely type:%d openType:%u SUCESS", vsensorInfo->type, openType);
+    return SENSOR_OK;
+}
+
+int32_t VsensorTaskVsensorOpenEvent(
+    VsensorTaskComm *component, enum SensorTypeTag type, SensorPara *para, uint32_t openType)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "[VTASK]OpenEvent type:%d openType:%u", type, openType);
+    int32_t ret = VsensorTaskCheckCommComponents(component);
+    SENSOR_CHECK_OK(ret);
+
+    VsensorTaskInfo *vsensorInfo = VsensorTaskFindVsensorInfo(component->vsensorInfo, VSENSOR_MAX_NUM, type);
+    if (vsensorInfo == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]open find vsensorInfo NULL! type:%d", type);
+        return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+    }
+
+    if (openType == APP_CTRL) {
+        vsensorInfo->relyedInfo.appOpenFlag = true;
+    } else { /* VSENSOR_CTRL */
+        vsensorInfo->relyedInfo.relyedCnt++;
+    }
+
+    if (vsensorInfo->state == SENSOR_STATE_OPEN) {
+        /* 已经开启vsensor,不再重复打开 */
+        if (openType == APP_CTRL) {
+            /* APP_CTRL 将状态刷新为OPEN */
+            Vsensor *vsensor = vsensorInfo->vsensor;
+            if (vsensor == NULL) {
+                return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+            }
+            SensorSetState(vsensor->type, SENSOR_STATE_OPEN);
+        }
+        return SENSOR_OK;
+    }
+
+    return VsensorTaskVsensorOpenRely(component, vsensorInfo, para, openType);
+}
+
+int32_t VsensorTaskVsensorCloseEvent(VsensorTaskComm *component, enum SensorTypeTag type, uint32_t closeType)
+{
+    int32_t ret = VsensorTaskCheckCommComponents(component);
+    SENSOR_CHECK_OK(ret);
+
+    VsensorTaskInfo *vsensorInfo = VsensorTaskFindVsensorInfo(component->vsensorInfo, VSENSOR_MAX_NUM, type);
+    if (vsensorInfo == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]close find vsensorInfo NULL! type:%d", type);
+        return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+    }
+
+    if (closeType == APP_CTRL) {
+        vsensorInfo->relyedInfo.appOpenFlag = false;
+    } else {
+        vsensorInfo->relyedInfo.relyedCnt--;
+    }
+
+    if (vsensorInfo->relyedInfo.relyedCnt > 0 || vsensorInfo->relyedInfo.appOpenFlag ||
+        (vsensorInfo->state == SENSOR_STATE_CLOSE)) {
+        /* (1)用户控制开和其他算法依赖开,都不能关闭虚拟传感器;(2)已经关闭的情况下无需再关闭一次 */
+        if (closeType == APP_CTRL) {  // 关闭vsensor,但还存在依赖不能关闭,需将状态更新为close
+            SensorSetState(type, SENSOR_STATE_CLOSE);
+        }
+        return SENSOR_OK;
+    }
+
+    /* 在前面的处理中,不可能出现空指针现象 */
+    Vsensor *vsensor = vsensorInfo->vsensor;
+    if (vsensor == NULL) {
+        return SENSOR_TASK_VSENSOR_INFO_FIND_NULL;
+    }
+
+    if (vsensor->close == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]vsensor_close NULL! type:%d", type);
+        return SENSOR_TASK_VSENSOR_CLOSE_NULL;
+    }
+    ret = vsensor->close();
+    if (ret != SENSOR_OK) {
+        return SENSOR_TASK_VSENSOR_CLOSE_FAIL;
+    }
+    vsensorInfo->state = SENSOR_STATE_CLOSE;
+    if (closeType == APP_CTRL) {
+        SensorSetState(vsensor->type, SENSOR_STATE_CLOSE);
+    }
+
+    RelySensorsInfo *relySensors = vsensor->relySensors;
+    ret = VsensorTaskCloseRelySensors(component, relySensors->relySensorArray, relySensors->relySensorCnt);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[VTASK]vsensor:%d close rely sensor FAIL!, ret:0x%04x\n", type, ret);
+        return ret;
+    }
+
+    return SENSOR_OK;
+}
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_mgr.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensor_task_mgr.c
new file mode 100644 (file)
index 0000000..7f5b319
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor task mgr impl
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "vsensor_task_mgr.h"
+#include "vsensor_task_class.h"
+#include "sensor_common.h"
+#include "sensor_log.h"
+#include "sensor_tmsg.h"
+
+/* 任务初始化 */
+int32_t VsensorTaskMgrInit(uint32_t taskId)
+{
+    VsensorTaskClass* aclassMotion = VsensorTaskClassInit(taskId, "VSENSOR_", NULL, NULL, 0);
+    if (aclassMotion == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "extern alg task create ERR!\n");
+        return SENSOR_ERROR;
+    }
+
+    return SENSOR_OK;
+}
+
+/* 任务销毁 */
+void VsensorTaskMgrDeInit(uint32_t taskId)
+{
+    VsensorTaskClass* vSensorClass = VsensorTaskClassGetByTaskid(taskId);
+    VsensorTaskClassDestruct(vSensorClass);
+}
+
+/* 任务消息处理函数入口 */
+int32_t VsensorTaskMgrMsgProcess(uint32_t taskId, const SensorTmsg *tmsg)
+{
+    VsensorTaskClass* vSensorClass = VsensorTaskClassGetByTaskid(taskId);
+    if (vSensorClass == NULL) {
+        return SENSOR_VSENSOR_TASK_CLASS_NULL;
+    }
+
+    return VsensorTaskClassMsgProcess(vSensorClass, tmsg);
+}
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensormgr_service.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensor_mgr/src/vsensormgr_service/src/vsensormgr_service.c
new file mode 100644 (file)
index 0000000..fba1782
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor mgr service
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "vsensormgr_service.h"
+#include "securec.h"
+#include "sensor_log.h"
+#include "sensor_utils.h"
+#include "sensor_memory.h"
+#include "sensor_common.h"
+#include "sensor_task.h"
+#include "sensor_tmsg.h"
+#include "sensor_para_decision.h"
+
+typedef struct {
+    struct osal_list_head list;
+    const Vsensor *vsensor;
+} VsensorInfo;
+
+typedef struct {
+    struct osal_list_head vsensorHead;
+    uint32_t vsensorNum;
+    bool inited;
+} VsensorMgr;
+
+static VsensorMgr g_vsensormgr = {0};
+
+VsensorMgr *VsensorMgrGetInstance(void)
+{
+    return &g_vsensormgr;
+}
+
+int32_t VsensorMgrInit(void)
+{
+    VsensorMgr *vsensorMgr = VsensorMgrGetInstance();
+    if (vsensorMgr->inited) {
+        return SENSOR_OK;
+    }
+    OSAL_INIT_LIST_HEAD(&(vsensorMgr->vsensorHead));
+    vsensorMgr->vsensorNum = 0;
+
+    int32_t ret = SensorTaskInit();
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "SensorTask fail.\n");
+        return SENSOR_ERROR;
+    }
+    vsensorMgr->inited = true;
+    HILOG_INFO(HILOG_MODULE_SEN, "VsensorMgrInit OK.");
+    return SENSOR_OK;
+}
+
+static int32_t NotifyVsensorTaskRegVsensor(const Vsensor *vsensor, int32_t taskId)
+{
+    SensorTmsg tmsgSend = {
+        .id = SENSOR_TMSG_VSENSOR_REG_EVENT, .value = (uintptr_t)vsensor, .ts = 0, .info = NULL, .infoSize = 0};
+    return SensorTmsgSend(taskId, &tmsgSend);
+}
+
+static const Vsensor *VsensorMgrFindVsensor(enum SensorTypeTag type)
+{
+    VsensorMgr *vsensorMgr = VsensorMgrGetInstance();
+
+    HILOG_DEBUG(HILOG_MODULE_SEN, "vsensorNum:%u", vsensorMgr->vsensorNum);
+    VsensorInfo *vsensorIndex = NULL;
+    osal_list_for_each_entry(vsensorIndex, &vsensorMgr->vsensorHead, list)
+    {
+        HILOG_DEBUG(HILOG_MODULE_SEN, "vsensor type:%d", vsensorIndex->vsensor->type);
+        if (vsensorIndex->vsensor->type == type) {
+            return vsensorIndex->vsensor;
+        }
+    }
+    return NULL;
+}
+
+static int32_t VsensorMgrSensorOpen(const Sensor *sensor, const SensorPara *openPara)
+{
+    const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ERROR);
+    uint32_t taskId = SensorUtilsGetRegisteredTaskId(sensor->sensorInfo.type);
+    if (taskId == SENSOR_TASK_MAX_CNT) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] not found taskId type:%d", vsensor->type);
+        return SENSOR_ERROR;
+    }
+    /* 传递para 计算实际需要的存储空间 */
+    uint32_t dataSize = (uint32_t)(sizeof(SensorPara));
+    SensorPara *paraTemp = (SensorPara *)SensorMalloc(dataSize);
+    if (paraTemp == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "cannot malloc for sensor:%d data!, taskId:%d", sensor->sensorInfo.type, taskId);
+        return SENSOR_ERROR;
+    }
+
+    SensorParaCopy(paraTemp, openPara);
+
+    SensorTmsg tmsgSend = {.id = SENSOR_TMSG_VSENSOR_OPEN_EVENT,
+        .value = (uintptr_t)sensor->sensorInfo.type,
+        .ts = 0,
+        .info = paraTemp,
+        .infoSize = dataSize};
+    HILOG_INFO(HILOG_MODULE_SEN, "Open vsensor type: %d name: %s taskId:%u ", vsensor->type, vsensor->name, taskId);
+    return SensorTmsgSend(taskId, &tmsgSend);
+}
+
+static int32_t VsensorMgrSensorClose(const Sensor *sensor)
+{
+    const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ERROR);
+    uint32_t taskId = SensorUtilsGetRegisteredTaskId(sensor->sensorInfo.type);
+    if (taskId == SENSOR_TASK_MAX_CNT) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] not found taskId type:%d", vsensor->type);
+        return SENSOR_ERROR;
+    }
+    SensorTmsg tmsgSend = {
+        .id = SENSOR_TMSG_VSENSOR_CLOSE_EVENT, .value = (uintptr_t)vsensor->type, .ts = 0, .info = NULL, .infoSize = 0};
+    HILOG_INFO(HILOG_MODULE_SEN, "close vsensor type: %d name: %s taskId:%u ", vsensor->type, vsensor->name, taskId);
+    return SensorTmsgSend(taskId, &tmsgSend);
+}
+
+static int32_t VsensorMgrSensorSetBatch(Sensor *sensor, int64_t samplingInterval, int64_t reportInterval)
+{
+    HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+    return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorSetMode(Sensor *sensor, int32_t mode)
+{
+    HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+    return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorSetOption(Sensor *sensor, uint32_t option)
+{
+    HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+    return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorRegisterResultCallback(const Sensor *sensor, RecordDataCallback cb)
+{
+    const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ERROR);
+    return vsensor->registDataCb(cb);
+}
+
+static int32_t VsensorMgrSensorUnregisterResultCallback(const Sensor *sensor, RecordDataCallback cb)
+{
+    const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+    CHECK_NULL_PTR_RETURN_VALUE(vsensor, SENSOR_ERROR);
+    return vsensor->unRegistDataCb(cb);
+}
+
+static int32_t VsensorMgrSensorCalibrate(const Sensor *sensor, void *para, uint32_t len)
+{
+    HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+    return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorSelfTest(const Sensor *sensor, void *para, uint32_t len)
+{
+    HILOG_WARN(HILOG_MODULE_SEN, "unsupport");
+    return SENSOR_VSENSOR_NOT_SUPPORT;
+}
+
+static int32_t VsensorMgrSensorIoctl(const Sensor *sensor, SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    if (cmd >= SENSOR_IOCTL_MAX || cmd < SENSOR_IOCTL_SET_PARA) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "invalid command!");
+        return SENSOR_ERROR;
+    }
+    const Vsensor *vsensor = VsensorMgrFindVsensor(sensor->sensorInfo.type);
+    if (vsensor->ioctl == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "invalid ioctl function!");
+        return SENSOR_ERROR;
+    }
+    return vsensor->ioctl(cmd, data, len);
+}
+
+static int32_t VsensorTaskRegister(const Vsensor *vsensor)
+{
+    int32_t ret = SensorTaskCreateVsensorTask(vsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "vsensor type %d name %s CreateVsensorTask fail", vsensor->type, vsensor->name);
+        return SENSOR_ERROR;
+    }
+    uint32_t taskId = SensorUtilsGetRegisteredTaskId(vsensor->type);
+    if (taskId == SENSOR_TASK_MAX_CNT) {
+        SensorTaskDestroyVsensorTask(vsensor->type);
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] not found taskId type:%d", vsensor->type);
+        return SENSOR_ERROR;
+    }
+    SensorUtilsRegisterVsensorType(vsensor->type);
+
+    HILOG_DEBUG(HILOG_MODULE_SEN, "vsensor type:%d  taskId:%u", vsensor->type, taskId);
+    ret = NotifyVsensorTaskRegVsensor(vsensor, taskId);
+    if (ret != SENSOR_OK) {
+        SensorTaskDestroyVsensorTask(vsensor->type);
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] NotifyVsensorTaskRegVsensor failed type:%d ret:%d", vsensor->type, ret);
+        return SENSOR_ERROR;
+    }
+    return SENSOR_OK;
+}
+
+static int32_t VsensorMgrSensorRegisterProc(const Vsensor *vsensor)
+{
+    Sensor *sensor = SensorUtilsRequestSensor(vsensor->type);
+    if (sensor == NULL || sensor->sensorInfo.state != SENSOR_STATE_IDLE) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "sensor type %d name %s request fail.", vsensor->type, vsensor->name);
+        return SENSOR_ERROR;
+    }
+    sensor->sensorInfo.type = vsensor->type;
+    sensor->sensorInfo.name = vsensor->name;
+    SensorParaDefaultInit(&sensor->sensorInfo.openPara);
+    sensor->open = VsensorMgrSensorOpen;
+    sensor->close = VsensorMgrSensorClose;
+    sensor->setBatch = VsensorMgrSensorSetBatch;
+    sensor->setMode = VsensorMgrSensorSetMode;
+    sensor->setOption = VsensorMgrSensorSetOption;
+    sensor->registerResultCallback = VsensorMgrSensorRegisterResultCallback;
+    sensor->unregisterResultCallback = VsensorMgrSensorUnregisterResultCallback;
+    sensor->calibrate = VsensorMgrSensorCalibrate;
+    sensor->selfTest = VsensorMgrSensorSelfTest;
+    sensor->ioctl = VsensorMgrSensorIoctl;
+    HILOG_INFO(HILOG_MODULE_SEN, "register vsensor type:%d name:%s ", sensor->sensorInfo.type, sensor->sensorInfo.name);
+    return SENSOR_OK;
+}
+
+int32_t VsensorMgrRegister(const Vsensor *vsensor)
+{
+    VsensorMgr *vsensorMgr = VsensorMgrGetInstance();
+    if (!vsensorMgr->inited && (VsensorMgrInit() != SENSOR_OK)) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "vsensorMgr inited failed.");
+        return SENSOR_ERROR;
+    }
+    int32_t ret = VsensorTaskRegister(vsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "[SYS] VsensorPostRegist failed type:%d", vsensor->type);
+        return SENSOR_ERROR;
+    }
+    ret = SensorUtilsAddVsensorList(vsensor->type);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(
+            HILOG_MODULE_SEN, "vsensor type %d name %s SensorUtilsAddSensorList fail", vsensor->type, vsensor->name);
+        return SENSOR_ERROR;
+    }
+    ret = VsensorMgrSensorRegisterProc(vsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN,
+            "vsensor type %d name %s VsensorMgrSensorRegisterProc fail",
+            vsensor->type,
+            vsensor->name);
+        return SENSOR_ERROR;
+    }
+    VsensorInfo *vsensorInfo = SensorMalloc(sizeof(VsensorInfo));
+    CHECK_NULL_PTR_RETURN_VALUE(vsensorInfo, SENSOR_ERROR);
+    OSAL_INIT_LIST_HEAD(&(vsensorInfo->list));
+    vsensorInfo->vsensor = vsensor;
+    osal_list_add(&vsensorInfo->list, &vsensorMgr->vsensorHead);
+    vsensorMgr->vsensorNum++;
+    HILOG_INFO(HILOG_MODULE_SEN, "register vsensor type %d name  %s success.", vsensor->type, vsensor->name);
+    return SENSOR_OK;
+}
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/acc_simulator/CMakeLists.txt b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/acc_simulator/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3dae158
--- /dev/null
@@ -0,0 +1,57 @@
+set(COMPONENT_NAME "sensor_hdi_acc_simulator")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/acc_simulator.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+set(AUTO_ADD_PATH
+    false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+    ${CDEFINES}
+)
+
+build_component()
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/acc_simulator/acc_simulator.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/acc_simulator/acc_simulator.c
new file mode 100644 (file)
index 0000000..f808e37
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: accel simu
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define ACCEL_MAX_BATCH_COUNT 10
+
+static int32_t AccSimuInit(void);
+static int32_t AccSimuDeinit(void);
+static int32_t AccSimuOpen(SensorPara *para);
+static int32_t AccSimuClose(void);
+static int32_t AccSimuRead(uint8_t *data, uint32_t len);
+static int32_t AccSimuIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_accSimuHsensor = {
+    .type = SENSOR_TYPE_ACCELEROMETER,
+    .name = "ACCEL_SIMU",
+    .caps.sampleElementlen = sizeof(struct AccelData),
+    .caps.maxBatchCount = ACCEL_MAX_BATCH_COUNT,
+    .privateData = NULL,
+    .privateDataLen = 0,
+    .init = AccSimuInit,
+    .deinit = AccSimuDeinit,
+    .open = AccSimuOpen,
+    .close = AccSimuClose,
+    .read = AccSimuRead,
+    .ioctl = AccSimuIoctl
+};
+
+static struct AccelData g_accSimuData = {
+    .axisX = 8,
+    .axisY = 9,
+    .axisZ = 10
+};
+
+static struct AccelData g_accSimuStoreData[ACCEL_MAX_BATCH_COUNT] = {0};
+static uint32_t g_accSimuBacthCnt = 1;
+static uint32_t g_accSimuTimeStamp = 0;
+
+static void AccSimuAddStoreData()
+{
+    uint32_t top = g_accSimuBacthCnt == ACCEL_MAX_BATCH_COUNT ? ACCEL_MAX_BATCH_COUNT - 1 : g_accSimuBacthCnt;
+    if (g_accSimuBacthCnt != ACCEL_MAX_BATCH_COUNT) {
+        g_accSimuBacthCnt++;
+    }
+    for (uint32_t i = top; i > 0; i--) {
+        g_accSimuStoreData[i].axisX = g_accSimuStoreData[i - 1].axisX;
+        g_accSimuStoreData[i].axisY = g_accSimuStoreData[i - 1].axisY;
+        g_accSimuStoreData[i].axisZ = g_accSimuStoreData[i - 1].axisZ;
+    }
+    g_accSimuStoreData[0].axisX = g_accSimuData.axisX++;
+    g_accSimuStoreData[0].axisY = g_accSimuData.axisY++;
+    g_accSimuStoreData[0].axisZ = g_accSimuData.axisZ++;
+    HILOG_INFO(HILOG_MODULE_SEN,
+        "AccSimuRead dataX:%d, dataY:%d, dataZ:%d",
+        g_accSimuData.axisX,
+        g_accSimuData.axisY,
+        g_accSimuData.axisZ);
+}
+
+static int32_t AccSimuInit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "AccSimuInit!");
+    return SENSOR_OK;
+}
+
+static int32_t AccSimuDeinit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "AccSimuDeinit!");
+    return SENSOR_OK;
+}
+
+static int32_t AccSimuOpen(SensorPara *para)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "AccSimuOpen!");
+    return SENSOR_OK;
+}
+
+static int32_t AccSimuClose(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "AccSimuClose!");
+    g_accSimuData.axisX = 0;
+    g_accSimuData.axisY = 0;
+    g_accSimuData.axisZ = 0;
+    return SENSOR_OK;
+}
+
+static int32_t AccSimuRead(uint8_t *data, uint32_t len)
+{
+    AccSimuAddStoreData();
+    g_accSimuTimeStamp += 1;
+    CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+    int32_t readLen = sizeof(struct AccelData);
+    int32_t ret = memcpy_s(data, len, &g_accSimuData, readLen);
+    if (ret != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+        return -1;
+    }
+    g_accSimuData.axisX++;
+    g_accSimuData.axisY++;
+    g_accSimuData.axisZ++;
+    return readLen;
+}
+
+static int32_t AccSimuGetData(SensorData *sensorData)
+{
+    sensorData->data = g_accSimuStoreData;
+    size_t len = sizeof(struct AccelData);
+    sensorData->dataLen = (uint32_t)len;
+    sensorData->batchCnt = g_accSimuBacthCnt;
+    sensorData->timestamp = g_accSimuTimeStamp;
+    return SENSOR_OK;
+}
+
+static int32_t AccSimuIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "AccSimuIoctl!");
+    switch (cmd) {
+        case SENSOR_IOCTL_GET_SENSOR_DATA:
+            AccSimuGetData((SensorData *)data);
+            break;
+        default:
+            return SENSOR_ERROR;
+    }
+    return SENSOR_OK;
+}
+
+static void AccSimuHsensorRigister(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_accSimuHsensor.type);
+    int32_t ret = SensorMgrRegistHsensor(&g_accSimuHsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_accSimuHsensor.type);
+        return;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_accSimuHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(AccSimuHsensorRigister, 3);
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/barometer/CMakeLists.txt b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/barometer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a03889d
--- /dev/null
@@ -0,0 +1,57 @@
+set(COMPONENT_NAME "sensor_hdi_barometer")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/barometer.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+set(AUTO_ADD_PATH
+    false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+    ${CDEFINES}
+)
+
+build_component()
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/barometer/barometer.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/barometer/barometer.c
new file mode 100644 (file)
index 0000000..0ccdddb
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: baroMeter simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define MAX_BATCH_COUNT 10
+
+static int32_t BaroMeterInit(void);
+static int32_t BaroMeterDeInit(void);
+static int32_t BaroMeterOpen(SensorPara *para);
+static int32_t BaroMeterClose(void);
+static int32_t BaroMeterRead(uint8_t *data, uint32_t len);
+static int32_t BaroMeterIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_baroMeterHsensor = {
+    .type = SENSOR_TYPE_BAROMETER,
+    .name = "BARO_METER",
+    .caps.sampleElementlen = sizeof(struct PressureData),
+    .caps.maxBatchCount = MAX_BATCH_COUNT,
+    .privateData = NULL,
+    .privateDataLen = 0,
+    .init = BaroMeterInit,
+    .deinit = BaroMeterDeInit,
+    .open = BaroMeterOpen,
+    .close = BaroMeterClose,
+    .read = BaroMeterRead,
+    .ioctl = BaroMeterIoctl
+};
+
+static struct PressureData g_baroMeterData = {
+    .pressure = 8,
+    .temperature = 9,
+    .dataValid = 0
+};
+
+static int32_t BaroMeterInit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterInit!");
+    g_baroMeterData.dataValid = 1;
+    return SENSOR_OK;
+}
+
+static int32_t BaroMeterDeInit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterDeInit!");
+    return SENSOR_OK;
+}
+
+static int32_t BaroMeterOpen(SensorPara *para)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterOpen!");
+    return SENSOR_OK;
+}
+
+static int32_t BaroMeterClose(void)
+{
+    g_baroMeterData.pressure = 0;
+    g_baroMeterData.temperature = 0;
+    g_baroMeterData.dataValid = 0;
+    HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterClose!");
+    return SENSOR_OK;
+}
+
+static int32_t BaroMeterRead(uint8_t *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterRead");
+    CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+    int32_t readLen = sizeof(struct PressureData);
+    int32_t ret = memcpy_s(data, len, &g_baroMeterData, readLen);
+    if (ret != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+        return -1;
+    }
+    g_baroMeterData.pressure++;
+    g_baroMeterData.temperature++;
+    return readLen;
+}
+
+static int32_t BaroMeterIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "BaroMeterIoctl!");
+    return SENSOR_OK;
+}
+
+static void BaroMeterHsensorRigister(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_baroMeterHsensor.type);
+    int32_t ret = SensorMgrRegistHsensor(&g_baroMeterHsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_baroMeterHsensor.type);
+        return;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_baroMeterHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(BaroMeterHsensorRigister, 3);
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/gyroscope/CMakeLists.txt b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/gyroscope/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d893a1b
--- /dev/null
@@ -0,0 +1,57 @@
+set(COMPONENT_NAME "sensor_hdi_gyroscope")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/gyroscope.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+set(AUTO_ADD_PATH
+    false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+    ${CDEFINES}
+)
+
+build_component()
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/gyroscope/gyroscope.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/gyroscope/gyroscope.c
new file mode 100644 (file)
index 0000000..b8845d4
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: gyroScope simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define ACCEL_MAX_BATCH_COUNT 10
+
+static int32_t GyroScopeInit(void);
+static int32_t GyroScopeDeinit(void);
+static int32_t GyroScopeOpen(SensorPara *para);
+static int32_t GyroScopeClose(void);
+static int32_t GyroScopeRead(uint8_t *data, uint32_t len);
+static int32_t GyroScopeIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_gyroScopeHsensor = {
+    .type = SENSOR_TYPE_GYROSCOPE,
+    .name = "GYRO_SCOPE",
+    .caps.sampleElementlen = sizeof(struct GyroData),
+    .caps.maxBatchCount = ACCEL_MAX_BATCH_COUNT,
+    .privateData = NULL,
+    .privateDataLen = 0,
+    .init = GyroScopeInit,
+    .deinit = GyroScopeDeinit,
+    .open = GyroScopeOpen,
+    .close = GyroScopeClose,
+    .read = GyroScopeRead,
+    .ioctl = GyroScopeIoctl
+};
+
+static struct GyroData g_gyroScopeData = {
+    .axisX = 8,
+    .axisY = 9,
+    .axisZ = 10
+};
+
+static int32_t GyroScopeInit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeInit!");
+    return SENSOR_OK;
+}
+
+static int32_t GyroScopeDeinit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeDeinit!");
+    return SENSOR_OK;
+}
+
+static int32_t GyroScopeOpen(SensorPara *para)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeOpen!");
+    return SENSOR_OK;
+}
+
+static int32_t GyroScopeClose(void)
+{
+    g_gyroScopeData.axisX = 0;
+    g_gyroScopeData.axisY = 0;
+    g_gyroScopeData.axisZ = 0;
+    HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeClose!");
+    return SENSOR_OK;
+}
+
+static int32_t GyroScopeRead(uint8_t *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeRead");
+    CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+    int32_t readLen = sizeof(struct GyroData);
+    int32_t ret = memcpy_s(data, len, &g_gyroScopeData, readLen);
+    if (ret != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+        return -1;
+    }
+    g_gyroScopeData.axisX++;
+    g_gyroScopeData.axisY++;
+    g_gyroScopeData.axisZ++;
+    return readLen;
+}
+
+static int32_t GyroScopeIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "GyroScopeIoctl!");
+    return SENSOR_OK;
+}
+
+static void GyroScopeHsensorRigister(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_gyroScopeHsensor.type);
+    int32_t ret = SensorMgrRegistHsensor(&g_gyroScopeHsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_gyroScopeHsensor.type);
+        return;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_gyroScopeHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(GyroScopeHsensorRigister, 3);
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/heart_rate_counter/CMakeLists.txt b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/heart_rate_counter/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1a16ec5
--- /dev/null
@@ -0,0 +1,57 @@
+set(COMPONENT_NAME "sensor_hdi_hr_counter")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/heart_rate_counter.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+set(AUTO_ADD_PATH
+    false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+    ${CDEFINES}
+)
+
+build_component()
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/heart_rate_counter/heart_rate_counter.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/heart_rate_counter/heart_rate_counter.c
new file mode 100644 (file)
index 0000000..8455206
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: heart rate simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define MAX_BATCH_COUNT 10
+#define DEFAULT_HEART_RATE 80
+
+static int32_t HeartRateInit(void);
+static int32_t HeartRateDeinit(void);
+static int32_t HeartRateOpen(SensorPara *para);
+static int32_t HeartRateClose(void);
+static int32_t HeartRateRead(uint8_t *data, uint32_t len);
+static int32_t HeartRateIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_heartRateHsensor = {
+    .type = SENSOR_TYPE_HEART_RATE,
+    .name = "HEART_RATE",
+    .caps.sampleElementlen = sizeof(int32_t),
+    .caps.maxBatchCount = MAX_BATCH_COUNT,
+    .privateData = NULL,
+    .privateDataLen = 0,
+    .init = HeartRateInit,
+    .deinit = HeartRateDeinit,
+    .open = HeartRateOpen,
+    .close = HeartRateClose,
+    .read = HeartRateRead,
+    .ioctl = HeartRateIoctl
+};
+
+static int32_t g_heartRate = 0;
+
+static int32_t HeartRateInit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "HeartRateInit!");
+    return SENSOR_OK;
+}
+
+static int32_t HeartRateDeinit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "HeartRateDeinit!");
+    return SENSOR_OK;
+}
+
+static int32_t HeartRateOpen(SensorPara *para)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "HeartRateOpen!");
+    g_heartRate = DEFAULT_HEART_RATE;
+    return SENSOR_OK;
+}
+
+static int32_t HeartRateClose(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "HeartRateClose!");
+    g_heartRate = 0;
+    return SENSOR_OK;
+}
+
+static int32_t HeartRateRead(uint8_t *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "HeartRateRead");
+    CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+    int32_t readLen = sizeof(int32_t);
+    int32_t ret = memcpy_s(data, len, &g_heartRate, readLen);
+    if (ret != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+        return -1;
+    }
+    g_heartRate++;
+    return readLen;
+}
+
+static int32_t HeartRateIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "HeartRateIoctl!");
+    return SENSOR_OK;
+}
+
+static void HeartRateHsensorRigister(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_heartRateHsensor.type);
+    int32_t ret = SensorMgrRegistHsensor(&g_heartRateHsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_heartRateHsensor.type);
+        return;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_heartRateHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(HeartRateHsensorRigister, 3);
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/pedometer/CMakeLists.txt b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/pedometer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..338fd9f
--- /dev/null
@@ -0,0 +1,57 @@
+set(COMPONENT_NAME "sensor_hdi_pedometer")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/pedometer.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+set(AUTO_ADD_PATH
+    false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+    ${CDEFINES}
+)
+
+build_component()
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/pedometer/pedometer.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/pedometer/pedometer.c
new file mode 100644 (file)
index 0000000..927aa32
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: pedometer simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define ACCEL_MAX_BATCH_COUNT 10
+
+static int32_t PedoMeterInit(void);
+static int32_t PedoMeterDeinit(void);
+static int32_t PedoMeterOpen(SensorPara *para);
+static int32_t PedoMeterClose(void);
+static int32_t PedoMeterRead(uint8_t *data, uint32_t len);
+static int32_t PedoMeterIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_pedoMeterHsensor = {
+    .type = SENSOR_TYPE_PEDOMETER,
+    .name = "PEDO_METER",
+    .caps.sampleElementlen = sizeof(int32_t),
+    .caps.maxBatchCount = ACCEL_MAX_BATCH_COUNT,
+    .privateData = NULL,
+    .privateDataLen = 0,
+    .init = PedoMeterInit,
+    .deinit = PedoMeterDeinit,
+    .open = PedoMeterOpen,
+    .close = PedoMeterClose,
+    .read = PedoMeterRead,
+    .ioctl = PedoMeterIoctl
+};
+
+static int32_t g_pedoMeterData = 0;
+
+static int32_t PedoMeterInit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterInit!");
+    return SENSOR_OK;
+}
+
+static int32_t PedoMeterDeinit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterDeinit!");
+    return SENSOR_OK;
+}
+
+static int32_t PedoMeterOpen(SensorPara *para)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterOpen!");
+    return SENSOR_OK;
+}
+
+static int32_t PedoMeterClose(void)
+{
+    g_pedoMeterData = 0;
+    HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterClose!");
+    return SENSOR_OK;
+}
+
+static int32_t PedoMeterRead(uint8_t *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterRead");
+    CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+    int32_t readLen = sizeof(int32_t);
+    int32_t ret = memcpy_s(data, len, &g_pedoMeterData, readLen);
+    if (ret != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+        return -1;
+    }
+    g_pedoMeterData++;
+    return readLen;
+}
+
+static int32_t PedoMeterIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "PedoMeterIoctl!");
+    return SENSOR_OK;
+}
+
+static void PedoMeterHsensorRigister(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_pedoMeterHsensor.type);
+    int32_t ret = SensorMgrRegistHsensor(&g_pedoMeterHsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_pedoMeterHsensor.type);
+        return;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_pedoMeterHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(PedoMeterHsensorRigister, 3);
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/wear_detection/CMakeLists.txt b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/wear_detection/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0e356bc
--- /dev/null
@@ -0,0 +1,57 @@
+set(COMPONENT_NAME "sensor_hdi_wear_detection")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+)
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/wear_detection.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+set(AUTO_ADD_PATH
+    false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+    ${CDEFINES}
+)
+
+build_component()
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/wear_detection/wear_detection.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/hsensor/wear_detection/wear_detection.c
new file mode 100644 (file)
index 0000000..5d734d0
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: wear detection simu
+ * Author: Media Software Group
+ * Create: 2025-09-25
+ */
+
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "sensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "ohos_init.h"
+
+#define ACCEL_MAX_BATCH_COUNT 10
+
+static int32_t WearDetectionInit(void);
+static int32_t WearDetectionDeinit(void);
+static int32_t WearDetectionOpen(SensorPara *para);
+static int32_t WearDetectionClose(void);
+static int32_t WearDetectionRead(uint8_t *data, uint32_t len);
+static int32_t WearDetectionIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+
+const static Hsensor g_wearDetectionHsensor = {
+    .type = SENSOR_TYPE_WEAR_DETECTION,
+    .name = "WEAR_DETECTION",
+    .caps.sampleElementlen = sizeof(bool),
+    .caps.maxBatchCount = ACCEL_MAX_BATCH_COUNT,
+    .privateData = NULL,
+    .privateDataLen = 0,
+    .init = WearDetectionInit,
+    .deinit = WearDetectionDeinit,
+    .open = WearDetectionOpen,
+    .close = WearDetectionClose,
+    .read = WearDetectionRead,
+    .ioctl = WearDetectionIoctl
+};
+
+static bool g_wearStatus = false;
+
+static int32_t WearDetectionInit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionInit!");
+    return SENSOR_OK;
+}
+
+static int32_t WearDetectionDeinit(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionDeinit!");
+    return SENSOR_OK;
+}
+
+static int32_t WearDetectionOpen(SensorPara *para)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionOpen!");
+    g_wearStatus = true;
+    return SENSOR_OK;
+}
+
+static int32_t WearDetectionClose(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionClose!");
+    g_wearStatus = false;
+    return SENSOR_OK;
+}
+
+static int32_t WearDetectionRead(uint8_t *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionRead");
+    CHECK_NULL_PTR_RETURN_VALUE(data, SENSOR_ERROR);
+    int32_t readLen = sizeof(bool);
+    int32_t ret = memcpy_s(data, len, &g_wearStatus, readLen);
+    if (ret != EOK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "memcpy_s err");
+        return -1;
+    }
+    return readLen;
+}
+
+static int32_t WearDetectionIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "WearDetectionIoctl!");
+    return SENSOR_OK;
+}
+
+static void WearDetectionHsensorRigister(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d !", g_wearDetectionHsensor.type);
+    int32_t ret = SensorMgrRegistHsensor(&g_wearDetectionHsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_wearDetectionHsensor.type);
+        return;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistHsensor type:%d SUCCESS!", g_wearDetectionHsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(WearDetectionHsensorRigister, 3);
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/vsensor/acc_alg_simulator/CMakeLists.txt b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/vsensor/acc_alg_simulator/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0c00c49
--- /dev/null
@@ -0,0 +1,58 @@
+set(COMPONENT_NAME "sensor_hdi_acc_alg_simulator")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+)
+
+set(PRIVATE_HEADER
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../../interfaces/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../../sensor_mgr/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/../common/include
+)
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/acc_alg_simulator.c
+)
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-error=unused-function
+)
+
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+set(AUTO_ADD_PATH
+    false
+)
+
+set(PUBLIC_DEFINES
+)
+
+set(CDEFINES ${CDEFINES} "CMSIS_SUPPORT")
+set(PRIVATE_DEFINES
+    ${CDEFINES}
+)
+
+build_component()
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/vsensor/acc_alg_simulator/acc_alg_simulator.c b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/vsensor/acc_alg_simulator/acc_alg_simulator.c
new file mode 100644 (file)
index 0000000..9fd2b75
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: accel vsensor simu
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#include "sensor_common.h"
+#include "vsensor_common.h"
+#include "securec.h"
+#include "sensor_manager.h"
+#include "sensor_log.h"
+#include "ohos_init.h"
+
+#define ACC_ALG_PERIOD_MS 100 // ms
+#define ACC_ALG_BATCH_COUNT 5
+
+#define ACC_ALG_OFFSET 10
+
+static int32_t AccAlgSimuDataCbRegister(RecordDataCallback cb);
+static int32_t AccAlgSimuDataCbUnRegister(RecordDataCallback cb);
+static int32_t AccAlgSimuOpen(SensorPara *para);
+static int32_t AccAlgSimuClose(void);
+static int32_t AccAlgSimuProcess(enum SensorTypeTag type, uint8_t *data, uint64_t ts, uint32_t len);
+static int32_t AccAlgSimuIoctl(SensorIoctlCmd cmd, void *data, uint32_t len);
+static int32_t AccAlgSimuGetData(SensorData *sensorData);
+
+typedef struct {
+    struct osal_list_head dataCbListHead; /* DataCallbackInfo head */
+    uint32_t dataCbNum;
+    uint32_t batchCount;
+    uint32_t timeStamp;
+    struct AccelData accAlgSimuData[ACC_ALG_BATCH_COUNT];
+} AccAlgSimuContext;
+
+const RelySensorInfo g_accAlgSimuRelySensor[] = {
+    {
+        .type = SENSOR_TYPE_ACCELEROMETER,
+        .param = {
+            .period = ACC_ALG_PERIOD_MS,
+            .batch = ACC_ALG_BATCH_COUNT,
+            .mode = SENSOR_MODE_REALTIME,
+            .option = 0
+        }
+    }
+};
+
+const RelySensorsInfo g_accAlgSimuRelySensors = {
+    .relySensorArray = (RelySensorInfo*)g_accAlgSimuRelySensor,
+    .relySensorCnt = sizeof(g_accAlgSimuRelySensor) / sizeof(RelySensorInfo)
+};
+
+const static Vsensor g_accAlgSimuVsensor = {
+    .type = SENSOR_TYPE_VSENSOR_ACCELEROMETER_ALG_SIMU,
+    .name = "ACCEL_ALG_SIMU",
+    .privateData = NULL,
+    .privateDataLen = 0,
+    .relySensors = (RelySensorsInfo*)&g_accAlgSimuRelySensors,
+    .registDataCb = AccAlgSimuDataCbRegister,
+    .unRegistDataCb = AccAlgSimuDataCbUnRegister,
+    .open = AccAlgSimuOpen,
+    .close = AccAlgSimuClose,
+    .process = AccAlgSimuProcess,
+    .ioctl = AccAlgSimuIoctl,
+};
+
+AccAlgSimuContext g_accAlgSimuCtx = {
+    .dataCbNum = 0,
+    .batchCount = 0,
+    .timeStamp = 0,
+    .accAlgSimuData = {0},
+};
+
+struct AccelData g_storeAccData[ACC_ALG_BATCH_COUNT] = {0};
+static uint32_t g_storeBatchCnt = 1;
+static uint32_t g_storeTimeStamp = 0;
+static int32_t AccAlgSimuDataCbRegister(RecordDataCallback cb)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "IN");
+    if (g_accAlgSimuCtx.dataCbNum == 0) {
+        OSAL_INIT_LIST_HEAD(&(g_accAlgSimuCtx.dataCbListHead));
+    }
+    DataCallbackInfo *dataCallbackInfoIndex = NULL;
+    osal_list_for_each_entry(dataCallbackInfoIndex, &g_accAlgSimuCtx.dataCbListHead, list)
+    {
+        if (cb == dataCallbackInfoIndex->dataCb) {
+            HILOG_INFO(HILOG_MODULE_SEN, "cb :%p is Registed");
+            return SENSOR_OK;
+        }
+    }
+    DataCallbackInfo *dataCallbackInfo = (DataCallbackInfo *)malloc(sizeof(DataCallbackInfo));
+    if (dataCallbackInfo == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "malloc DataCallbackInfo failed!");
+        return SENSOR_ERROR;
+    }
+    OSAL_INIT_LIST_HEAD(&(dataCallbackInfo->list));
+    dataCallbackInfo->dataCb = cb;
+    osal_list_add(&dataCallbackInfo->list, &g_accAlgSimuCtx.dataCbListHead);
+    g_accAlgSimuCtx.dataCbNum++;
+    return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuDataCbUnRegister(RecordDataCallback cb)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "IN");
+    DataCallbackInfo *dataCallbackInfoIndex = NULL;
+    DataCallbackInfo *dataCallbackInfo = NULL;
+    osal_list_for_each_entry(dataCallbackInfoIndex, &g_accAlgSimuCtx.dataCbListHead, list)
+    {
+        if (cb == dataCallbackInfoIndex->dataCb) {
+            dataCallbackInfo = dataCallbackInfoIndex;
+            HILOG_INFO(HILOG_MODULE_SEN, "cb is Registed");
+            break;
+        }
+    }
+    if (dataCallbackInfo == NULL) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "DataCallback not Registed!");
+        return SENSOR_ERROR;
+    }
+    osal_list_del(&dataCallbackInfo->list);
+    free(dataCallbackInfo);
+    g_accAlgSimuCtx.dataCbNum--;
+    return SENSOR_OK;
+}
+
+
+static int32_t AccAlgSimuOpen(SensorPara *para)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "IN");
+    return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuClose(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "IN");
+    for (uint32_t i = 0; i < ACC_ALG_BATCH_COUNT; i++) {
+        g_accAlgSimuCtx.accAlgSimuData[i].axisX = 0;
+        g_accAlgSimuCtx.accAlgSimuData[i].axisY = 0;
+        g_accAlgSimuCtx.accAlgSimuData[i].axisZ = 0;
+    }
+    return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuProcess(enum SensorTypeTag type, uint8_t *data, uint64_t ts, uint32_t len)
+{
+    HILOG_DEBUG(HILOG_MODULE_SEN, "Acc ALG Process ts :%llu len:%u!", ts, len);
+    uint32_t accelDataLen = sizeof(struct AccelData);
+    struct AccelData *orgAccelData = (struct AccelData*)data;
+    if (orgAccelData == NULL || (len % sizeof(struct AccelData)) != 0) {
+        HILOG_INFO(HILOG_MODULE_SEN, "Acc ALG Process :%llu invalid data!", ts);
+        return -1;
+    }
+    uint32_t batchCount = len / accelDataLen;
+    if (batchCount > ACC_ALG_BATCH_COUNT) {
+        HILOG_INFO(HILOG_MODULE_SEN, "Acc ALG Process :%llu invalid batchCount:%u!", ts, batchCount);
+        return -1;
+    }
+    for (uint32_t i = 0; i < batchCount; i++) {
+        g_accAlgSimuCtx.accAlgSimuData[i].axisX = orgAccelData[i].axisX + ACC_ALG_OFFSET;
+        g_accAlgSimuCtx.accAlgSimuData[i].axisY = orgAccelData[i].axisY + ACC_ALG_OFFSET;
+        g_accAlgSimuCtx.accAlgSimuData[i].axisZ = orgAccelData[i].axisZ + ACC_ALG_OFFSET;
+        g_storeAccData[i].axisX = orgAccelData[i].axisX + ACC_ALG_OFFSET;
+        g_storeAccData[i].axisY = orgAccelData[i].axisY + ACC_ALG_OFFSET;
+        g_storeAccData[i].axisZ = orgAccelData[i].axisZ + ACC_ALG_OFFSET;
+    }
+    g_accAlgSimuCtx.batchCount = batchCount;
+    g_accAlgSimuCtx.timeStamp = ts;
+    g_storeTimeStamp = g_accAlgSimuCtx.timeStamp;
+    g_storeBatchCnt = g_accAlgSimuCtx.batchCount;
+    DataCallbackInfo *dataCallbackInfoIndex = NULL;
+    osal_list_for_each_entry(dataCallbackInfoIndex, &g_accAlgSimuCtx.dataCbListHead, list)
+    {
+        struct SensorEvents sensorEvent = {
+            .sensorId = type,
+            .version = 0,
+            .timestamp = ts,
+            .option = 0,
+            .mode = 0,
+            .data = (uint8_t *)g_accAlgSimuCtx.accAlgSimuData,
+            .dataLen = len,
+        };
+        dataCallbackInfoIndex->dataCb(&sensorEvent);
+    }
+    return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuIoctl(SensorIoctlCmd cmd, void *data, uint32_t len)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "AccAlgSimuIoctl!");
+    switch (cmd) {
+        case SENSOR_IOCTL_GET_SENSOR_DATA:
+            AccAlgSimuGetData((SensorData *)data);
+            break;
+        default:
+            return SENSOR_ERROR;
+    }
+    return SENSOR_OK;
+}
+
+static int32_t AccAlgSimuGetData(SensorData *sensorData)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "AccAlgSimuGetData!");
+    sensorData->data = (uint8_t *)(g_storeAccData);
+    size_t len = sizeof(struct AccelData);
+    sensorData->dataLen = (uint32_t)len;
+    sensorData->batchCnt = g_storeBatchCnt;
+    sensorData->timestamp = g_storeTimeStamp;
+    HILOG_INFO(HILOG_MODULE_SEN,
+        "SensorData datalen:%u batchcnt:%u timestamp:%lld",
+        sensorData->dataLen,
+        sensorData->batchCnt,
+        sensorData->timestamp);
+    return SENSOR_OK;
+}
+
+static void AccAlgSimuVsensorRegister(void)
+{
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistVsensor type:%d in !", g_accAlgSimuVsensor.type);
+    int32_t ret = SensorMgrRegistVsensor(&g_accAlgSimuVsensor);
+    if (ret != SENSOR_OK) {
+        HILOG_ERROR(HILOG_MODULE_SEN, "RegistHsensor type:%d ERR!", g_accAlgSimuVsensor.type);
+        return;
+    }
+    HILOG_INFO(HILOG_MODULE_SEN, "RegistVsensor type:%d SUCCESS!", g_accAlgSimuVsensor.type);
+}
+
+APP_FEATURE_INIT_PRI(AccAlgSimuVsensorRegister, 4);
diff --git a/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/vsensor/common/include/vsensor_common.h b/code/sdk/open_source/openharmony/drivers/peripheral/sensor/hal_lite/sensors/vsensor/common/include/vsensor_common.h
new file mode 100644 (file)
index 0000000..38889be
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: vsensor common
+ * Author: Media Software Group
+ * Create: 2025-06-06
+ */
+
+#ifndef HDI_V_SENSOR_COMMON_H
+#define HDI_V_SENSOR_COMMON_H
+
+#include <stdio.h>
+#include "sensor_typedef.h"
+#include "sensor_log.h"
+#include "soc_osal.h"
+
+typedef struct {
+    struct osal_list_head list;          /* link point */
+    RecordDataCallback dataCb;
+} DataCallbackInfo;
+
+#endif /* HDI_V_SENSOR_COMMON_H */
index f08e962..18b637e 100644 (file)
@@ -82,7 +82,7 @@ struct SensorInterface {
      * @since 2.2
      * @version 1.0
      */
-    int32_t (*Enable)(int32_t sensorTypeId);
+    int32_t (*Enable)(int32_t sensorId);
 
     /**
      * @brief Disables an enabled sensor.
@@ -93,7 +93,7 @@ struct SensorInterface {
      * @since 2.2
      * @version 1.0
      */
-    int32_t (*Disable)(int32_t sensorTypeId);
+    int32_t (*Disable)(int32_t sensorId);
 
     /**
      * @brief Sets the data sampling interval and data reporting interval for the specified sensor.
@@ -106,7 +106,7 @@ struct SensorInterface {
      * @since 2.2
      * @version 1.0
      */
-    int32_t (*SetBatch)(int32_t sensorTypeId, int64_t samplingInterval, int64_t reportInterval);
+    int32_t (*SetBatch)(int32_t sensorId, int64_t samplingInterval, int64_t reportInterval);
 
     /**
      * @brief Sets the data reporting mode for the specified sensor.
@@ -119,7 +119,7 @@ struct SensorInterface {
      * @since 2.2
      * @version 1.0
      */
-    int32_t (*SetMode)(int32_t sensorTypeId, int32_t mode);
+    int32_t (*SetMode)(int32_t sensorId, int32_t mode);
 
     /**
      * @brief Sets options for the specified sensor, including its measurement range and accuracy.
@@ -131,11 +131,16 @@ struct SensorInterface {
      * @since 2.2
      * @version 1.0
      */
-    int32_t (*SetOption)(int32_t sensorTypeId, uint32_t option);
+    int32_t (*SetOption)(int32_t sensorId, uint32_t option);
 
     /**
      * @brief Registers the callback for reporting sensor data to the subscriber.
      *
+     * @param sensorTypeId Indicates the sensor group ID.
+     * The sensorId enumeration value range is 128-160, which means that the medical sensor service is subscribed.
+     * It only needs to be subscribed once successfully, and there is no need to subscribe repeatedly.
+     * The sensorId enumeration value range is not within 128-160, which means that the traditional sensor
+     * is subscribed, and the subscription is successful once.
      * @param cb Indicates the callback to register. For details, see {@link RecordDataCallback}.
      * @return Returns <b>0</b> if the callback is successfully registered; returns a negative value otherwise.
      *
@@ -147,12 +152,56 @@ struct SensorInterface {
     /**
      * @brief Deregisters the callback for reporting sensor data.
      *
+     * @param sensorTypeId Indicates the sensor group ID.
+     * The sensorId enumeration value range is 128-160, which means that the medical sensor service is subscribed.
+     * It only needs to cancel the subscription once successfully, and there is no need to
+     * cancel the subscription repeatedly. The sensorId enumeration value range is not within 128-160,
+     * which means that the traditional sensor is subscribed. You can cancel the subscription once successfully.
+     * @param cb Indicates the callback to register. For details, see {@link RecordDataCallback}.
      * @return Returns <b>0</b> if the callback is successfully deregistered; returns a negative value otherwise.
      *
      * @since 2.2
      * @version 1.0
      */
     int32_t (*Unregister)(int32_t sensorTypeId, RecordDataCallback cb);
+
+    /**
+     * @brief Obtain the sensor event data in the small system.
+     *
+     * @param sensorId Indicates the sensor ID. For details, see {@link SensorTypeTag}.
+     * @param event Indicates the vector of the sensor event data in the system.
+     * The sensor event data includes the sensor ID, sensor algorithm version, data generation time,
+     * data options (such as the measurement range and accuracy), data reporting mode, data address, and data length.
+     * For details, see {@link HdfSensorEvents}.
+     * @return Returns <b>0</b> if the event data is obtained; returns a negative value otherwise.
+     *
+     * @since 2.2
+     * @version 1.0
+     */
+    int32_t (*ReadData)(int32_t sensorId, struct SensorEvents *event);
+
+    /**
+     * @brief Obtain sensor information for SDC
+     *
+     * @param sdcSensorInfo Indicates the data of the SDC type.
+     * @return Returns <b>0</b> if the event data is obtained; returns a negative value otherwise.
+     *
+     * @since 4.1
+     * @version 2.0
+     */
+    int32_t (*GetSdcSensorInfo)(struct SdcSensorInfo sdcSensorInfo[]);
+    // ohos-hisi begin
+    /**
+    * @brief Get the data of the specified sensor stored.
+    *
+    * @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.
+    * @param sensorData Indicates the data of sensor stored For details, see {@link SensorData}.
+    * @return Returns <b>0</b> if get sensor data successfully; returns a non-zero value otherwise.
+    *
+    * @since 5
+    */
+    int32_t (*GetSensorData)(int32_t sensorTypeId, SensorData *sensorData);
+    // ohos-hisi end
 };
 
 /**
index f256d22..1e45713 100644 (file)
@@ -48,7 +48,12 @@ extern "C" {
 #endif
 #endif /* __cplusplus */
 
-#define SENSOR_NAME_MAX_LEN       16 /**< Maximum length of the sensor name */
+// ohos-hisi begin
+// avoid redefined for SENSOR_NAME_MAX_LEN by liteos_m
+#ifndef SENSOR_NAME_MAX_LEN
+#define SENSOR_NAME_MAX_LEN       32 /**< Maximum length of the sensor name */
+#endif /* SENSOR_NAME_MAX_LEN */
+// ohos-hisi end
 #define SENSOR_VERSION_MAX_LEN    16 /**< Maximum length of the sensor version */
 
 /**
@@ -85,6 +90,13 @@ enum SensorTypeTag {
     SENSOR_TYPE_GESTURE             = 11,  /**< Gesture sensor */
     SENSOR_TYPE_PROXIMITY           = 12,  /**< Proximity sensor */
     SENSOR_TYPE_HUMIDITY            = 13,  /**< Humidity sensor */
+    SENSOR_TYPE_COLOR               = 14,  /**< Color sensor */
+    SENSOR_TYPE_SAR                 = 15,  /**< SAR sensor */
+    SENSOR_TYPE_AMBIENT_LIGHT1      = 16,  /**< Secondary ambient light sensor*/
+    SENSOR_TYPE_HALL1               = 17,  /**< Secondary hall effect sensor */
+    SENSOR_TYPE_PROXIMITY1          = 18,  /**< Secondary proximity sensor */
+    SENSOR_TYPE_MEDICAL_BEGIN       = 128, /**< The begin of medical sensorId enumeration value range */
+    SENSOR_TYPE_MEDICAL_END         = 160, /**< The end of medical sensorId enumeration value range */
     SENSOR_TYPE_PHYSICAL_MAX        = 255, /**< Maximum type of a physical sensor */
     SENSOR_TYPE_ORIENTATION         = 256, /**< Orientation sensor */
     SENSOR_TYPE_GRAVITY             = 257, /**< Gravity sensor */
@@ -97,12 +109,22 @@ enum SensorTypeTag {
     SENSOR_TYPE_SIGNIFICANT_MOTION          = 264,   /**< Significant motion sensor */
     SENSOR_TYPE_PEDOMETER_DETECTION         = 265,   /**< Pedometer detection sensor */
     SENSOR_TYPE_PEDOMETER                   = 266,   /**< Pedometer sensor */
+    SENSOR_TYPE_POSTURE                     = 267,   /**< Posture sensor */
+    SENSOR_TYPE_HEADPOSTURE                 = 268,   /**< Headposture sensor */
+    SENSOR_TYPE_DROP_DETECT                 = 269,   /**< Drop detection sensor */
     SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR = 277,   /**< Geomagnetic rotation vector sensor */
     SENSOR_TYPE_HEART_RATE                  = 278,   /**< Heart rate sensor */
     SENSOR_TYPE_DEVICE_ORIENTATION          = 279,   /**< Device orientation sensor */
     SENSOR_TYPE_WEAR_DETECTION              = 280,   /**< Wear detection sensor */
     SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED  = 281,   /**< Uncalibrated acceleration sensor */
-    SENSOR_TYPE_MAX                         = 0xFFF, /**< Maximum number of sensor types */
+    SENSOR_TYPE_RPC                         = 282,   /**< Radio Power Control */
+       // ohos-hisi begin
+    SENSOR_TYPE_VSENSOR_EXPAND_START        = 0x1000,   /* 4096 */
+    SENSOR_TYPE_VSENSOR_ACCELEROMETER_ALG_SIMU,         /**< ACCELEROMETER ALG sensor */
+    SENSOR_TYPE_VSENSOR_WEAR_ALG,                       /**< WEAR ALG sensor */
+    SENSOR_TYPE_VSENSOR_PRESS_ALG,                      /**< PRESS ALG sensor */
+       // ohos-hisi end
+    SENSOR_TYPE_MAX,                                 /**< Maximum number of sensor types */
 };
 
 /**
@@ -145,39 +167,14 @@ enum SensorModeType {
 };
 
 /**
- * @brief 加速度传感器的数据结构
- */
-struct AccelData {
-    /** 加速度X轴 */
-    int16_t axisX;
-    /** 加速度Y轴 */
-    int16_t axisY;
-    /** 加速度Z轴 */
-    int16_t axisZ;
-};
-
-/**
- * @brief 角速度传感器的数据结构
- */
-struct GyroData {
-    /** 加速度X轴 */
-    int16_t axisX;
-    /** 加速度Y轴 */
-    int16_t axisY;
-    /** 加速度Z轴 */
-    int16_t axisZ;
-};
-
-/**
- * @brief 气压传感器的数据结构
+ * @brief Enumerates hardware service group for sensors
+ *
+ * @since 2.2
  */
-struct PressureData {
-    /** 气压计气压值 */
-    uint32_t pressure;
-    /** 气压计温度值 */
-    uint32_t temperature;
-    /** 气压计数据有效性 */
-    uint32_t dataValid;
+enum SensorGroupType {
+    TRADITIONAL_SENSOR_TYPE = 0, /**< traditional sensor type, the sensorId enumeration value range is 128-160 */
+    MEDICAL_SENSOR_TYPE = 1,  /**< medical sensor type, the sensorId enumeration value range is not within 128-160 */
+    SENSOR_GROUP_TYPE_MAX,          /**< Maximum sensor type*/
 };
 
 /**
@@ -198,6 +195,10 @@ struct SensorInformation {
     float maxRange;       /**< Maximum measurement range of the sensor */
     float accuracy;       /**< Sensor accuracy */
     float power;          /**< Sensor power */
+    int64_t minDelay;     /**< Minimum sample period allowed in microseconds */
+    int64_t maxDelay;     /**< Maxmum sample period allowed in microseconds */
+    uint32_t fifoMaxEventCount; /**< Maxmum number of events of this sensor that could be batched */
+    uint32_t reserved;    /**< Reserved fields */
 };
 
 /**
@@ -218,6 +219,73 @@ struct SensorEvents {
     uint32_t dataLen;  /**< Sensor data length */
 };
 
+/**
+ * @brief Defines SDC reports data object operations to the node.
+ *
+ * The reported sensor data includes the offset, type, ddrSize, minRateLevel, maxRateLevel, reserved, memAddr.
+ *
+ * @since 4.1
+ */
+struct SdcSensorInfo {
+    uint64_t offset;
+    int32_t sensorId;
+    int32_t ddrSize;
+    int32_t minRateLevel;
+    int32_t maxRateLevel;
+    uint64_t memAddr;
+    int32_t reserved;
+};
+
+// ohos-hisi begin
+/**
+ * @brief Accelerometer sensor data structure
+ */
+struct AccelData {
+    /** Accelerometer data X-axis */
+    int16_t axisX;
+    /** Accelerometer data Y-axis */
+    int16_t axisY;
+    /** Accelerometer data Z-axis */
+    int16_t axisZ;
+};
+ 
+/**
+ * @brief Gyro sensor data structure
+ */
+struct GyroData {
+    /** Gyro data X-axis */
+    int16_t axisX;
+    /** Gyro data Y-axis */
+    int16_t axisY;
+    /** Gyro data Z-axis */
+    int16_t axisZ;
+};
+ 
+/**
+ * @brief Pressure sensor data structure
+ */
+struct PressureData {
+    /** pressure value */
+    uint32_t pressure;
+    /** temperature value */
+    uint32_t temperature;
+    /** Data Validity */
+    uint32_t dataValid;
+};
+
+/**
+ * @brief Defines the sensor data.
+ *
+ * @since 5
+ */
+typedef struct SensorData {
+    int64_t timestamp;     /**< Time when sensor data was reported */
+    uint32_t batchCnt;     /**< Sensor batch cnt */
+    uint8_t *data;         /**< Sensor data */
+    uint32_t dataLen;      /**< Sensor data length */
+} SensorData;
+// ohos-hisi end
+
 /**
  * @brief Defines the callback for reporting sensor data. This callback needs to be registered when
  * a sensor user subscribes to sensor data. Only after the sensor is enabled, the sensor data subscriber can receive
index 084a0fa..058255d 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-auto-ota-cli/libams.a and b/code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-auto-ota-cli/libams.a differ
index ea7325c..2055618 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-auto-ota-ser/libams.a and b/code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-auto-ota-ser/libams.a differ
index b294a76..203d8c9 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-native-js/libams.a and b/code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-native-js/libams.a differ
index a4d2638..612e348 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-xts/libams.a and b/code/sdk/open_source/openharmony/foundation/aafwk/aafwk_lite/brandy-xts/libams.a differ
index 6e76b8c..2cfe47a 100644 (file)
@@ -31,6 +31,7 @@ set(PRIVATE_HEADER
     ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/utils/innerkits
     ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include
     ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/service
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/components
     ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
     ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/components
     ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/animator
@@ -48,6 +49,7 @@ set(PRIVATE_HEADER
     ${ROOT_DIR}/application/wearable/ohos_deps
     ${ROOT_DIR}/application/wearable/nativeabilityfwk/include
     ${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include
+    ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include
     ${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector/libs
     ${ROOT_DIR}/open_source/openharmony/third_party/cJSON
     ${ROOT_DIR}/open_source/openharmony/third_party/qrcodegen/cpp
@@ -179,6 +181,7 @@ set(PUBLIC_HEADER
 )
 
 set(PRIVATE_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext
     ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
     ${CMAKE_CURRENT_SOURCE_DIR}/animation
     ${CMAKE_CURRENT_SOURCE_DIR}/base
@@ -198,8 +201,10 @@ set(PRIVATE_HEADER
     ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/utils/innerkits
     ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include
     ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/service
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/components
     ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
-
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/connection_manage
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/ui/innerkits
     ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/components
     ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/animator
     ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits
@@ -217,6 +222,7 @@ set(PRIVATE_HEADER
     ${ROOT_DIR}/application/wearable/ohos_deps
     ${ROOT_DIR}/application/wearable/nativeabilityfwk/include
     ${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include
+    ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include
     ${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector/libs
     ${ROOT_DIR}/open_source/openharmony/third_party/cJSON
     ${ROOT_DIR}/open_source/openharmony/third_party/qrcodegen/cpp
@@ -228,6 +234,7 @@ set(PRIVATE_HEADER
     ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network
     ${ROOT_DIR}/open_source/openharmony/base/sensors/location/interfaces/kits/include
     ${ROOT_DIR}/open_source/openharmony/base/sensors/interfaces/kits/native/include
+    ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter
 )
 
 if("JS_ENABLE" IN_LIST DEFINES)
@@ -267,6 +274,8 @@ set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/device_module.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/nativeapi_ohos_deviceinfo.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/network/network_module.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/network/network_listener.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/network/connection_manage/connection_manage.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/nfc_module.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/vibrator_module.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/battery_module.cpp
@@ -328,9 +337,134 @@ set(MAIN_COMPONENT
 )
 
 set(PUBLIC_DEFINES
+    FEATURE_COMPONENT_LISTEXT
+    FEATURE_COMPONENT_SCROLL
+)
+
+set(PRIVATE_DEFINES
+    ENABLE_LOCATION
+)
+
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/include" "*")
+
+build_component()
+
+set(COMPONENT_NAME "ace_ext")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+
+set(PUBLIC_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/async
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/jsi
+    ${CMAKE_CURRENT_SOURCE_DIR}/
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/context
+)
+
+set(PRIVATE_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/animation
+    ${CMAKE_CURRENT_SOURCE_DIR}/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/base/cache
+    ${CMAKE_CURRENT_SOURCE_DIR}/components
+    ${CMAKE_CURRENT_SOURCE_DIR}/context
+    ${CMAKE_CURRENT_SOURCE_DIR}/directive
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/context
+    ${CMAKE_CURRENT_SOURCE_DIR}/jsi
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/presets
+    ${CMAKE_CURRENT_SOURCE_DIR}/router
+    ${CMAKE_CURRENT_SOURCE_DIR}/stylemgr
+    ${CMAKE_CURRENT_SOURCE_DIR}/targets
+    ${ROOT_DIR}/application/wearable/service/msg_center/include/vendor_app
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/utils/innerkits
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/service
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/components
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
+
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/ui/innerkits
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/components
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/animator
+    ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits
+    ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits
+    ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits/gfx_utils
+    ${ROOT_DIR}/middleware/services/gui/uikit/surface/interfaces/kits
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/layout
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits/common
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/font
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/dfx
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/common
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/frameworks
+    ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${ROOT_DIR}/application/wearable/nativeabilityfwk/include
+    ${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include
+    ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include
+    ${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector/libs
+    ${ROOT_DIR}/open_source/openharmony/third_party/cJSON
+    ${ROOT_DIR}/open_source/openharmony/third_party/qrcodegen/cpp
+    ${ROOT_DIR}/open_source/openharmony/base/global/i18n_lite/frameworks/i18n/include
+    ${ROOT_DIR}/open_source/openharmony/base/global/i18n_lite/interfaces/kits/i18n/include
+    ${ROOT_DIR}/open_source/openharmony/base/global/resmgr_lite/frameworks/resmgr_lite/include
+    ${ROOT_DIR}/open_source/openharmony/base/global/resmgr_lite/interfaces/innerkits/include
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/keyinput
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network
+    ${ROOT_DIR}/open_source/openharmony/base/sensors/location/interfaces/kits/include
+    ${ROOT_DIR}/open_source/openharmony/base/sensors/interfaces/kits/native/include
+    ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter
+)
+
+if("JS_ENABLE" IN_LIST DEFINES)
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext/menu_item_component.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext/list_ext_component.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext/scroll_component.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ace_ext/list_adapter_ext.cpp
+)
+
+endif()
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+    -std=c++11
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-c++11-narrowing
+    -Wno-error=unused-function
+)
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+set(PUBLIC_DEFINES
+    FEATURE_COMPONENT_LISTEXT
+    FEATURE_COMPONENT_SCROLL
 )
 
 set(PRIVATE_DEFINES
+    ENABLE_LOCATION
 )
 
 install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
@@ -509,6 +643,67 @@ install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/include" "*")
 
 build_component()
 
+set(COMPONENT_NAME "ace_ble")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+ 
+set(PUBLIC_HEADER
+)
+ 
+set(PRIVATE_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/bluetooth
+    ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include/bluetooth
+    ${ROOT_DIR}/middleware/services/bts/ble
+    ${ROOT_DIR}/middleware/services/bts/br
+)
+ 
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_common.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_gattc_callback.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_discover.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_advertise.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module_scan.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/bluetooth/ble_module.cpp
+)
+ 
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+ 
+set(COMPONENT_CCFLAGS
+    -std=c++11
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-c++11-narrowing
+    -Wno-error=unused-function
+)
+ 
+set(WHOLE_LINK
+    true
+)
+ 
+set(MAIN_COMPONENT
+   false
+)
+ 
+set(PRIVATE_DEFINES
+)
+ 
+set(PUBLIC_DEFINES
+    FEATURE_MODULE_BLE
+)
+ 
+build_component()
+
 set(COMPONENT_NAME "netstack_http")
 set(MODULE_NAME "ohos")
 set(AUTO_DEF_FILE_ID TRUE)
@@ -528,6 +723,7 @@ set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/netstack/http/src/http_api.c
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/netstack/http/src/http_client.c
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/netstack/http/src/http_wrapper.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/netstack/http/src/http_form_data.c
 )
 
 set(COMPONENT_PUBLIC_CCFLAGS
@@ -562,6 +758,8 @@ set(PUBLIC_DEFINES
 )
 
 set(PRIVATE_DEFINES
+    CONFIG_HTTP_FORM_DATA
+    CONFIG_HTTP_FILE_OPERATE
 )
 
 install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
@@ -578,15 +776,19 @@ set(PUBLIC_HEADER
  
 set(PRIVATE_HEADER
     ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
-    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/net
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http
     ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/http/include
     ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include
     ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include
     ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter
+    ${ROOT_DIR}/open_source/openharmony/utils/native/lite/js/builtin/filekit/include
+    ${ROOT_DIR}/open_source/openharmony/utils/native/lite/js/builtin/common/include
 )
  
 set(SOURCES
-    ${CMAKE_CURRENT_SOURCE_DIR}/modules/net/http_module.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/http/http_module.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/http/http_module_client.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/http/http_module_callback.cpp
 )
  
 set(COMPONENT_PUBLIC_CCFLAGS
@@ -638,7 +840,7 @@ set(PUBLIC_HEADER
 
 set(PRIVATE_HEADER
     ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
-    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/net
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http
     ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/include
     ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include
     ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include
@@ -647,6 +849,8 @@ set(PRIVATE_HEADER
 
 set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/modules/websocket/websocket_module.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/websocket/websocket_module_client.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/websocket/websocket_module_callback.cpp
 )
 
 set(COMPONENT_PUBLIC_CCFLAGS
@@ -698,6 +902,7 @@ set(PUBLIC_HEADER
 
 set(PRIVATE_HEADER
     ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/include
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal
     ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_v2.1.3/src/include
     ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include
     ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter
@@ -748,4 +953,184 @@ set(PRIVATE_DEFINES
 install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
 install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/include" "*")
 
+build_component()
+ 
+set(COMPONENT_NAME "ace_watchface")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+ 
+set(PUBLIC_HEADER
+)
+ 
+set(PRIVATE_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/watchface
+    ${ROOT_DIR}/open_source/openharmony/utils/native/lite/js/builtin/filekit/include
+    ${ROOT_DIR}/open_source/openharmony/utils/native/lite/js/builtin/common/include
+    ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include/main/dial/
+    ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/format/interfaces/include/
+)
+ 
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/watchface/watchface_module.cpp
+)
+ 
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+ 
+set(COMPONENT_CCFLAGS
+    -std=c++11
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-c++11-narrowing
+    -Wno-error=unused-function
+)
+ 
+set(WHOLE_LINK
+    true
+)
+ 
+set(MAIN_COMPONENT
+   false
+)
+ 
+set(PUBLIC_DEFINES
+    FEATURE_MODULE_WATCHFACE
+)
+ 
+set(PRIVATE_DEFINES
+)
+ 
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/include" "*")
+
+build_component()
+ 
+set(COMPONENT_NAME "ace_calendar")
+set(MODULE_NAME "ohos")
+set(AUTO_DEF_FILE_ID TRUE)
+ 
+set(PUBLIC_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/async
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/jsi
+    ${CMAKE_CURRENT_SOURCE_DIR}/
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/context
+)
+ 
+set(PRIVATE_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/interfaces/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/animation
+    ${CMAKE_CURRENT_SOURCE_DIR}/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/base/cache
+    ${CMAKE_CURRENT_SOURCE_DIR}/components
+    ${CMAKE_CURRENT_SOURCE_DIR}/context
+    ${CMAKE_CURRENT_SOURCE_DIR}/directive
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/base
+    ${CMAKE_CURRENT_SOURCE_DIR}/include/context
+    ${CMAKE_CURRENT_SOURCE_DIR}/jsi
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/presets
+    ${CMAKE_CURRENT_SOURCE_DIR}/router
+    ${CMAKE_CURRENT_SOURCE_DIR}/stylemgr
+    ${CMAKE_CURRENT_SOURCE_DIR}/targets
+    ${ROOT_DIR}/application/wearable/service/msg_center/include/vendor_app
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/utils/innerkits
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/service
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/include/components
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
+ 
+    ${ROOT_DIR}/middleware/services/gui/uikit/proprietary/src/ui/innerkits
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/components
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/animator
+    ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/innerkits
+    ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits
+    ${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits/gfx_utils
+    ${ROOT_DIR}/middleware/services/gui/uikit/surface/interfaces/kits
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/layout
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits/common
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/font
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/dfx
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/kits/common
+    ${ROOT_DIR}/middleware/services/gui/uikit/ui/frameworks
+    ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include
+    ${ROOT_DIR}/application/wearable/ohos_deps
+    ${ROOT_DIR}/application/wearable/nativeabilityfwk/include
+    ${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include
+    ${ROOT_DIR}/application/wearable/nativeapp/nativeui/include
+    ${ROOT_DIR}/application/wearable/service/xiaodu_navi_vector/libs
+    ${ROOT_DIR}/open_source/openharmony/third_party/cJSON
+    ${ROOT_DIR}/open_source/openharmony/third_party/qrcodegen/cpp
+    ${ROOT_DIR}/open_source/openharmony/base/global/i18n_lite/frameworks/i18n/include
+    ${ROOT_DIR}/open_source/openharmony/base/global/i18n_lite/interfaces/kits/i18n/include
+    ${ROOT_DIR}/open_source/openharmony/base/global/resmgr_lite/frameworks/resmgr_lite/include
+    ${ROOT_DIR}/open_source/openharmony/base/global/resmgr_lite/interfaces/innerkits/include
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/keyinput
+    ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network
+    ${ROOT_DIR}/open_source/openharmony/base/sensors/location/interfaces/kits/include
+    ${ROOT_DIR}/open_source/openharmony/base/sensors/interfaces/kits/native/include
+    ${ROOT_DIR}/application/wearable/service/msg_center/include/client
+)
+ 
+if("JS_ENABLE" IN_LIST DEFINES)
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/calendarManager/calendar_manager.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/calendarManager/calendar_timer.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/calendarManager/calendar_module.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/modules/calendarManager/event_id_manager.cpp
+)
+ 
+endif()
+ 
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+ 
+set(COMPONENT_CCFLAGS
+    -std=c++11
+    -Wno-error
+    -Wno-unused-parameter
+    -fno-exceptions
+    -fno-unwind-tables
+    -fno-asynchronous-unwind-tables
+    -Wno-undef
+    -Wno-bitwise-op-parentheses
+    -Wno-shift-op-parentheses
+    -nostdlibinc
+    -nostdinc
+    -nostdlib
+    -Wno-c++11-narrowing
+    -Wno-error=unused-function
+)
+ 
+set(WHOLE_LINK
+    true
+)
+ 
+set(MAIN_COMPONENT
+    false
+)
+ 
+set(PUBLIC_DEFINES
+    ENABLE_MODULE_CALENDAR
+)
+ 
+set(PRIVATE_DEFINES
+)
+ 
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/interfaces" "*")
+install_sdk_by_sh("${CMAKE_CURRENT_SOURCE_DIR}/include" "*")
+ 
 build_component()
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/list_adapter_ext.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/list_adapter_ext.h
new file mode 100644 (file)
index 0000000..ef85bff
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2024-2025. All rights reserved.
+ * Description: ace_ext listadapter
+ * Author: SoftwarePlatform Group
+ * Create: 2024-08-10
+ */
+
+#ifndef OHOS_ACELITE_LIST_ADAPTER_EXT_H
+#define OHOS_ACELITE_LIST_ADAPTER_EXT_H
+
+#include <string>
+#include <vector>
+#include "text_component.h"
+
+namespace OHOS {
+namespace ACELite {
+
+class ListAdapterExt {
+public:
+    ListAdapterExt();
+
+    ~ListAdapterExt();
+
+    static void SetItemAdaptive(bool isItemAdaptive);
+
+    static bool GetItemAdaptive();
+
+    static void SetListValue(char *text);
+
+    static void SetItemIndex(int16_t index);
+
+    static int16_t GetItemIndex();
+
+    static int16_t BuildItemAdaptive(Component *component, int16_t index);
+
+    static void CleanVector();
+
+    static void CleanString();
+
+    static void CleanAll();
+
+private:
+    static int16_t CalculateItems(UILabel *uiLable, int16_t index);
+    static bool isItemAdaptive_;
+    static int16_t itemIndex_;
+    static std::vector<std::string> strings_;
+    static std::string all_;
+};
+}  // namespace ACELite
+}  // namespace OHOS
+#endif // OHOS_ACELITE_LIST_ADAPTER_EXT_H
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/list_ext_component.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/list_ext_component.h
new file mode 100644 (file)
index 0000000..fc86255
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: ace scale-list
+ * Author: SoftwarePlatform Group
+ * Create: 2025-08-8
+ */
+
+#ifndef OHOS_ACELITE_LIST_EXT_COMPONENT_H
+#define OHOS_ACELITE_LIST_EXT_COMPONENT_H
+
+#include "component.h"
+#include "list_adapter.h"
+#include "ui_transform_list.h"
+
+namespace OHOS {
+namespace ACELite {
+class ListExtComponent final : public Component {
+public:
+    ACE_DISALLOW_COPY_AND_MOVE(ListExtComponent);
+    ListExtComponent() = delete;
+    ListExtComponent(JSValue options, JSValue children, AppStyleManager *styleManager);
+    ~ListExtComponent() override {}
+
+protected:
+    bool CreateNativeViews() override;
+    void ReleaseNativeViews() override;
+    UIView *GetComponentRootView() const override;
+    bool ApplyPrivateStyle(const AppStyleItem* style) override;
+    bool RegisterPrivateEventListener(uint16_t eventTypeId, JSValue funcValue, bool isStopPropagation) override;
+    bool SetPrivateAttribute(uint16_t attrKeyId, jerry_value_t attrValue) override;
+    bool ProcessChildren() override;
+    void OnViewAttached() override;
+    bool UpdateForView() override;
+
+private:
+    UITransformList list_;
+    ListAdapter adapter_;
+    ListEventListener listEventListener_;
+    static const char * const FUNC_SCROLLTO;
+    static const char * const INDEX_SCROLLTO;
+
+    int16_t scaleFactor_;
+    UIView::ViewExtraMsg scaleMsg_;
+    static bool ScaleListItem(UITransformList* list, UIView* item);
+
+    static const char * const FUNC_SCROLLTO_END;
+    static JSValue ListScrollTo(const JSValue func, const JSValue dom, const JSValue args[], const jerry_length_t size);
+    static JSValue ListScrollToEnd(const JSValue func, const JSValue dom, const JSValue args[], const jerry_length_t size);
+    void ComputeListLength();
+    static JSValue ListScroll(const JSValue func, const JSValue dom, const JSValue args[], const jerry_length_t size);
+};
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // OHOS_ACELITE_LIST_EXT_COMPONENT_H
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/menu_item_component.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/menu_item_component.h
new file mode 100644 (file)
index 0000000..5aa73ac
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: ace scale-list
+ * Author: SoftwarePlatform Group item
+ * Create: 2025-08-8
+ */
+
+#ifndef OHOS_ACELITE_MENU_ITEM_COMPONENT_H
+#define OHOS_ACELITE_MENU_ITEM_COMPONENT_H
+#include "component.h"
+#include "ui_transform_group.h"
+#include "non_copyable.h"
+
+namespace OHOS {
+namespace ACELite {
+class MenuItemComponent final : public Component {
+public:
+
+    ACE_DISALLOW_COPY_AND_MOVE(MenuItemComponent);
+    MenuItemComponent() = delete;
+    MenuItemComponent(jerry_value_t options, jerry_value_t children, AppStyleManager* styleManager);
+    ~MenuItemComponent() override {}
+
+protected:
+    UIView *GetComponentRootView() const override;
+    bool ProcessChildren() override;
+    void AttachView(const Component *child) override;
+
+private:
+    UITransformGroup item_;
+};
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // OHOS_ACELITE_MENU_ITEM_COMPONENT_H
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/scroll_component.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/ace_ext/scroll_component.h
new file mode 100644 (file)
index 0000000..50944ca
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: ace scroll view
+ * Author: SoftwarePlatform Group item
+ * Create: 2025-08-12
+ */
+
+#ifndef OHOS_ACELITE_SCROLL_COMPONENT_H
+#define OHOS_ACELITE_SCROLL_COMPONENT_H
+#include "component.h"
+#include "ui_scroll_view.h"
+#include "non_copyable.h"
+
+namespace OHOS {
+namespace ACELite {
+class ScrollComponent final : public Component {
+public:
+
+    ACE_DISALLOW_COPY_AND_MOVE(ScrollComponent);
+    ScrollComponent() = delete;
+    ScrollComponent(jerry_value_t options, jerry_value_t children, AppStyleManager* styleManager);
+    ~ScrollComponent() override {}
+
+protected:
+    UIView *GetComponentRootView() const override;
+    bool SetPrivateAttribute(uint16_t attrKeyId, jerry_value_t attrValue) override;
+    bool ProcessChildren() override;
+    void AttachView(const Component *child) override;
+
+private:
+    UIScrollView scrolliew_;
+};
+} // namespace ACELite
+} // namespace OHOS
+
+#endif // OHOS_ACELITE_SCROLL_COMPONENT_H
index 1667ee1..4fff4cf 100644 (file)
@@ -154,6 +154,10 @@ enum {
     KEYWORD(ITEM_SELECTED, itemselected) // scroll item selected event listener
     KEYWORD(ITERATION, iteration) // image-animator attribute
     KEYWORD(JUSTIFY_CONTENT, justifyContent) // layout style
+    // ohos begin
+    // list-item adaptive
+    KEYWORD(LONG_TEXT, longText) // common attributes
+    // ohos end
 #ifdef JS_TOUCH_EVENT_SUPPORT
     KEYWORD(KEY, key) // onkey event
 #endif
@@ -164,6 +168,13 @@ enum {
     KEYWORD(LINE_HEIGHT, lineHeight) // text style type
     KEYWORD(LIST, list) // list tag name
     KEYWORD(LIST_ITEM, list-item) // list-item tag name
+#ifdef FEATURE_COMPONENT_LISTEXT
+    KEYWORD(MENU_ITEM, arclist-item) // arclist-item tag name
+    KEYWORD(LIST_EXT, arclist) // arclist tag name
+#endif // FEATURE_COMPONENT_LISTEXT
+#ifdef FEATURE_COMPONENT_SCROLL
+    KEYWORD(SCROLL, scroll) // scroll tag name
+#endif // FEATURE_COMPONENT_SCROLL
 #ifdef FEATURE_DATE_FORMAT
     KEYWORD(LONG, long)
 #endif
index 911eac8..eab551a 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_ble.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_ble.a
new file mode 100644 (file)
index 0000000..63c1215
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_ble.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_ext.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_ext.a
new file mode 100644 (file)
index 0000000..587eab1
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_ext.a differ
index 4adbcbe..f0adf75 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_http.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_http.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_websocket.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_websocket.a
new file mode 100644 (file)
index 0000000..4eecaba
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libace_websocket.a differ
index 772a439..7cf9ee1 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libnetstack_http.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libnetstack_http.a differ
index 8dfa5e2..4b04c1b 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libwebsocket.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-cli/libwebsocket.a differ
index 9ec1739..bc72f9a 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_ble.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_ble.a
new file mode 100644 (file)
index 0000000..a917d81
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_ble.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_ext.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_ext.a
new file mode 100644 (file)
index 0000000..25f6ee5
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_ext.a differ
index 12f9b10..a0a00f5 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_http.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_http.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_websocket.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_websocket.a
new file mode 100644 (file)
index 0000000..32d6613
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libace_websocket.a differ
index 055db3b..0e01cde 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libnetstack_http.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libnetstack_http.a differ
index 8dfa5e2..f5dd2f8 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libwebsocket.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-auto-ota-ser/libwebsocket.a differ
index e807091..8d5a592 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_ble.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_ble.a
new file mode 100644 (file)
index 0000000..77e74b0
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_ble.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_ext.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_ext.a
new file mode 100644 (file)
index 0000000..99a6acf
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_ext.a differ
index cdfdb31..b93d220 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_http.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_http.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_websocket.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_websocket.a
new file mode 100644 (file)
index 0000000..757832c
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libace_websocket.a differ
index b9c1bb0..fcaecba 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libnetstack_http.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libnetstack_http.a differ
index 8dfa5e2..c8de21d 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libwebsocket.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-native-js/libwebsocket.a differ
index eb0cef5..01c8d06 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-target3/libnetstack_http.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-target3/libnetstack_http.a differ
index 0bff7a3..b8b76cf 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_ble.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_ble.a
new file mode 100644 (file)
index 0000000..c7c8ffa
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_ble.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_ext.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_ext.a
new file mode 100644 (file)
index 0000000..b95fdfd
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_ext.a differ
index e7707d7..a94551f 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_http.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_http.a differ
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_websocket.a b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_websocket.a
new file mode 100644 (file)
index 0000000..e2cf4b2
Binary files /dev/null and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libace_websocket.a differ
index c44ffef..efc192d 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libnetstack_http.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libnetstack_http.a differ
index 8dfa5e2..9f86f8d 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libwebsocket.a and b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/brandy-xts/libwebsocket.a differ
index a53e555..f32ea36 100644 (file)
 #endif // FEATURE_COMPONENT_BAIDUMAP
 #include "text_component.h"
 #include "video_component.h"
+#if FEATURE_COMPONENT_LISTEXT
+#include "menu_item_component.h"
+#include "list_ext_component.h"
+#endif // FEATURE_COMPONENT_LISTEXT
+#if FEATURE_COMPONENT_SCROLL
+#include "scroll_component.h"
+#endif // FEATURE_COMPONENT_SCROLL
 
 namespace OHOS {
 namespace ACELite {
@@ -147,6 +154,19 @@ public:
             case K_LIST_ITEM:
                 component = new DivComponent(options, children, styleManager);
                 break;
+#if FEATURE_COMPONENT_LISTEXT
+            case K_MENU_ITEM:
+                component = new MenuItemComponent(options, children, styleManager);
+                break;
+            case K_LIST_EXT:
+                component = new ListExtComponent(options, children, styleManager);
+                break;
+#endif // FEATURE_COMPONENT_LISTEXT
+#if FEATURE_COMPONENT_SCROLL
+            case K_SCROLL:
+                component = new ScrollComponent(options, children, styleManager);
+                break;
+#endif // FEATURE_COMPONENT_SCROLL
 #ifdef FEATURE_COMPONENT_ANALOG_CLOCK
             case K_CLOCK_HAND:
                 component = new ClockHandComponent(options, children, styleManager);
index b144e11..257235a 100644 (file)
@@ -45,8 +45,12 @@ void ComponentUtils::ReleaseComponents(Component *rootComponent)
     if (rootComponent == nullptr) {
         return;
     }
+#if FEATURE_COMPONENT_LISTEXT
+    if (rootComponent->GetComponentName() != K_LIST && rootComponent->GetComponentName() != K_LIST_EXT) {
+#else
     // for list component, release all the list items first
     if (rootComponent->GetComponentName() != K_LIST) {
+#endif // FEATURE_COMPONENT_LISTEXT
         JSValue descriptors = rootComponent->GetDescriptors();
         if (!JSUndefined::Is(descriptors)) {
             DescriptorUtils::ReleaseDescriptorOrElements(descriptors);
index 40042c0..dd12976 100644 (file)
 #include "key_parser.h"
 #include "keys.h"
 #include "product_adapter.h"
+#include "input_method/ui_input_method.h"
 
 namespace OHOS {
 namespace ACELite {
+InputEditTextComponent::~InputEditTextComponent()
+{
+    UIInputMethod::GetInstance()->Input(UI_KEYCODE::UI_KEY_ENTER);
+}
+
 bool InputEditTextComponent::CreateNativeViews()
 {
     fontSize_ = ProductAdapter::GetDefaultFontSize();
index f6b2e07..8672c15 100644 (file)
@@ -38,7 +38,7 @@ public:
     {
         SetComponentName(K_INPUT);
     }
-    ~InputEditTextComponent() override {};
+    ~InputEditTextComponent() override;
     bool CreateNativeViews() override;
     void ReleaseNativeViews() override;
     bool SetPrivateAttribute(uint16_t attrKeyId, jerry_value_t attrValue) override;
index abf9cec..a03887e 100644 (file)
 #include "securec.h"
 #include "text_component.h"
 
+// ohos begin
+// list-item adaptive
+#include "list_adapter_ext.h"
+// ohos end
 namespace OHOS {
 namespace ACELite {
 ListAdapter::ListAdapter()
@@ -67,6 +71,10 @@ ListAdapter::~ListAdapter()
 
     itemsCount_ = 0;
     listItemsCount_ = 0;
+    // ohos begin
+    // list-item adaptive
+    ListAdapterExt::CleanAll();
+    // ohos end
 }
 
 bool ListAdapter::Initialize(const JSValue descriptors)
@@ -173,7 +181,12 @@ int16_t ListAdapter::CalculateItemIndex(int16_t itemIndex) const
     if (listItems_ == nullptr) {
         return FAILED;
     }
-
+    // ohos begin
+    // list-item adaptive
+    if (ListAdapterExt::GetItemAdaptive()) {
+        return 0;
+    }
+    // ohos end
     for (int16_t listItemsIndex = 0; listItemsIndex < listItemsCount_; listItemsIndex++) {
         if (itemIndex >= listItems_[listItemsIndex].startIndex &&
             itemIndex <= (listItems_[listItemsIndex].startIndex + listItems_[listItemsIndex].itemsCount - 1) &&
@@ -191,6 +204,12 @@ UIView *ListAdapter::GetView(UIView *inView, int16_t index)
     if (index < 0) {
         return nullptr;
     }
+    // ohos begin
+    // list-item adaptive
+    if (ListAdapterExt::GetItemAdaptive() && index >= itemsCount_) {
+        return nullptr;
+    }
+    // ohos end
     // 1. get UIView according to index which will show in list.
     int16_t listItemsIndex = CalculateItemIndex(index);
     if (listItemsIndex < 0) {
@@ -225,7 +244,7 @@ UIView *ListAdapter::GetView(UIView *inView, int16_t index)
     return newView;
 }
 
-JSValue ListAdapter::GetElement(int16_t listItemsIndex, int16_t index, bool &isFor) const
+JSValue ListAdapter::GetElement(int16_t listItemsIndex, int16_t index, bool &isFor)
 {
     JSValue element = UNDEFINED;
     JSValue descriptorOrElement = listItems_[listItemsIndex].descriptorOrElement;
@@ -235,12 +254,19 @@ JSValue ListAdapter::GetElement(int16_t listItemsIndex, int16_t index, bool &isF
     // if it is a for or for+if type list-item, we need create view dynamically.
     if (isFor) {
         // get render argument
-        JSValue item = jerry_get_property_by_index(getterRetList, index - startIndex);
+        // ohos begin
+        // list-item adaptive
+        JSValue item =
+            jerry_get_property_by_index(getterRetList, (ListAdapterExt::GetItemAdaptive() ? 0 : index) - startIndex);
+        // ohos end
         if (jerry_value_is_undefined(item)) {
             HILOG_ERROR(HILOG_MODULE_ACE, "List adapter: Get item from getterRetList failed.");
             return UNDEFINED;
         }
-        JSValue itemIdx = jerry_create_number(index - startIndex);
+        // ohos begin
+        // list-item adaptive
+        JSValue itemIdx = jerry_create_number((ListAdapterExt::GetItemAdaptive() ? 0 : index) - startIndex);
+        // ohos end
         const int8_t argsLen = 2;
         JSValue args[argsLen] = {item, itemIdx};
         // get render function
@@ -276,11 +302,15 @@ JSValue ListAdapter::GetElement(int16_t listItemsIndex, int16_t index, bool &isF
     } else { // if it is a common list-item
         element = descriptorOrElement;
     }
+    // ohos begin
+    // list-item adaptive
+    ListAdapterExt::SetItemIndex(index);
+    // ohos end
     BuildItemViewTree(element);
     return element;
 }
 
-void ListAdapter::BuildItemViewTree(const JSValue element) const
+void ListAdapter::BuildItemViewTree(const JSValue element)
 {
     Component *component = ComponentUtils::GetComponentFromBindingObject(element);
     if (component == nullptr) {
@@ -352,6 +382,14 @@ void ListAdapter::BuildItemViewTree(const JSValue element) const
             Component::BuildViewTree(component, nullptr, parentParam);
         }
     }
+    // begin end
+    // ohos begin
+    // list-item adaptive
+    if (ListAdapterExt::GetItemAdaptive()) {
+        int16_t itemsCount = ListAdapterExt::BuildItemAdaptive(component, ListAdapterExt::GetItemIndex());
+        itemsCount_ = itemsCount > 0 ? itemsCount : itemsCount_;
+    }
+    // ohos end
     component->OnViewAttached();
 }
 
@@ -432,6 +470,11 @@ void ListAdapter::CleanUp()
     itemsCount_ = 0;
     listItemsCount_ = 0;
 
+    // ohos begin
+    // list-item adaptive
+    ListAdapterExt::CleanVector();
+    // ohos end
+
     if (listItems_ != nullptr) {
         delete[] listItems_;
         listItems_ = nullptr;
index 6d35188..2a4668e 100644 (file)
@@ -81,10 +81,16 @@ public:
 private:
     bool GenerateListItems(const JSValue descriptors, int16_t size);
     int16_t CalculateItemIndex(int16_t itemIndex) const;
-    JSValue GetElement(int16_t listItemsIndex, int16_t index, bool &isFor) const;
+    // ohos begin
+    // list-item adaptive
+    JSValue GetElement(int16_t listItemsIndex, int16_t index, bool &isFor);
+    // ohos end
     bool AddForDescriptorToList(JSValue descriptorOrElement, int16_t listItemsIndex) const;
     void InsertItem(JSValue nativeElement, UIView *uiView);
-    void BuildItemViewTree(const JSValue element) const;
+    // ohos begin
+    // list-item adaptive
+    void BuildItemViewTree(const JSValue element);
+    // ohos end
     ListItemValue *listItems_;
     ViewNativePair *headNode_;
     ViewNativePair *tailNode_;
index e41f45f..9fd0dca 100644 (file)
 #include "fatal_handler.h"
 #include "key_parser.h"
 #include "keys.h"
+// ohos begin
+// list-item adaptive
+#include "list_adapter_ext.h"
+// ohos end
 
 namespace OHOS {
 namespace ACELite {
@@ -98,7 +102,26 @@ bool ListComponent::SetPrivateAttribute(uint16_t attrKeyId, jerry_value_t attrVa
             list_.SetYScrollBarVisible(false);
         }
         return true;
+    // ohos begin
+    // list-item adaptive
+    } else if (attrKeyId == K_LONG_TEXT) {
+        if (jerry_value_is_boolean(attrValue)) {
+            ListAdapterExt::SetItemAdaptive(BoolOf(attrValue));
+        }
+        return true;
+    } else if (attrKeyId == K_VALUE) {
+        if (jerry_value_is_string(attrValue)) {
+            char *value = MallocStringOf(attrValue);
+            if (value == nullptr) {
+                HILOG_ERROR(HILOG_MODULE_ACE, "value is nullptr");
+                return false;
+            }
+            ListAdapterExt::SetListValue(value);
+            ace_free(value);
+        }
+        return true;
     }
+    // ohos end
     return false;
 }
 
index 1879b67..b023a7a 100644 (file)
@@ -26,7 +26,7 @@
 #ifdef CUSTOM_ZHIHUI
 #include "themestyle/include/ThemeStyleModel.h"
 #else
-#include "settings/SetDesktopModel.h"
+#include "settings/model/SettingDesktopModel.h"
 #endif
 
 namespace OHOS {
@@ -86,10 +86,10 @@ void TerminateWrapper(uint32_t token, bool forceStop)
     (void)forceStop;
     uint16_t preSliceId = NativeAbility::GetInstance().GetPreSliceId();
     if (preSliceId == VIEW_APPLIST) {
-        if (SetDesktopModel::GetInstance().GetDesktopStyle() == HEXAGONS_STYLE) {
+        if (SettingDesktopModel::GetInstance().GetDesktopStyle() == HEXAGONS_STYLE) {
             AbilityMsClient::GetInstance().TerminateAbility(token, TransitionType::TRANSITION_BACK_TO_HEXAGONS);
             return;
-        } else if (SetDesktopModel::GetInstance().GetDesktopStyle() == WATERFALL_STYLE) {
+        } else if (SettingDesktopModel::GetInstance().GetDesktopStyle() == WATERFALL_STYLE) {
             AbilityMsClient::GetInstance().TerminateAbility(token, TransitionType::TRANSITION_BACK_TO_WATERFALL);
             return;
         }
index fc1c1d4..dfa4132 100644 (file)
@@ -1462,6 +1462,7 @@ int32_t BaidumapSendMsgToJS(const char *msgBody, uint8_t type)
     if (!ret) {
         HILOG_ERROR(HILOG_MODULE_ACE, "Failed to dispatch async work");
         AdapterFree(params->msgBody);
+        params->msgBody = nullptr;
         delete params;
         params = nullptr;
         return -1;
@@ -1493,6 +1494,7 @@ int32_t BaidumapFailSendMsgToJS(const char *msgBody, uint8_t type)
     if (!ret) {
         HILOG_ERROR(HILOG_MODULE_ACE, "Failed to dispatch async work");
         AdapterFree(params->msgBody);
+        params->msgBody = nullptr;
         delete params;
         params = nullptr;
         return -1;
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/bluetooth/ble_module.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/bluetooth/ble_module.h
new file mode 100644 (file)
index 0000000..cf6931b
--- /dev/null
@@ -0,0 +1,141 @@
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025. All rights reserved.\r
+ * Description: http control interfaces\r
+ * Author: Software Group\r
+ * Create: 2025-08-06\r
+ */\r
+\r
+#ifndef BLE_CLIENT_MODULE_H\r
+#define BLE_CLIENT_MODULE_H\r
+\r
+#include "ble_module_common.h"\r
+#include "los_task.h" \r
+#include "bts_le_gap.h"\r
+#include "cmsis_os2.h"\r
+#include "ohos_init.h"\r
+#include <queue>\r
+#include <mutex>\r
+#include <condition_variable>\r
+\r
+namespace OHOS {\r
+namespace ACELite {\r
+class BleModule final : public MemoryHeap {\r
+public:\r
+    BleModule() = default;\r
+    ~BleModule() = default;\r
+    static JSIValue JSGetMtu(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Connect(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue DisConnect(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue GetServices(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue ReadCharacteristicValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue WriteCharacteristicValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue ReadDescriptorValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue WriteDescriptorValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue SetNotifyCharacteristicChanged(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue GetDeviceName(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue GetRssiValue(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Close(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue CreateGattClientDevice(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue StartBLEScan(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue StopBLEScan(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue StartAdvertising(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue StopAdvertising(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue SetCharacteristicChangeIndication(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue SetCharacteristicChangeNotification(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue On(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Off(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue ClientOff(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue ClientOn(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static void CheckSubscription(const char *type, const JSIValue err, const JSIValue value);\r
+    static void Destroy();\r
+    static void GetAdvertiseData(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingParams, const char *type,\r
+        bool *hasResponse);\r
+    static void GetAdvertiseWithCallback(const JSIValue *args, uint8_t argsSize, AdvertisingParams &advertisingParams,\r
+        bool *hasResponse);\r
+    static void GetAdvertiseWithParame(const JSIValue *args, uint8_t argsSize, AdvertiseSetting &setting,\r
+        AdvertiseData &advData, AdvertiseData &advResponse, bool *hasResponse);\r
+    static void DiscoverCharacteristicsForService(uint8_t client_id, uint16_t conn_id);\r
+    static void CompleteDiscovery(uint16_t conn_id, errcode_t status);\r
+    static void StartDescriptorDiscovery(uint8_t client_id, uint16_t conn_id);\r
+    static DiscoveryContext* GetValidDiscoveryContext(uint16_t connId);\r
+    static void ProcessNextDescriptorDiscovery(uint8_t client_id, uint16_t conn_id);\r
+    // 辅助函数:根据UUID查找特征值\r
+    static bool FindCharacteristic(const uint16_t charHandle, const std::string& serviceUuid,\r
+        const std::string& charUuid, BLECharacteristic& outChar, uint16_t connId);\r
+    static void CleanupConnectionResources(uint16_t conn_id);\r
+    // 辅助函数:根据UUID查找描述符\r
+    static bool FindDescriptor(const uint16_t descHandle, const std::string& serviceUuid, const std::string& charUuid,\r
+        const std::string& descUuid, BLEDescriptor& outDesc, uint16_t connId);\r
+    static void DsicoverExecute(void *data);\r
+    static void OnTerminate();\r
+\r
+    static std::map<std::string, EventCallback *> eventCallbacks;\r
+    static std::mutex scanResultMutex;\r
+    static std::vector<ScanResult> scanResult;\r
+    static uint32_t bleMtu;\r
+    static uint8_t clientId;\r
+    static std::mutex addrMapMutex;\r
+    static std::map<std::string, uint8_t> addrMap;\r
+    static BLEConnectionChangeState connectState;\r
+    static std::vector<GattService> gattServices; // -----发现服务的回调里捞取服务、特征值、描述\r
+    static std::vector<BLECharacteristic> gattCharacteristics;\r
+    static std::vector<BLEDescriptor> gattDescriptors; \r
+    static std::map<std::string, uint16_t> connectMap;\r
+    static std::map<uint8_t, uint8_t> advertisingMap;\r
+    static uint8_t advId;\r
+    static std::string deviceId;\r
+    static bool hasOn;\r
+    // 上下文管理相关静态成员\r
+    static std::map<uint16_t, DiscoveryContext> discoveryContexts;\r
+    static std::mutex contextMutex;\r
+    // 操作上下文管理\r
+    static std::vector<GattOperationContext> operationContexts;\r
+    static std::mutex operationMutex;\r
+    static std::vector<BleScanFilter> bleScanFilters;\r
+    static std::map<uint16_t, std::vector<GattService>> discoveredServicesMap;\r
+\r
+    static std::queue<gap_scan_result_data_t> scanDataQueue;\r
+    static std::mutex queueMutex;\r
+    static std::condition_variable queueCond;\r
+    static bool workerThreadRunning;\r
+    static osThreadId_t workerThreadId;\r
+\r
+    static std::queue<std::shared_ptr<DiscoveryData>> discoveryQueue;\r
+    static std::mutex discoveryQueueMutex;\r
+    static std::condition_variable discoveryQueueCond;\r
+    static bool discoveryWorkerRunning;\r
+    static osThreadId_t discoveryWorkerThreadId;\r
+    static ScanOptions scanOptions;\r
+private:\r
+    static errcode_t ProcessAdvertisingParameters(const JSIValue *args, uint8_t argsSize,\r
+    gap_ble_adv_params_t &adv_param, gap_ble_config_adv_data_t &cfg_adv_data, bool &hasResponse);\r
+    static errcode_t HandleAdvertiseSetting(const JSIValue *args, uint8_t argsSize,\r
+    gap_ble_config_adv_data_t &cfg_adv_data, bool &hasResponse);\r
+    static errcode_t HandleAdvertisingParams(const JSIValue *args, uint8_t argsSize,\r
+    gap_ble_adv_params_t &adv_param, gap_ble_config_adv_data_t &cfg_adv_data, bool &hasResponse);\r
+    static errcode_t ConfigureAndStartAdvertising(gap_ble_adv_params_t &adv_param,\r
+    gap_ble_config_adv_data_t &cfg_adv_data);\r
+    static JSIValue HandleExit(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize, errcode_t ret,\r
+    const gap_ble_config_adv_data_t &cfg_adv_data);\r
+    static bool CheckResponseData(const char *type, JSIValue jsiAdvertisingData, bool *hasResponse);\r
+    static void ProcessServiceUuids(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingData,\r
+        const char *type);\r
+    static void ProcessManufactureData(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingData,\r
+        const char *type);\r
+    static void ProcessManufactureValue(JSIValue jsiManufactureDataItem, ManufactureData &manufactureData);\r
+    static void ProcessServiceData(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingData,\r
+        const char *type);\r
+    static void ProcessServiceValue(JSIValue jsiServiceDataItem, ServiceData &serviceData);\r
+    static void ProcessIncludeDeviceName(AdvertisingParams &advertisingParams, JSIValue jsiAdvertisingData,\r
+        const char *type);\r
+    \r
+    static errcode_t ReleaseConnect();\r
+    static void ReleaseClose();\r
+    static void DestroyStopScanAndAdv();\r
+    static JSIValue gattClient;\r
+};\r
+void InitBleModule(JSIValue exports);\r
+\r
+}  // namespace ACELite\r
+}  // namespace OHOS\r
+#endif  // BLE_CLIENT_MODULE_H
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/bluetooth/ble_module_common.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/bluetooth/ble_module_common.h
new file mode 100644 (file)
index 0000000..81763d6
--- /dev/null
@@ -0,0 +1,409 @@
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2025. All rights reserved.\r
+ * Description: http control interfaces\r
+ * Author: Software Group\r
+ * Create: 2025-08-06\r
+ */\r
+\r
+#ifndef BLE_CLIENT_MODULE_COMMON_H\r
+#define BLE_CLIENT_MODULE_COMMON_H\r
+\r
+#include <stdint.h>\r
+#include "jsi.h"\r
+#include "errcode.h"\r
+#include "bts_gatt_client.h"\r
+#include "non_copyable.h"\r
+#include "js_async_work.h"\r
+#include "bts_le_gap.h"\r
+#include <map>\r
+#include <vector>\r
+#include <string> \r
+\r
+namespace OHOS {\r
+namespace ACELite {\r
+\r
+#define MAX_CHARACTERISTICVALUE_LEN 128\r
+#define MAX_BLE_NAME_LEN 10\r
+#define MIN_BLE_INTERVEL_LEN 48\r
+#define MAX_BLE_INTERVEL_LEN 96\r
+#define MAX_ADV_DATA_LEN 31\r
+#define NOMAL_MTU_VALUE 512\r
+#define NOMAL_ADV_ID 3\r
+\r
+#define BLE_ADDR_LEN 6\r
+#define BLE_INVALID_CHARACTERISTIC_HANDLE 65530\r
+#define BLE_INVALID_DESCRIPTOR_HANDLE 65531\r
+\r
+// 蓝牙广播数据类型定义\r
+#define BLE_AD_TYPE_FLAGS 0x01\r
+#define BLE_AD_TYPE_16BIT_SERVICE_UUID 0x03\r
+#define BLE_AD_TYPE_32BIT_SERVICE_UUID 0x05\r
+#define BLE_AD_TYPE_128BIT_SERVICE_UUID 0x07\r
+#define BLE_AD_TYPE_COMPLETE_LOCAL_NAME 0x09\r
+#define BLE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF\r
+#define BLE_AD_TYPE_SERVICE_DATA_16BIT 0x16\r
+#define BLE_AD_TYPE_SERVICE_DATA_32BIT 0x20\r
+#define BLE_AD_TYPE_SERVICE_DATA_128BIT 0x21\r
+// 广播数据类型常量定义\r
+constexpr const char* ADVERTISING_DATA = "advertisingData";\r
+constexpr const char* ADVERTISING_RESPONSE = "advertisingResponse";\r
+constexpr const char* SERVICE_UUIDS = "serviceUuids";\r
+constexpr const char* MANUFACTURE_DATA = "manufactureData";\r
+constexpr const char* SERVICE_DATA = "serviceData";\r
+constexpr const char* MANUFACTURE_ID = "manufactureId";\r
+constexpr const char* MANUFACTURE_VALUE = "manufactureValue";\r
+constexpr const char* SERVICE_UUID = "serviceUuid";\r
+constexpr const char* SERVICE_VALUE = "serviceValue";\r
+constexpr const char* INCLUDE_DEVICE_NAME = "includeDeviceName";\r
+\r
+\r
+struct EventCallback {\r
+    JSIValue callback;\r
+    JSIValue context;\r
+};\r
+\r
+enum ErrNum {\r
+    BLE_SUCCESS = 0,\r
+    BLE_PERMISSION_DENIED = 201,\r
+    BLE_INVALID_PARAMETER = 401,\r
+    BLE_UNSUPPORT = 801,\r
+    BLE_SERVICE_STOP = 2900001,\r
+    BLE_READ_FORBID = 2901000,\r
+    BLE_OPRATION_FAILED = 2900099,\r
+};\r
+\r
+enum class MatchType {\r
+    NONE,\r
+    CHARACTERISTIC,\r
+    DESCRIPTOR\r
+};\r
+\r
+enum ChannelMap {\r
+    BLE_ONE_CHANEL = 0x1,\r
+    BLE_THREE_CHANEL = 0x7,\r
+};\r
+\r
+enum ScanDuty {\r
+    SCAN_MODE_LOW_POWER = 0,\r
+    SCAN_MODE_BALANCED = 1,\r
+    SCAN_MODE_LOW_LATENCY = 2,\r
+    SCAN_MODE_NONE,\r
+};\r
+\r
+enum MatchMode {\r
+    MATCH_MODE_AGGRESSIVE = 1,\r
+    MATCH_MODE_STICKY = 2,\r
+    MATCH_MODE_NONE,\r
+};\r
+\r
+enum PhyType {\r
+    PHY_LE_1M = 1,\r
+    PHY_LE_ALL_SUPPORTED = 255,\r
+    PHY_LE_NONE,\r
+};\r
+\r
+enum ScanReportMode {\r
+    SCAN_REPORT_MODE_NORMAL = 1,\r
+    SCAN_REPORT_MODE_NONE,\r
+};\r
+\r
+struct BLEDescriptor {\r
+    std::string serviceUuid;\r
+    std::string characteristicUuid;\r
+    std::string descriptorUuid;\r
+    std::vector<uint8_t> descriptorValue;\r
+    gattc_discovery_descriptor_result_t descriptor;\r
+};\r
+\r
+struct GattProperties {\r
+    bool write;\r
+    bool writeNoResponse;\r
+    bool read;\r
+    bool notify;\r
+    bool indicate;\r
+};\r
+\r
+struct BLECharacteristic {\r
+    std::string serviceUuid;\r
+    std::string characteristicUuid;\r
+    std::vector<uint8_t> characteristicValue;\r
+    std::vector<BLEDescriptor> descriptors;\r
+    GattProperties properties;\r
+    gattc_discovery_character_result_t character;\r
+    uint16_t service_start_hdl;\r
+    uint16_t service_end_hdl;\r
+};\r
+\r
+struct CallFuncAsyncParams : public MemoryHeap {\r
+    ACE_DISALLOW_COPY_AND_MOVE(CallFuncAsyncParams);\r
+    CallFuncAsyncParams() : err(nullptr), result(nullptr), callback(nullptr), context(nullptr),\r
+        type(nullptr), connId(0), characteristicArgs(nullptr){}\r
+\r
+    JSIValue err;\r
+    JSIValue result;\r
+    JSIValue callback;\r
+    JSIValue context;\r
+    char* type;\r
+    uint16_t connId;\r
+    BLECharacteristic *characteristicArgs;\r
+};\r
+\r
+struct BleScanFilter {\r
+    std::string deviceId;\r
+    std::string name;\r
+    std::string serviceUuid;\r
+    std::string serviceUuidMask;\r
+    std::string serviceSolicitationUuid;\r
+    std::string serviceSolicitationUuidMask;\r
+    std::vector<uint8_t> serviceData;\r
+    std::vector<uint8_t> serviceDataMask;\r
+    uint16_t manufactureId = 0;\r
+    std::vector<uint8_t> manufactureData;\r
+    std::vector<uint8_t> manufactureDataMask;\r
+};\r
+\r
+struct ScanOptions {\r
+    double interval;\r
+    ScanDuty dutyMode;\r
+    MatchMode matchMode;\r
+    PhyType phyType;\r
+    ScanReportMode reportMode;\r
+};\r
+\r
+struct ScanResult {\r
+    std::string deviceId;\r
+    int8_t rssi;\r
+    std::vector<uint8_t> data;\r
+    std::string deviceName;\r
+    bool connectable;\r
+};\r
+\r
+// AD结构定义\r
+struct AdStruct {\r
+    uint8_t length;       // 类型+数据的总长度\r
+    uint8_t type;         // 类型标志\r
+    std::vector<uint8_t> data; // 数据内容\r
+};\r
+\r
+struct BleParsedResult {\r
+    std::vector<std::string> serviceUuids;                     // 服务UUID\r
+    std::vector<std::string> serviceSolicitationUuids;         // 服务请求UUID\r
+    std::vector<std::pair<std::string, std::vector<uint8_t>>> serviceDatas; // 服务数据\r
+    uint16_t manufactureId = 0;                                // 厂商ID\r
+    std::vector<uint8_t> manufactureData;                      // 厂商数据\r
+};\r
+\r
+struct ServiceData {\r
+    std::string serviceUuid;\r
+    std::vector<uint8_t> serviceValue;\r
+};\r
+\r
+struct ManufactureData {\r
+    uint16_t manufactureId;\r
+    std::vector<uint8_t> manufactureValue;\r
+};\r
+\r
+struct AdvertiseSetting {\r
+    double interval;\r
+    double txPower;\r
+    bool connectable;\r
+};\r
+\r
+struct AdvertiseData {\r
+    std::vector<std::string> serviceUuids;\r
+    std::vector<ManufactureData> manufactureData;\r
+    std::vector<ServiceData> serviceData;\r
+    bool includeDeviceName;\r
+};\r
+\r
+\r
+struct AdvertisingParams {\r
+    AdvertiseSetting advertisingSettings;\r
+       AdvertiseData advertisingData;\r
+    AdvertiseData advertisingResponse;\r
+    uint32_t duration;\r
+};\r
+\r
+enum ProfileConnectionState {\r
+    STATE_DISCONNECTED = 0,\r
+    STATE_CONNECTING = 1,\r
+    STATE_CONNECTED = 2,\r
+    STATE_DISCONNECTING = 3,\r
+};\r
+\r
+enum GattWriteType {\r
+    WRITE = 1,\r
+    WRITE_NO_RESPONSE = 2,\r
+};\r
+\r
+enum AdvertisingState {\r
+    STARTED = 1, // advertising started.\r
+    ENABLED = 2, // advertising temporarily enabled.\r
+    DISABLED = 3, // advertising temporarily disabled.\r
+    STOPPED = 4, // advertising stopped.\r
+};\r
+\r
+struct AdvertisingStateChangeInfo {\r
+    uint32_t advertisingId;\r
+    AdvertisingState state;\r
+};\r
+\r
+struct BLEConnectionChangeState {\r
+    std::string deviceId;\r
+       ProfileConnectionState state;\r
+};\r
+\r
+struct GattService {\r
+    std::string serviceUuid;\r
+    bool isPrimary;\r
+    std::vector<BLECharacteristic> characteristics;\r
+    std::vector<GattService> includeServices;\r
+    gattc_discovery_service_result_t service;\r
+    GattService() : isPrimary(true) {}\r
+};\r
+\r
+// 发现过程上下文,管理单个连接的服务发现状态\r
+struct DiscoveryContext {\r
+    uint16_t connId;\r
+    bool isInProgress;\r
+    JSIValue callback;\r
+    JSIValue thisVal;\r
+    uint16_t currentStartHandle;\r
+    std::vector<uint16_t> pendingCharHandles;\r
+    uint32_t currentServiceIndex;\r
+    uint16_t currentDescHandle;\r
+    uint16_t expectedDescCount;   // 预期描述符总数\r
+    uint16_t receivedDescCount;   // 已接收描述符计数\r
+    std::vector<GattService> discoveredServices; // 存储发现的服务数据\r
+    bool isCompleted; // 标记发现是否完成\r
+    bool isLastCharacteristic; // 新增:标记当前是否在处理最后一个特征值\r
+    uint16_t lastServiceEndHandle; // 新增:记录最后一个服务的结束句柄\r
+    \r
+    DiscoveryContext() : connId(0), isInProgress(false), currentStartHandle(0),\r
+        callback(JSI::CreateUndefined()), thisVal(JSI::CreateUndefined()), \r
+        currentDescHandle(0), expectedDescCount(0), receivedDescCount(0),\r
+        isCompleted(false), isLastCharacteristic(false), lastServiceEndHandle(0) {}\r
+};\r
+\r
+// 读写请求上下文,用于匹配请求和回调结果\r
+struct GattOperationContext {\r
+    enum Type {\r
+        READ_CHARACTERISTIC,\r
+        WRITE_CHARACTERISTIC,\r
+        READ_DESCRIPTOR,\r
+        WRITE_DESCRIPTOR\r
+    };\r
+\r
+    Type type;\r
+    uint16_t connId; // 新增:关联的连接ID\r
+    std::string serviceUuid;\r
+    std::string charUuid;\r
+    std::string descUuid;\r
+    uint16_t charHandle;\r
+    uint16_t descHandle;\r
+    JSIValue callback;\r
+    JSIValue thisVal;\r
+    GattWriteType writeType; // 仅用于写操作\r
+};\r
+\r
+struct DiscoveryData {\r
+    uint16_t connId;\r
+    std::vector<GattService> services;\r
+    std::vector<BLECharacteristic> characteristics;\r
+    std::vector<BLEDescriptor> descriptors;\r
+    JSIValue callback;\r
+    JSIValue thisVal;\r
+    \r
+    DiscoveryData(uint16_t id) : connId(id), \r
+        callback(JSI::CreateUndefined()), \r
+        thisVal(JSI::CreateUndefined()) {}\r
+    \r
+    ~DiscoveryData() {\r
+        JSI::ReleaseValueList(callback, thisVal);\r
+    }\r
+};\r
+\r
+struct DispatchAsync {\r
+    JSIValue err;\r
+    JSIValue result;\r
+    JSIValue callback;\r
+    JSIValue thisVal;\r
+    char* type;\r
+    uint16_t connId;\r
+    BLECharacteristic characteristicArgs;\r
+};\r
+uint8_t Char2Num(int8_t c);\r
+bool CompareHexStrings(const std::string& str1, const std::string& str2);\r
+errcode_t DecodeUuidFromStr(const char *uuidStr, uint8_t *uuid, int32_t *cnt);\r
+std::string FormatMacAddress(const uint8_t addr[BLE_ADDR_LEN]);\r
+errcode_t ParseUuidList(const uint8_t *data, uint8_t len, uint8_t uuid_size, std::vector<std::string> &uuid_list);\r
+bool CheckUuidMatch(const std::string &uuid, const std::string &filter, const std::string &mask);\r
+std::string GetUUidStr(const bt_uuid_t &uuid);\r
+void GetAttValueData(uint8_t *dataVec, bool enable, bool indication);\r
+errcode_t SetJsiBLECharacteristic(JSIValue jsiBleCharacteristic, uint16_t connId,\r
+    BLECharacteristic *bleCharacteristicArgs);\r
+void DiscoveryWorkerThread(void* arg);\r
+void GapBleEnableStackCbk(errcode_t status);\r
+void GapBleDisableStackCbk(errcode_t status);\r
+void GapBleSetAdvDataCbk(uint8_t adv_id, errcode_t status);\r
+void GapBleSetAdvParamCbk(uint8_t advId, errcode_t status);\r
+void GapBleSetScanParamCbk(errcode_t status);\r
+void GapBleStartAdvCbk(uint8_t advId, adv_status_t status);\r
+void GapBleStopAdvCbk(uint8_t advId, adv_status_t status);\r
+void GattcIndicationCbk(uint8_t client_id, uint16_t connId, gattc_handle_value_t *data,\r
+    errcode_t status);\r
+void GattcNotificationdCbk(uint8_t client_id, uint16_t connId, gattc_handle_value_t *data, errcode_t status);\r
+void GattsMtuChangedCbk(uint8_t server_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status);\r
+void GattcMtuChangedCbk(uint8_t client_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status);\r
+void GattcWriteCfmCbk(uint8_t client_id, uint16_t conn_id, uint16_t handle, gatt_status_t status);\r
+void GattcReadByUuidRespone(uint8_t client_id, uint16_t conn_id,\r
+    gattc_read_req_by_uuid_param_t *param, errcode_t status);\r
+void GattcReadCfmCbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *read_result, gatt_status_t status);\r
+void GattcDiscoveryDescResponse(uint8_t client_id, uint16_t conn_id, uint16_t character_handle,\r
+    errcode_t status);\r
+void GattcDiscoveryDescCbk(uint8_t client_id, uint16_t conn_id,\r
+    gattc_discovery_descriptor_result_t* descriptor, errcode_t status);\r
+void GattcDiscoveryCharResponse(uint8_t client_id, uint16_t conn_id, gattc_discovery_character_param_t *param,\r
+    errcode_t status);\r
+void GattcDiscoveryCharCbk(uint8_t client_id, uint16_t conn_id,\r
+    gattc_discovery_character_result_t *character, errcode_t status);\r
+void GattcDiscoverySvcResponse(uint8_t client_id, uint16_t conn_id, bt_uuid_t *uuid, errcode_t status);\r
+void GattcDiscoverySvcCbk(uint8_t client_id, uint16_t conn_id, gattc_discovery_service_result_t *service,\r
+    errcode_t status);\r
+void GapBleAuthCompeteCbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status,\r
+    const ble_auth_info_evt_t* evt);\r
+void GapBleReadRemoteRssiCbk(uint16_t conn_id, int8_t rssi, errcode_t status);\r
+void GapBleConnectParamUpdateCbk(uint16_t conn_id, errcode_t status,\r
+    const gap_ble_conn_param_update_t *param);\r
+void GapBleTerminateAdvCbk(uint8_t adv_id, adv_status_t status);\r
+void GapBlePariedCompleteCbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status);\r
+void GapBleConnStateChangeCbk(uint16_t conn_id, bd_addr_t *addr, gap_ble_conn_state_t conn_state,\r
+    gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason);\r
+void GapBleScanResultCbk(gap_scan_result_data_t *scan_result_data);\r
+void WorkerThreadFunc(void *argument);\r
+void GetCharacteristic(const JSIValue *args, BLECharacteristic &bleCharacteristicArgs, bool isRead);\r
+void GetProperty(const JSIValue jsiCharacteristic, BLECharacteristic &bleCharacteristicArgs);\r
+bool ValidateWriteParameters(uint8_t argsSize, const JSIValue* args);\r
+// 解析参数函数\r
+errcode_t ParseWriteArguments(const JSIValue* args, BLECharacteristic& bleCharacteristicArgs,\r
+    GattWriteType& writeType);\r
+void CleanupDiscoveryWorker();\r
+void InitDiscoveryWorker();\r
+void GetProperties(uint8_t properties, GattProperties &props);\r
+void CreateGattServices(JSIValue *rltArray, const std::vector<GattService> &services);\r
+JSIValue ConstructJSIResult(const gattc_handle_value_t *read_result, const BLECharacteristic *charFound,\r
+    const BLEDescriptor *descFound, const std::string &serviceUuid, const std::string &charUuid,\r
+    const std::string &descUuid);\r
+std::vector<GattService> AssembleGattServicesThreaded(std::shared_ptr<DiscoveryData> data);\r
+std::string FormatDeviceName(gap_scan_result_data_t *scan_result_data);\r
+BleParsedResult ParseMixedAdvertisingData(const uint8_t *data, uint8_t len);\r
+bool CheckBasicDeviceMatch(const BleScanFilter& filter, const ScanResult& scanResultTmp);\r
+bool CheckUuidMatch(const BleScanFilter& filter, const BleParsedResult& parsedResult);\r
+bool CheckDataMatch(const BleScanFilter& filter, const BleParsedResult& parsedResult);\r
+bool ReadMatchFilter(const BleScanFilter& filter, const BleParsedResult& parsedResult, \r
+    const ScanResult& scanResultTmp);\r
+void UpdateScanResult(const ScanResult &scanResultTmp, std::vector<ScanResult>::iterator existingIt,\r
+    std::vector<ScanResult> &scanResultList);\r
+}  // namespace ACELite\r
+}  // namespace OHOS\r
+#endif  // BLE_CLIENT_MODULE_COMMON_H
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_manager.cpp b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_manager.cpp
new file mode 100644 (file)
index 0000000..9ade0c2
--- /dev/null
@@ -0,0 +1,988 @@
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#include <cstdio>
+#include <cstring>
+#include <cerrno>
+#include <cstdlib>
+#include <securec.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "ace_mem_base.h"
+#include "memory_heap.h"
+#include "cJSON.h"
+#include "ace_log.h"
+#include "calendar_manager.h"
+
+#define FILE_SIZE_MAX 0xF00000
+namespace OHOS {
+namespace ACELite {
+// Error message mapping table
+static const char *g_errorStrings[CALENDAR_ERROR_MAX] = {"Operation successful",
+    "File does not exist",
+    "File open failed",
+    "JSON parsing error",
+    "User does not exist",
+    "Event does not exist",
+    "Event ID already exists",
+    "User information does not match",
+    "Memory allocation failed",
+    "Invalid parameter",
+    "File write failed",
+    "Failed to allocate event ID"};
+
+// Get error message string
+const char *GetCalendarErrorString(CalendarError error)
+{
+    return (error >= 0 && error < CALENDAR_ERROR_MAX) ? g_errorStrings[error] : "Unknown error";
+}
+
+// Internal utility: Read JSON file content
+static char *ReadJsonFile(const char *filename, CalendarError *error)
+{
+    if (!filename || !error) {
+        if (error) {
+            *error = CALENDAR_INVALID_PARAMETER;
+        }
+        return nullptr;
+    }
+
+    FILE *file = fopen(filename, "rb");
+    if (!file) {
+        *error = (errno == ENOENT) ? CALENDAR_FILE_NOT_FOUND : CALENDAR_FILE_OPEN_FAILED;
+        return nullptr;
+    }
+
+    // Get file size
+    fseek(file, 0, SEEK_END);
+    long fileLen = ftell(file);
+    fseek(file, 0, SEEK_SET);
+    if (fileLen > FILE_SIZE_MAX) {
+        return nullptr;
+    }
+    // Allocate memory (+1 for terminator)
+    char *data = (char *)malloc(fileLen + 1);
+    if (!data) {
+        fclose(file);
+        *error = CALENDAR_MEMORY_ALLOC_FAILED;
+        return nullptr;
+    }
+
+    // Read file
+    size_t readLen = fread(data, 1, fileLen, file);
+    fclose(file);
+
+    if (readLen != fileLen) {
+        free(data);
+        *error = CALENDAR_FILE_OPEN_FAILED;
+        return nullptr;
+    }
+    data[fileLen] = '\0';
+    *error = CALENDAR_SUCCESS;
+    return data;
+}
+
+// Internal utility: Write to JSON file
+static CalendarError writeJsonFile(const char *filename, cJSON *root)
+{
+    if (!filename || !root) {
+        return CALENDAR_INVALID_PARAMETER;
+    }
+
+    char *jsonStr = cJSON_Print(root);
+    if (!jsonStr) {
+        return CALENDAR_MEMORY_ALLOC_FAILED;
+    }
+
+    int fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
+    if (fd == -1) {
+        free(jsonStr);
+        return CALENDAR_FILE_OPEN_FAILED;
+    }
+
+    size_t strLen = strlen(jsonStr);
+    ssize_t writeLen = write(fd, jsonStr, strLen);
+    close(fd);  // Close file descriptor
+    free(jsonStr);
+
+    return (writeLen == strLen) ? CALENDAR_SUCCESS : CALENDAR_FILE_WRITE_FAILED;
+}
+
+// Internal utility: Get or create JSON root object
+static cJSON *getOrCreateRoot(const char *filename, CalendarError *error)
+{
+    if (!filename || !error) {
+        *error = CALENDAR_INVALID_PARAMETER;
+        return nullptr;
+    }
+
+    char *jsonData = ReadJsonFile(filename, error);
+    cJSON *root = nullptr;
+
+    // Create empty root object when file doesn't exist
+    if (*error == CALENDAR_FILE_NOT_FOUND) {
+        root = cJSON_CreateObject();
+        *error = (root) ? CALENDAR_SUCCESS : CALENDAR_MEMORY_ALLOC_FAILED;
+        return root;
+    }
+
+    // Return directly if read failed
+    if (*error != CALENDAR_SUCCESS) {
+        return nullptr;
+    }
+
+    // Parse JSON data
+    root = cJSON_Parse(jsonData);
+    free(jsonData);
+    jsonData = nullptr;
+    if (!root) {
+        *error = CALENDAR_JSON_PARSE_ERROR;
+    } else {
+        *error = CALENDAR_SUCCESS;
+    }
+
+    return root;
+}
+
+// Internal utility: Find user JSON object
+static cJSON *findUserObject(cJSON *root, const char *userName)
+{
+    if (!root || !userName || !cJSON_IsObject(root)) {
+        return nullptr;
+    }
+    return cJSON_GetObjectItemCaseSensitive(root, userName);
+}
+
+// Internal utility: Find event index in array (-1 means not exists)
+static int findEventIndex(cJSON *eventsArray, int eventId)
+{
+    if (!eventsArray || !cJSON_IsArray(eventsArray)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid parameter");
+        return -1;
+    }
+
+    int index = 0;
+    cJSON *event = nullptr;
+    cJSON_ArrayForEach(event, eventsArray)
+    {
+        cJSON *idItem = cJSON_GetObjectItemCaseSensitive(event, "id");
+        if (idItem && cJSON_IsNumber(idItem) && idItem->valueint == eventId) {
+            return index;
+        }
+        index++;
+    }
+    return -1;
+}
+
+// Internal utility: Create cJSON object from CalendarEvent struct
+static cJSON *createEventJson(const CalendarEvent *event)
+{
+    if (!event) {
+        return nullptr;
+    }
+
+    cJSON *eventJson = cJSON_CreateObject();
+    if (!eventJson) {
+        return nullptr;
+    }
+    cJSON_AddNumberToObject(eventJson, "id", event->id);
+    cJSON_AddNumberToObject(eventJson, "type", event->type);
+    cJSON_AddNumberToObject(eventJson, "startTime", event->startTime);
+    cJSON_AddNumberToObject(eventJson, "endTime", event->endTime);
+    cJSON_AddStringToObject(eventJson, "bundlename", event->bundlename);
+    cJSON_AddBoolToObject(eventJson, "isAllDay", event->isAllDay);
+    cJSON_AddBoolToObject(eventJson, "hasReminder", event->hasReminder);
+    cJSON_AddBoolToObject(eventJson, "isRepeat", event->isRepeat);
+    cJSON_AddNumberToObject(eventJson, "recurrenceFrequency", event->recurrenceFrequency);
+    cJSON_AddStringToObject(eventJson, "eventContent", event->eventContent);
+    return eventJson;
+}
+
+// Internal utility: Create user account JSON object
+static cJSON *createUserAccountJson(const char *name, const char *type, const char *displayName)
+{
+    if (!name || !type || !displayName) {
+        return nullptr;
+    }
+
+    cJSON *account = cJSON_CreateObject();
+    if (!account) {
+        return nullptr;
+    }
+
+    // Create CalendarAccount object
+    cJSON *calendarAccount = cJSON_CreateObject();
+    if (!calendarAccount) {
+        cJSON_Delete(account);
+        return nullptr;
+    }
+    cJSON_AddStringToObject(calendarAccount, "name", name);
+    cJSON_AddStringToObject(calendarAccount, "type", type);
+    cJSON_AddStringToObject(calendarAccount, "displayName", displayName);
+    cJSON_AddItemToObject(account, "CalendarAccount", calendarAccount);
+
+    // Create empty events array
+    cJSON *events = cJSON_CreateArray();
+    if (!events) {
+        cJSON_Delete(account);
+        return nullptr;
+    }
+    cJSON_AddItemToObject(account, "events", events);
+
+    return account;
+}
+
+// 1. Create or append user
+const char *CreateOrAppendUser(
+    const char *filename, const char *name, const char *type, const char *displayName, CalendarError *error)
+{
+    if (!filename || !name || !type || !displayName || !error) {
+        if (error) {
+            *error = CALENDAR_INVALID_PARAMETER;
+        }
+        return nullptr;
+    }
+
+    cJSON *root = getOrCreateRoot(filename, error);
+    if (!root || *error != CALENDAR_SUCCESS) {
+        return nullptr;
+    }
+
+    cJSON *user = findUserObject(root, name);
+    if (user) {
+        // User already exists, check if information matches
+        cJSON *account = cJSON_GetObjectItemCaseSensitive(user, "CalendarAccount");
+        if (!account) {
+            cJSON_Delete(root);
+            *error = CALENDAR_JSON_PARSE_ERROR;
+            return nullptr;
+        }
+
+        cJSON *existingtype = cJSON_GetObjectItemCaseSensitive(account, "type");
+        cJSON *existingDisplayName = cJSON_GetObjectItemCaseSensitive(account, "displayName");
+
+        if (!existingtype || !existingDisplayName || !cJSON_IsString(existingtype) ||
+            !cJSON_IsString(existingDisplayName) || strcmp(existingtype->valuestring, type) != 0 ||
+            strcmp(existingDisplayName->valuestring, displayName) != 0) {
+            cJSON_Delete(root);
+            *error = CALENDAR_USER_INFO_MISMATCH;
+            return nullptr;
+        }
+
+        // Information matches, return username
+        cJSON_Delete(root);
+        *error = CALENDAR_SUCCESS;
+        return name;
+    }
+
+    // Create new user
+    cJSON *newUser = createUserAccountJson(name, type, displayName);
+    if (!newUser) {
+        cJSON_Delete(root);
+        *error = CALENDAR_MEMORY_ALLOC_FAILED;
+        return nullptr;
+    }
+
+    cJSON_AddItemToObject(root, name, newUser);
+    *error = writeJsonFile(filename, root);
+    cJSON_Delete(root);
+
+    return (*error == CALENDAR_SUCCESS) ? name : nullptr;
+}
+
+// 2. Append single event (using CalendarEvent struct for parameters)
+CalendarError AppendEvent(const char *filename, const char *name, const CalendarEvent *event)
+{
+    if (!filename || !name || !event) {
+        return CALENDAR_INVALID_PARAMETER;
+    }
+
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    cJSON *root = getOrCreateRoot(filename, &error);
+    if (!root || error != CALENDAR_SUCCESS) {
+        return error;
+    }
+
+    cJSON *user = findUserObject(root, name);
+    if (!user) {
+        cJSON_Delete(root);
+        return CALENDAR_USER_NOT_FOUND;
+    }
+
+    cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+    if (!events || !cJSON_IsArray(events)) {
+        events = cJSON_CreateArray();
+        if (!events) {
+            cJSON_Delete(root);
+            return CALENDAR_MEMORY_ALLOC_FAILED;
+        }
+        cJSON_AddItemToObject(user, "events", events);
+    }
+
+    // Check if event ID already exists
+    if (findEventIndex(events, event->id) != -1) {
+        cJSON_Delete(root);
+        return CALENDAR_EVENT_ID_EXISTS;
+    }
+
+    // Create and add new event
+    cJSON *eventJson = createEventJson(event);
+    if (!eventJson) {
+        cJSON_Delete(root);
+        return CALENDAR_MEMORY_ALLOC_FAILED;
+    }
+
+    cJSON_AddItemToArray(events, eventJson);
+    error = writeJsonFile(filename, root);
+    cJSON_Delete(root);
+
+    return error;
+}
+
+// 3. Append multiple events
+CalendarError AppendEvents(const char *filename, const char *name, const CalendarEventArray *eventArray)
+{
+    if (!filename || !name || !eventArray || !eventArray->events || eventArray->count == 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "AppendEvents Invalid parameter");
+        return CALENDAR_INVALID_PARAMETER;
+    }
+
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    cJSON *root = getOrCreateRoot(filename, &error);
+    if (!root || error != CALENDAR_SUCCESS) {
+        return error;
+    }
+
+    cJSON *user = findUserObject(root, name);
+    if (!user) {
+        cJSON_Delete(root);
+        return CALENDAR_USER_NOT_FOUND;
+    }
+
+    cJSON *eventsArray = cJSON_GetObjectItemCaseSensitive(user, "events");
+    if (!eventsArray || !cJSON_IsArray(eventsArray)) {
+        eventsArray = cJSON_CreateArray();
+        if (!eventsArray) {
+            cJSON_Delete(root);
+            return CALENDAR_MEMORY_ALLOC_FAILED;
+        }
+        cJSON_AddItemToObject(user, "events", eventsArray);
+    }
+
+    // Check if all event IDs already exist
+    for (size_t i = 0; i < eventArray->count; i++) {
+        if (findEventIndex(eventsArray, eventArray->events[i].id) != -1) {
+            cJSON_Delete(root);
+            return CALENDAR_EVENT_ID_EXISTS;
+        }
+    }
+
+    // Add events in batch
+    for (size_t i = 0; i < eventArray->count; i++) {
+        cJSON *eventJson = createEventJson(&eventArray->events[i]);
+        if (!eventJson) {
+            cJSON_Delete(root);
+            return CALENDAR_MEMORY_ALLOC_FAILED;
+        }
+        cJSON_AddItemToArray(eventsArray, eventJson);
+    }
+
+    error = writeJsonFile(filename, root);
+    cJSON_Delete(root);
+
+    return error;
+}
+
+// 4. Get user's specific event
+CalendarEvent *CalendarGetEvent(const char *filename, const char *name, int eventId, CalendarError *error)
+{
+    if (!filename || !name || !error) {
+        *error = CALENDAR_INVALID_PARAMETER;
+        HILOG_ERROR(HILOG_MODULE_ACE, "AppendEvents Invalid parameter");
+        return nullptr;
+    }
+
+    char *jsonData = ReadJsonFile(filename, error);
+    if (!jsonData || *error != CALENDAR_SUCCESS) {
+        return nullptr;
+    }
+
+    cJSON *root = cJSON_Parse(jsonData);
+    free(jsonData);
+    jsonData = nullptr;
+    if (!root) {
+        *error = CALENDAR_JSON_PARSE_ERROR;
+        return nullptr;
+    }
+
+    cJSON *user = findUserObject(root, name);
+    if (!user) {
+        cJSON_Delete(root);
+        *error = CALENDAR_USER_NOT_FOUND;
+        return nullptr;
+    }
+
+    cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+    if (!events || !cJSON_IsArray(events)) {
+        cJSON_Delete(root);
+        *error = CALENDAR_EVENT_NOT_FOUND;
+        return nullptr;
+    }
+
+    int index = findEventIndex(events, eventId);
+    if (index == -1) {
+        cJSON_Delete(root);
+        *error = CALENDAR_EVENT_NOT_FOUND;
+        return nullptr;
+    }
+
+    // Extract event information
+    cJSON *eventObj = cJSON_GetArrayItem(events, index);
+    CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+    if (!event) {
+        cJSON_Delete(root);
+        *error = CALENDAR_MEMORY_ALLOC_FAILED;
+        return nullptr;
+    }
+
+    cJSON *item = nullptr;
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "id");
+    event->id = (item && cJSON_IsNumber(item)) ? item->valueint : -1;
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "type");
+    event->type = (item && cJSON_IsNumber(item)) ? item->valueint : -1;
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "startTime");
+    event->startTime = (item && cJSON_IsNumber(item)) ? item->valuedouble : -1;
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "endTime");
+    event->endTime = (item && cJSON_IsNumber(item)) ? item->valuedouble : -1;
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "bundlename");
+    if (item && cJSON_IsString(item)) {
+        if (strcpy_s(event->bundlename, sizeof(event->bundlename), item->valuestring) != EOK) {
+            cJSON_Delete(root);
+            *error = CALENDAR_MEMORY_ALLOC_FAILED;
+            return nullptr;
+        }
+    }
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "isAllDay");
+    event->isAllDay = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "hasReminder");
+    event->hasReminder = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "isRepeat");
+    event->isRepeat = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "recurrenceFrequency");
+    event->recurrenceFrequency = (item && cJSON_IsNumber(item)) ? item->valuedouble : -1;
+
+    item = cJSON_GetObjectItemCaseSensitive(eventObj, "eventContent");
+    if (item && cJSON_IsString(item)) {
+        if (strcpy_s(event->eventContent, sizeof(event->eventContent), item->valuestring) != EOK) {
+            cJSON_Delete(root);
+            *error = CALENDAR_MEMORY_ALLOC_FAILED;
+            return nullptr;
+        }
+    }
+
+    cJSON_Delete(root);
+    root = nullptr;
+    *error = CALENDAR_SUCCESS;
+    return event;
+}
+
+// Batch get all events of a user
+CalendarEventArray *CalendarGetEvents(const char *filename, const char *name, CalendarError *error)
+{
+    // Parameter validation
+    if (!filename || !name || !error) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "AppendEvents Invalid parameter");
+        *error = CALENDAR_INVALID_PARAMETER;
+        return nullptr;
+    }
+    *error = CALENDAR_SUCCESS;
+
+    // Read JSON file content
+    char *jsonData = ReadJsonFile(filename, error);
+    if (!jsonData || *error != CALENDAR_SUCCESS) {
+        return nullptr;
+    }
+
+    // Parse JSON
+    cJSON *root = cJSON_Parse(jsonData);
+    free(jsonData);  // Free JSON string memory
+    jsonData = nullptr;
+    if (!root) {
+        *error = CALENDAR_JSON_PARSE_ERROR;
+        return nullptr;
+    }
+
+    // Find user object
+    cJSON *user = findUserObject(root, name);
+    if (!user) {
+        cJSON_Delete(root);
+        *error = CALENDAR_USER_NOT_FOUND;
+        return nullptr;
+    }
+
+    // Get events array
+    cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+    if (!events || !cJSON_IsArray(events)) {
+        cJSON_Delete(root);
+        *error = CALENDAR_EVENT_NOT_FOUND;
+        return nullptr;
+    }
+
+    // Get event count
+    int eventCount = cJSON_GetArraySize(events);
+    if (eventCount <= 0) {
+        cJSON_Delete(root);
+        *error = CALENDAR_EVENT_NOT_FOUND;
+        return nullptr;
+    }
+
+    // Allocate memory for event array
+    CalendarEvent *eventList = (CalendarEvent *)malloc(sizeof(CalendarEvent) * eventCount);
+    if (!eventList) {
+        cJSON_Delete(root);
+        *error = CALENDAR_MEMORY_ALLOC_FAILED;
+        return nullptr;
+    }
+
+    // Allocate memory for event array structure
+    CalendarEventArray *eventArray = (CalendarEventArray *)malloc(sizeof(CalendarEventArray));
+    if (!eventArray) {
+        free(eventList);
+        cJSON_Delete(root);
+        *error = CALENDAR_MEMORY_ALLOC_FAILED;
+        return nullptr;
+    }
+
+    // Parse events one by one
+    cJSON *eventObj = nullptr;
+    int i = 0;
+    cJSON_ArrayForEach(eventObj, events)
+    {
+        cJSON *item = nullptr;
+
+        // Parse event ID
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "id");
+        eventList[i].id = (item && cJSON_IsNumber(item)) ? item->valueint : -1;
+
+        // Parse event type
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "type");
+        eventList[i].type = (item && cJSON_IsNumber(item)) ? item->valueint : -1;
+
+        // Parse start time
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "startTime");
+        eventList[i].startTime = (item && cJSON_IsNumber(item)) ? (int64_t)item->valuedouble : -1;
+
+        // Parse end time
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "endTime");
+        eventList[i].endTime = (item && cJSON_IsNumber(item)) ? (int64_t)item->valuedouble : -1;
+
+        // Parse bundlename
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "bundlename");
+        if (item && cJSON_IsString(item)) {
+            if (strcpy_s(eventList[i].bundlename, sizeof(eventList[i].bundlename), item->valuestring) != 0) {
+                HILOG_ERROR(HILOG_MODULE_ACE, "strcpy_s faild");
+            }
+        } else {
+            memset_s(eventList[i].bundlename, sizeof(eventList[i].bundlename), 0, sizeof(eventList[i].bundlename));
+        }
+
+        // Parse isAllDay
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "isAllDay");
+        eventList[i].isAllDay = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+        // Parse hasReminder
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "hasReminder");
+        eventList[i].hasReminder = (item && cJSON_IsBool(item)) ? item->valueint : false;
+
+        // Parse isRepeat
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "isRepeat");
+        eventList[i].isRepeat = (item && cJSON_IsBool(item)) ? (int64_t)item->valuedouble : false;
+
+        // Parse recurrenceFrequency
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "recurrenceFrequency");
+        eventList[i].recurrenceFrequency = (item && cJSON_IsNumber(item)) ? (int64_t)item->valuedouble : -1;
+
+        // Parse eventContent
+        item = cJSON_GetObjectItemCaseSensitive(eventObj, "eventContent");
+        if (item && cJSON_IsString(item)) {
+            if(strcpy_s((char *)eventList[i].eventContent, sizeof(eventList[i].eventContent), item->valuestring) != 0) {
+                HILOG_ERROR(HILOG_MODULE_ACE, "strcpy_s faild");
+            }
+        } else {
+            memset_s(
+                eventList[i].eventContent, sizeof(eventList[i].eventContent), 0, sizeof(eventList[i].eventContent));
+        }
+        i++;
+    }
+
+    // Fill event array structure
+    eventArray->events = eventList;
+    eventArray->count = eventCount;
+
+    // Clean up resources
+    cJSON_Delete(root);
+
+    *error = CALENDAR_SUCCESS;
+    return eventArray;
+}
+
+// 5. Delete single event
+CalendarError CalendarDeleteEvent(const char *filename, const char *name, int eventId)
+{
+    if (!filename || !name) {
+        return CALENDAR_INVALID_PARAMETER;
+    }
+
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    cJSON *root = getOrCreateRoot(filename, &error);
+    if (!root || error != CALENDAR_SUCCESS) {
+        return error;
+    }
+
+    cJSON *user = findUserObject(root, name);
+    if (!user) {
+        cJSON_Delete(root);
+        return CALENDAR_USER_NOT_FOUND;
+    }
+
+    cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+    if (!events || !cJSON_IsArray(events)) {
+        cJSON_Delete(root);
+        return CALENDAR_EVENT_NOT_FOUND;
+    }
+
+    int index = findEventIndex(events, eventId);
+    if (index == -1) {
+        cJSON_Delete(root);
+        return CALENDAR_EVENT_NOT_FOUND;
+    }
+
+    // Delete event
+    cJSON_DeleteItemFromArray(events, index);
+    error = writeJsonFile(filename, root);
+    cJSON_Delete(root);
+
+    return error;
+}
+
+// 6. Batch delete events
+CalendarError CalendarDeleteEvents(const char *filename, const char *name, const int *eventIds, size_t idCount)
+{
+    if (!filename || !name || !eventIds || idCount == 0) {
+        return CALENDAR_INVALID_PARAMETER;
+    }
+
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    cJSON *root = getOrCreateRoot(filename, &error);
+    if (!root || error != CALENDAR_SUCCESS) {
+        return error;
+    }
+
+    cJSON *user = findUserObject(root, name);
+    if (!user) {
+        cJSON_Delete(root);
+        return CALENDAR_USER_NOT_FOUND;
+    }
+
+    cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+    if (!events || !cJSON_IsArray(events)) {
+        cJSON_Delete(root);
+        return CALENDAR_EVENT_NOT_FOUND;
+    }
+
+    // Mark indices of events to delete (sorted from largest to smallest to avoid index changes)
+    int *indices = (int *)malloc(sizeof(int) * idCount);
+    if (!indices) {
+        cJSON_Delete(root);
+        return CALENDAR_MEMORY_ALLOC_FAILED;
+    }
+
+    size_t foundCount = 0;
+    for (size_t i = 0; i < idCount; i++) {
+        int index = findEventIndex(events, eventIds[i]);
+        if (index != -1) {
+            indices[foundCount++] = index;
+        }
+    }
+
+    // Delete from largest index to smallest to avoid index shifting issues
+    for (int i = foundCount - 1; i >= 0; i--) {
+        cJSON_DeleteItemFromArray(events, indices[i]);
+    }
+
+    free(indices);
+    error = writeJsonFile(filename, root);
+    cJSON_Delete(root);
+
+    return error;
+}
+
+// 7. Modify/add event (using CalendarEvent struct for parameters)
+CalendarError CalendarUpdateEvent(const char *filename, const char *name, const CalendarEvent *event)
+{
+    if (!filename || !name || !event) {
+        return CALENDAR_INVALID_PARAMETER;
+    }
+
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    cJSON *root = getOrCreateRoot(filename, &error);
+    if (!root || error != CALENDAR_SUCCESS) {
+        return error;
+    }
+
+    cJSON *user = findUserObject(root, name);
+    if (!user) {
+        cJSON_Delete(root);
+        return CALENDAR_USER_NOT_FOUND;
+    }
+
+    cJSON *events = cJSON_GetObjectItemCaseSensitive(user, "events");
+    if (!events || !cJSON_IsArray(events)) {
+        events = cJSON_CreateArray();
+        if (!events) {
+            cJSON_Delete(root);
+            return CALENDAR_MEMORY_ALLOC_FAILED;
+        }
+        cJSON_AddItemToObject(user, "events", events);
+    }
+
+    // Find if event exists
+    int index = findEventIndex(events, event->id);
+    if (index != -1) {
+        // Event exists, delete old event first
+        cJSON_DeleteItemFromArray(events, index);
+        // Add new event (whether update or add)
+        cJSON *eventJson = createEventJson(event);
+        if (!eventJson) {
+            cJSON_Delete(root);
+            return CALENDAR_MEMORY_ALLOC_FAILED;
+        }
+        cJSON_AddItemToArray(events, eventJson);
+        error = writeJsonFile(filename, root);
+    } else {
+        error = CALENDAR_EVENT_NOT_FOUND;
+    }
+
+    cJSON_Delete(root);
+    return error;
+}
+
+CalendarError CalendarUpdateEvents(const char *filename, const char *name, const CalendarEventArray *events)
+{
+    // Parameter validity check
+    if (!filename || !name || !events || !events->events || events->count == 0) {
+        return CALENDAR_INVALID_PARAMETER;
+    }
+
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    cJSON *root = getOrCreateRoot(filename, &error);
+    if (!root || error != CALENDAR_SUCCESS) {
+        return error;
+    }
+
+    // Find user object
+    cJSON *user = findUserObject(root, name);
+    if (!user) {
+        cJSON_Delete(root);
+        return CALENDAR_USER_NOT_FOUND;
+    }
+
+    // Get or create events array
+    cJSON *eventsArray = cJSON_GetObjectItemCaseSensitive(user, "events");
+    if (!eventsArray || !cJSON_IsArray(eventsArray)) {
+        eventsArray = cJSON_CreateArray();
+        if (!eventsArray) {
+            cJSON_Delete(root);
+            return CALENDAR_MEMORY_ALLOC_FAILED;
+        }
+        cJSON_AddItemToObject(user, "events", eventsArray);
+    }
+
+    // Record whether any events were successfully updated
+    bool hasUpdated = false;
+
+    // Iterate through all events to update
+    for (size_t i = 0; i < events->count; i++) {
+        const CalendarEvent *event = &events->events[i];
+
+        // Find event position in JSON array
+        int index = findEventIndex(eventsArray, event->id);
+        if (index != -1) {
+            // Found event, delete old version first
+            cJSON_DeleteItemFromArray(eventsArray, index);
+
+            // Create new event JSON object
+            cJSON *eventJson = createEventJson(event);
+            if (!eventJson) {
+                cJSON_Delete(root);
+                return CALENDAR_MEMORY_ALLOC_FAILED;
+            }
+
+            // Add updated event
+            cJSON_AddItemToArray(eventsArray, eventJson);
+            hasUpdated = true;
+        }
+    }
+
+    // If any events were updated, write to file
+    if (hasUpdated) {
+        error = writeJsonFile(filename, root);
+    } else {
+        // No events found to update
+        error = CALENDAR_EVENT_NOT_FOUND;
+    }
+
+    // Clean up resources
+    cJSON_Delete(root);
+    return error;
+}
+
+// 8. Get user information
+CalendarAccount *GetUserInfo(const char *filename, const char *name, CalendarError *error)
+{
+    if (!filename || !name || !error) {
+        *error = CALENDAR_INVALID_PARAMETER;
+        return nullptr;
+    }
+
+    char *jsonData = ReadJsonFile(filename, error);
+    if (!jsonData || *error != CALENDAR_SUCCESS) {
+        return nullptr;
+    }
+
+    cJSON *root = cJSON_Parse(jsonData);
+    free(jsonData);
+    jsonData = nullptr;
+    if (!root) {
+        *error = CALENDAR_JSON_PARSE_ERROR;
+        return nullptr;
+    }
+
+    cJSON *user = findUserObject(root, name);
+    if (!user) {
+        cJSON_Delete(root);
+        *error = CALENDAR_USER_NOT_FOUND;
+        return nullptr;
+    }
+
+    cJSON *accountObj = cJSON_GetObjectItemCaseSensitive(user, "CalendarAccount");
+    if (!accountObj) {
+        cJSON_Delete(root);
+        *error = CALENDAR_JSON_PARSE_ERROR;
+        return nullptr;
+    }
+
+    // Allocate memory for account information structure
+    CalendarAccount *account = (CalendarAccount *)malloc(sizeof(CalendarAccount));
+    if (!account) {
+        cJSON_Delete(root);
+        *error = CALENDAR_MEMORY_ALLOC_FAILED;
+        return nullptr;
+    }
+    memset_s(account, sizeof(CalendarAccount), 0, sizeof(CalendarAccount));
+
+    // Extract account information
+    cJSON *item = cJSON_GetObjectItemCaseSensitive(accountObj, "name");
+    if (item && cJSON_IsString(item)) {
+        account->name = (char *)ace_malloc(strlen(item->valuestring) + 1);
+        if (!account->name) {
+            free(account);
+            cJSON_Delete(root);
+            *error = CALENDAR_MEMORY_ALLOC_FAILED;
+            return nullptr;
+        }
+        memset_s(account->name, (strlen(item->valuestring) + 1), 0, (strlen(item->valuestring) + 1));
+        if(memcpy_s(account->name,
+            strlen(item->valuestring) + 1, item->valuestring, strlen(item->valuestring) + 1) != EOK) {
+            HILOG_ERROR(HILOG_MODULE_ACE, "memcpy_s faild");
+        }
+    }
+
+    item = cJSON_GetObjectItemCaseSensitive(accountObj, "type");
+    if (item && cJSON_IsString(item)) {
+        account->type = (char *)ace_malloc(strlen(item->valuestring) + 1);
+        if (!account->type) {
+            ace_free(account->name);
+            free(account);
+            cJSON_Delete(root);
+            *error = CALENDAR_MEMORY_ALLOC_FAILED;
+            return nullptr;
+        }
+        memset_s(account->type, (strlen(item->valuestring) + 1), 0, (strlen(item->valuestring) + 1));
+        if(memcpy_s(account->type, strlen(item->valuestring) + 1, item->valuestring, strlen(item->valuestring) + 1) != EOK) {
+            HILOG_ERROR(HILOG_MODULE_ACE, "memcpy_s faild");
+        }
+    }
+
+    item = cJSON_GetObjectItemCaseSensitive(accountObj, "displayName");
+    if (item && cJSON_IsString(item)) {
+        account->displayName = (char *)ace_malloc(strlen(item->valuestring) + 1);
+        if (!account->displayName) {
+            ace_free(account->name);
+            ace_free(account->type);
+            free(account);
+            cJSON_Delete(root);
+            *error = CALENDAR_MEMORY_ALLOC_FAILED;
+            return nullptr;
+        }
+        memset_s(account->displayName, (strlen(item->valuestring) + 1), 0, (strlen(item->valuestring) + 1));
+        if(memcpy_s(account->displayName,
+            strlen(item->valuestring) + 1, item->valuestring, strlen(item->valuestring) + 1) != EOK) {
+            HILOG_ERROR(HILOG_MODULE_ACE, "memcpy_s faild");
+        }
+    }
+
+    cJSON_Delete(root);
+    *error = CALENDAR_SUCCESS;
+    return account;
+}
+
+// Free event memory
+void FreeCalendarEvent(CalendarEvent *event)
+{
+    if (event) {
+        free(event);
+    }
+}
+
+// Helper function to free CalendarEventArray resources
+void FreeCalendarEventArray(CalendarEventArray *array)
+{
+    if (array) {
+        free(static_cast<void*>(array->events));  // Free event array
+        free(array);                  // Free array structure
+    }
+}
+
+// Convert timestamp to datetime string
+// Return 0 on success, -1 on failure
+int TimestampToDatetime(time_t timestamp, char *datetimeStr, size_t maxLen)
+{
+    if (datetimeStr == nullptr || maxLen < 20) {  // At least 20 bytes needed for "YYYY-MM-DD HH:MM:SS"
+        return -1;
+    }
+
+    struct tm *tminfo = localtime(&timestamp);  // Convert to local time
+    if (tminfo == nullptr) {
+        return -1;
+    }
+
+    // Format datetime string
+    strftime(datetimeStr, maxLen, "%Y-%m-%d %H:%M:%S", tminfo);
+    return 0;
+}
+
+}  // namespace ACELite
+}  // namespace OHOS
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_manager.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_manager.h
new file mode 100644 (file)
index 0000000..3132909
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef CALENDAR_MANAGER_H
+#define CALENDAR_MANAGER_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <ctime>
+
+namespace OHOS {
+namespace ACELite {
+// Error code definitions
+typedef enum {
+    CALENDAR_SUCCESS = 0,
+    CALENDAR_FILE_NOT_FOUND,
+    CALENDAR_FILE_OPEN_FAILED,
+    CALENDAR_JSON_PARSE_ERROR,
+    CALENDAR_USER_NOT_FOUND,
+    CALENDAR_EVENT_NOT_FOUND,
+    CALENDAR_EVENT_ID_EXISTS,
+    CALENDAR_USER_INFO_MISMATCH,
+    CALENDAR_MEMORY_ALLOC_FAILED,
+    CALENDAR_INVALID_PARAMETER,
+    CALENDAR_FILE_WRITE_FAILED,
+    CALENDAR_EVENT_ID_ALLOC_FAILED,
+    CALENDAR_ERROR_MAX
+} CalendarError;
+
+// Calendar event structure
+typedef struct {
+    int id;
+    int type;
+    int64_t startTime;
+    int64_t endTime;
+    bool isAllDay;
+    bool hasReminder;
+    bool isRepeat;
+    int64_t recurrenceFrequency;
+    char bundlename[64];  // String passed from outside, internal code does not handle its release
+    char eventContent[256];
+} CalendarEvent;
+
+// Batch event array structure
+typedef struct {
+    CalendarEvent *events;  // Pointer to event array
+    size_t count;           // Number of events
+} CalendarEventArray;
+
+// Calendar account structure
+typedef struct {
+    char *name;
+    char *type;
+    char *displayName;
+} CalendarAccount;
+
+// Error message retrieval interface
+const char *GetCalendarErrorString(CalendarError error);
+
+// 1. Create or append user
+// Return value: Returns username string on success, nullptr on failure
+const char *CreateOrAppendUser(
+    const char *filename, const char *name, const char *type, const char *displayName, CalendarError *error);
+
+// 2. Append single event (using CalendarEvent struct for parameters)
+CalendarError AppendEvent(const char *filename, const char *name, const CalendarEvent *event);
+
+// 3. Append multiple events
+CalendarError AppendEvents(const char *filename, const char *name, const CalendarEventArray *eventArray);
+
+// 4. Get user's specific event
+// Return value: Returns dynamically allocated CalendarEvent on success,
+// needs to be released by calling FreeCalendarEvent
+CalendarEvent *CalendarGetEvent(const char *filename, const char *name, int eventId, CalendarError *error);
+
+// Batch get all events of a user
+CalendarEventArray *CalendarGetEvents(const char *filename, const char *name, CalendarError *error);
+
+// 5. Delete single event
+CalendarError CalendarDeleteEvent(const char *filename, const char *name, int eventId);
+
+// 6. Batch delete events
+CalendarError CalendarDeleteEvents(const char *filename, const char *name, const int *eventIds, size_t idCount);
+
+// 7. Modify/add event (using CalendarEvent struct for parameters)
+CalendarError CalendarUpdateEvent(const char *filename, const char *name, const CalendarEvent *event);
+
+CalendarError CalendarUpdateEvents(const char *filename, const char *name, const CalendarEventArray *events);
+
+// 8. Get user information
+// Return value: Returns dynamically allocated CalendarAccount on success,
+CalendarAccount *GetUserInfo(const char *filename, const char *name, CalendarError *error);
+
+// Convert timestamp to datetime string
+// Return 0 on success, -1 on failure
+int TimestampToDatetime(time_t timestamp, char *datetimeStr, size_t maxLen);
+
+// Memory release interfaces
+void FreeCalendarEvent(CalendarEvent *event);
+}  // namespace ACELite
+}  // namespace OHOS
+#endif  // CALENDAR_MANAGER_H
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_module.cpp b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_module.cpp
new file mode 100644 (file)
index 0000000..a126972
--- /dev/null
@@ -0,0 +1,1194 @@
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#include <cstring>
+#include <climits>
+#include "calendar_manager.h"
+#include "event_id_manager.h"
+#include "ability_env.h"
+#include "calendar_utils.h"
+#include "ace_log.h"
+#include "calendar_module.h"
+namespace OHOS {
+namespace ACELite {
+// Global variable for calendar file path
+std::string g_canlendarFilePath = "/user/app/calendar.json";
+
+// Module constant definitions
+const char *const CalendarModule::MODULE_NAME = "calendar";
+const char *const CalendarModule::CREATE_CALENDAR = "createCalendar";
+const char *const CalendarModule::DELETE_CALENDAR = "deleteCalendar";
+const char *const CalendarModule::GET_CALENDAR = "getCalendar";
+const char *const CalendarModule::ADD_EVENT = "addEvent";
+const char *const CalendarModule::ADD_EVENTS = "addEvents";
+const char *const CalendarModule::DELETE_EVENT = "deleteEvent";
+const char *const CalendarModule::DELETE_EVENTS = "deleteEvents";
+const char *const CalendarModule::UPDATE_EVENT = "updateEvent";
+const char *const CalendarModule::UPDATE_EVENTS = "updateEvents";
+const char *const CalendarModule::GET_EVENT = "getEvent";
+const char *const CalendarModule::GET_EVENTS = "getEvents";
+const char *const CalendarModule::GET_ACCOUNT = "getAccount";
+const char *const CalendarModule::GET_CONFIG = "getconfig";
+const char *const CalendarModule::SET_CONFIG = "setconfig";
+
+// Static member variable for callback data
+CalendarCallback *CalendarModule::callbackData_ = nullptr;
+
+// Module initialization
+void CalendarModule::Init(JSIValue exports)
+{}
+
+void InitCalendarModule(JSIValue exports)
+{
+    // Register Calendar module API functions
+    JSI::SetModuleAPI(exports, CalendarModule::CREATE_CALENDAR, CalendarModule::CreateCalendar);
+    JSI::SetModuleAPI(exports, CalendarModule::DELETE_CALENDAR, CalendarModule::DeleteCalendar);
+    JSI::SetModuleAPI(exports, CalendarModule::GET_CALENDAR, CalendarModule::GetCalendar);
+}
+
+// Helper function: Convert JS object to CalendarAccount
+bool CalendarModule::ConvertToCalendarAccount(const JSIValue jsAccount, CalendarAccount &account)
+{
+    if (!JSI::ValueIsObject(jsAccount)) {
+        return false;
+    }
+
+    // Extract name property
+    JSIValue nameVal = JSI::GetNamedProperty(jsAccount, "name");
+    if (JSI::ValueIsString(nameVal)) {
+        account.name = JSI::ValueToString(nameVal);
+    } else {
+        JSI::ReleaseValue(nameVal);
+        return false;
+    }
+    JSI::ReleaseValue(nameVal);
+
+    // Extract type property
+    JSIValue typeVal = JSI::GetNamedProperty(jsAccount, "type");
+    if (JSI::ValueIsString(typeVal)) {
+        account.type = JSI::ValueToString(typeVal);
+    } else {
+        JSI::ReleaseValue(typeVal);
+        ace_free(static_cast<void*>(account.name));
+        return false;
+    }
+    JSI::ReleaseValue(typeVal);
+
+    // Extract displayName property
+    JSIValue displayNameVal = JSI::GetNamedProperty(jsAccount, "displayName");
+    if (JSI::ValueIsString(displayNameVal)) {
+        account.displayName = JSI::ValueToString(displayNameVal);
+    } else {
+        JSI::ReleaseValue(displayNameVal);
+        ace_free(static_cast<void*>(account.name));
+        ace_free(static_cast<void*>(account.type));
+        return false;
+    }
+    JSI::ReleaseValue(displayNameVal);
+
+    return true;
+}
+
+// Helper function: Convert CalendarEvent to JS object
+JSIValue CalendarModule::ConvertToJSEvent(const CalendarEvent &event)
+{
+    JSIValue jsEvent = JSI::CreateObject();
+
+    JSI::SetNamedProperty(jsEvent, "id", JSI::CreateNumber(event.id));
+    JSI::SetNamedProperty(jsEvent, "type", JSI::CreateNumber(event.type));
+    JSI::SetNamedProperty(jsEvent, "startTime", JSI::CreateNumber(event.startTime));
+    JSI::SetNamedProperty(jsEvent, "endTime", JSI::CreateNumber(event.endTime));
+    JSI::SetNamedProperty(jsEvent, "bundlename", JSI::CreateString(event.bundlename));
+    JSI::SetNamedProperty(jsEvent, "isAllDay", JSI::CreateBoolean(event.isAllDay));
+    JSI::SetNamedProperty(jsEvent, "hasReminder", JSI::CreateBoolean(event.hasReminder));
+    JSI::SetNamedProperty(jsEvent, "isRepeat", JSI::CreateBoolean(event.isRepeat));
+    JSI::SetNamedProperty(jsEvent, "recurrenceFrequency", JSI::CreateNumber(event.recurrenceFrequency));
+    JSI::SetNamedProperty(jsEvent, "eventContent", JSI::CreateString(event.eventContent));
+
+    return jsEvent;
+}
+
+// Helper function: Convert CalendarAccount to JS object
+JSIValue CalendarModule::ConvertToJSAccount(const CalendarAccount &account)
+{
+    JSIValue jsAccount = JSI::CreateObject();
+
+    if (account.name) {
+        JSI::SetNamedProperty(jsAccount, "name", JSI::CreateString(account.name));
+    }
+    if (account.type) {
+        JSI::SetNamedProperty(jsAccount, "type", JSI::CreateString(account.type));
+    }
+    if (account.displayName) {
+        JSI::SetNamedProperty(jsAccount, "displayName", JSI::CreateString(account.displayName));
+    }
+
+    return jsAccount;
+}
+
+// Free callback data
+void CalendarModule::FreeCallbackData(CalendarCallback *callbackData)
+{
+    if (callbackData) {
+        if (callbackData->account.name) {
+            ace_free(callbackData->account.name);
+            callbackData->account.name = nullptr;
+        }
+        if (callbackData->account.type) {
+            ace_free(callbackData->account.type);
+            callbackData->account.type = nullptr;
+        }
+        if (callbackData->account.displayName) {
+            ace_free(callbackData->account.displayName);
+            callbackData->account.displayName = nullptr;
+        }
+        delete callbackData;
+    }
+}
+
+// Create calendar
+JSIValue CalendarModule::CreateCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    if (argsNum < ARGC_TWO || !JSI::ValueIsObject(args[0]) || !JSI::ValueIsFunction(args[1])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for createCalendar");
+        return JSI::CreateUndefined();
+    }
+
+    // Create callback data
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    callbackData->account.name = nullptr;
+    callbackData->account.displayName = nullptr;
+    callbackData->account.type = nullptr;
+    if (!callbackData) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for callback data");
+        return JSI::CreateUndefined();
+    }
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[1]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    // Convert calendar account information
+    if (!ConvertToCalendarAccount(args[0], callbackData->account)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Failed to convert to CalendarAccount");
+        FreeCallbackData(callbackData);
+        JSI::ReleaseValue(callbackData->callback);
+        JSI::ReleaseValue(callbackData->jsCtx);
+        return JSI::CreateUndefined();
+    }
+    // Dispatch asynchronous work
+    JsAsyncWork::DispatchAsyncWork(CreateCalendarCallback, static_cast<void *>(callbackData));
+
+    return JSI::CreateUndefined();
+}
+
+// Asynchronous callback for creating calendar
+void CalendarModule::CreateCalendarCallback(void *data)
+{
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        JSI::ReleaseValue(callbackData->callback);
+        JSI::ReleaseValue(callbackData->jsCtx);
+        return;
+    }
+    // Call calendar management tool to create user
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    const char *result = CreateOrAppendUser(GetCanlendarFilePath(),
+        callbackData->account.name,
+        callbackData->account.type,
+        callbackData->account.displayName,
+        &error);
+    // Prepare callback parameters
+    JSIValue args[ARGC_TWO];
+    JSIValue addEvent;
+    JSIValue addEvents;
+    JSIValue deleteEvent;
+    JSIValue deleteEvents;
+    JSIValue updateEvent;
+    JSIValue updateEvents;
+    JSIValue getEvent;
+    JSIValue getEvents;
+    JSIValue getAccount;
+    JSIValue getConfig;
+    JSIValue setConfig;
+    JSIValue calendarObj;
+    if (error == CALENDAR_SUCCESS && result != nullptr) {
+        // Success: first parameter is null, second is calendar object
+        args[0] = JSI::CreateNull();
+        // Create calendar object
+        calendarObj = JSI::CreateObject();
+        addEvent = JSI::CreateFunction(CalendarModule::AddEvent);
+        addEvents = JSI::CreateFunction(CalendarModule::AddEvents);
+        deleteEvent = JSI::CreateFunction(CalendarModule::DeleteEvent);
+        deleteEvents = JSI::CreateFunction(CalendarModule::DeleteEvents);
+        updateEvent = JSI::CreateFunction(CalendarModule::UpdateEvent);
+        updateEvents = JSI::CreateFunction(CalendarModule::UpdateEvents);
+        getEvent = JSI::CreateFunction(CalendarModule::GetEvent);
+        getEvents = JSI::CreateFunction(CalendarModule::GetEvents);
+        getAccount = JSI::CreateFunction(CalendarModule::GetAccount);
+        getConfig = JSI::CreateFunction(CalendarModule::GetConfig);
+        setConfig = JSI::CreateFunction(CalendarModule::SetConfig);
+        JSI::SetNamedProperty(calendarObj, ADD_EVENT, addEvent);
+        JSI::SetNamedProperty(calendarObj, ADD_EVENTS, addEvents);
+        JSI::SetNamedProperty(calendarObj, DELETE_EVENT, deleteEvent);
+        JSI::SetNamedProperty(calendarObj, DELETE_EVENTS, deleteEvents);
+        JSI::SetNamedProperty(calendarObj, UPDATE_EVENT, updateEvent);
+        JSI::SetNamedProperty(calendarObj, UPDATE_EVENTS, updateEvents);
+        JSI::SetNamedProperty(calendarObj, GET_EVENT, getEvent);
+        JSI::SetNamedProperty(calendarObj, GET_EVENTS, getEvents);
+        JSI::SetNamedProperty(calendarObj, GET_ACCOUNT, getAccount);
+        JSI::SetNamedProperty(calendarObj, GET_CONFIG, getConfig);
+        JSI::SetNamedProperty(calendarObj, SET_CONFIG, setConfig);
+        // Store calendar account information;
+        args[1] = calendarObj;
+        if (callbackData_) {
+            FreeCallbackData(callbackData_);
+            callbackData_ = nullptr;
+        }
+        callbackData_ = callbackData;
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(args[0],
+            args[1],
+            callbackData->callback,
+            callbackData->jsCtx,
+            addEvent,
+            addEvents,
+            deleteEvent,
+            deleteEvents,
+            updateEvent,
+            updateEvents,
+            getConfig,
+            setConfig,
+            getEvent,
+            getEvents,
+            getAccount,
+            ARGS_END);
+    } else {
+        // Failure: first parameter is error message, second is null
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        args[1] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+        FreeCallbackData(callbackData);
+    }
+}
+
+// Delete calendar
+JSIValue CalendarModule::DeleteCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    if (callbackData_) {
+        FreeCallbackData(callbackData_);
+        callbackData_ = nullptr;
+    }
+    return JSI::CreateUndefined();
+}
+
+// Asynchronous callback for deleting calendar
+void CalendarModule::DeleteCalendarCallback(void *data)
+{
+    // Implement actual logic and callback handling for deleting calendar
+}
+
+// Get default calendar
+JSIValue CalendarModule::GetCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    if (argsNum < 1 || !JSI::ValueIsFunction(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for getCalendar");
+        return JSI::CreateUndefined();
+    }
+    // Create callback data
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    callbackData->account.name = nullptr;
+    callbackData->account.displayName = nullptr;
+    callbackData->account.type = nullptr;
+    if (!callbackData) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for callback data");
+        return JSI::CreateUndefined();
+    }
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[0]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(GetCalendarCallback, static_cast<void *>(callbackData));
+
+    return JSI::CreateUndefined();
+}
+
+// Asynchronous callback for getting default calendar
+void CalendarModule::GetCalendarCallback(void *data)
+{
+    // Implement actual logic and callback handling for getting default calendar
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    CalendarAccount *account = GetUserInfo(GetCanlendarFilePath(), "default", &error);
+    if (account) {
+        callbackData->account.type = account->type;
+        callbackData->account.name = account->name;
+        callbackData->account.displayName = account->displayName;
+        free(account);
+    }
+    // Prepare callback parameters
+    JSIValue args[ARGC_TWO];
+    JSIValue addEvent;
+    JSIValue addEvents;
+    JSIValue deleteEvent;
+    JSIValue deleteEvents;
+    JSIValue updateEvent;
+    JSIValue updateEvents;
+    JSIValue getEvent;
+    JSIValue getEvents;
+    JSIValue getAccount;
+    JSIValue getConfig;
+    JSIValue setConfig;
+    if (error == CALENDAR_SUCCESS) {
+        // Success: first parameter is null, second is calendar object
+        args[0] = JSI::CreateNull();
+        // Create calendar object
+        JSIValue calendarObj = JSI::CreateObject();
+        addEvent = JSI::CreateFunction(CalendarModule::AddEvent);
+        addEvents = JSI::CreateFunction(CalendarModule::AddEvents);
+        deleteEvent = JSI::CreateFunction(CalendarModule::DeleteEvent);
+        deleteEvents = JSI::CreateFunction(CalendarModule::DeleteEvents);
+        updateEvent = JSI::CreateFunction(CalendarModule::UpdateEvent);
+        updateEvents = JSI::CreateFunction(CalendarModule::UpdateEvents);
+        getEvent = JSI::CreateFunction(CalendarModule::GetEvent);
+        getEvents = JSI::CreateFunction(CalendarModule::GetEvents);
+        getAccount = JSI::CreateFunction(CalendarModule::GetAccount);
+        getConfig = JSI::CreateFunction(CalendarModule::GetConfig);
+        setConfig = JSI::CreateFunction(CalendarModule::SetConfig);
+        JSI::SetNamedProperty(calendarObj, ADD_EVENT, addEvent);
+        JSI::SetNamedProperty(calendarObj, ADD_EVENTS, addEvents);
+        JSI::SetNamedProperty(calendarObj, DELETE_EVENT, deleteEvent);
+        JSI::SetNamedProperty(calendarObj, DELETE_EVENTS, deleteEvents);
+        JSI::SetNamedProperty(calendarObj, UPDATE_EVENT, updateEvent);
+        JSI::SetNamedProperty(calendarObj, UPDATE_EVENTS, updateEvents);
+        JSI::SetNamedProperty(calendarObj, GET_EVENT, getEvent);
+        JSI::SetNamedProperty(calendarObj, GET_EVENTS, getEvents);
+        JSI::SetNamedProperty(calendarObj, GET_ACCOUNT, getAccount);
+        JSI::SetNamedProperty(calendarObj, GET_CONFIG, getConfig);
+        JSI::SetNamedProperty(calendarObj, SET_CONFIG, setConfig);
+        // Store calendar account information;
+        args[1] = calendarObj;
+        if (callbackData_) {
+            FreeCallbackData(callbackData_);
+            callbackData_ = nullptr;
+        }
+        callbackData_ = callbackData;
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(args[0],
+            args[1],
+            addEvent,
+            addEvents,
+            deleteEvent,
+            deleteEvents,
+            updateEvent,
+            updateEvents,
+            getConfig,
+            setConfig,
+            getEvent,
+            getEvents,
+            getAccount,
+            ARGS_END);
+    } else {
+        // Failure: first parameter is error message, second is null
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        args[1] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+        FreeCallbackData(callbackData);
+    }
+}
+
+// Add event
+void CalendarModule::AddEventCallback(void *data)
+{
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    int id = AllocateAndSetCalendarEvent(callbackData->eventarray.events);
+    if (id > 0) {
+        error = AppendEvent(GetCanlendarFilePath(), callbackData_->account.name, callbackData->eventarray.events);
+        if (error != CALENDAR_SUCCESS) {
+            FreeEventId(id);
+        }
+    } else {
+        error = CALENDAR_EVENT_ID_ALLOC_FAILED;
+        free(callbackData->eventarray.events);
+    }
+
+    JSIValue args[ARGC_TWO];
+    if (error == CALENDAR_SUCCESS) {
+        args[1] = JSI::CreateNumber(callbackData->eventarray.events->id);
+        args[0] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    } else {
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        args[1] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    }
+    delete callbackData;
+    callbackData = nullptr;
+}
+
+JSIValue CalendarModule::AddEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for adding a single event
+    if (callbackData_ == nullptr) {
+        return nullptr;
+    }
+    if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsObject(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for AddEvent");
+        return JSI::CreateUndefined();
+    }
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+    if (!callbackData->eventarray.events) {
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    if (strcpy_s(callbackData->eventarray.events->bundlename,
+        sizeof(callbackData->eventarray.events->bundlename),
+        GetBundleName()) != EOK) {
+        free(callbackData->eventarray.events);
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    callbackData->eventarray.events->startTime = (int64_t)JSI::GetNumberProperty(args[0], "startTime");
+    callbackData->eventarray.events->endTime = (int64_t)JSI::GetNumberProperty(args[0], "endTime");
+    callbackData->eventarray.events->type = (int)JSI::GetNumberProperty(args[0], "type");
+    char *eventContent = JSI::GetStringProperty(args[0], "eventContent");
+    if (strcpy_s(callbackData->eventarray.events->eventContent,
+        sizeof(callbackData->eventarray.events->eventContent),
+        eventContent) != EOK) {
+        free(callbackData->eventarray.events);
+        ace_free(eventContent);
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    ace_free(eventContent);
+    callbackData->eventarray.events->isAllDay = JSI::GetBooleanProperty(args[0], "isAllDay");
+    callbackData->eventarray.events->hasReminder = JSI::GetBooleanProperty(args[0], "hasReminder");
+    callbackData->eventarray.events->isRepeat = JSI::GetBooleanProperty(args[0], "isRepeat");
+    callbackData->eventarray.events->recurrenceFrequency =
+        (int64_t)JSI::GetNumberProperty(args[0], "recurrenceFrequency");
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[1]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(AddEventCallback, static_cast<void *>(callbackData));
+    return JSI::CreateUndefined();
+}
+
+// Add multiple events
+void CalendarModule::AddEventsCallback(void *data)
+{
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    CalendarError error = CALENDAR_SUCCESS;
+    int *ids = static_cast<int*>(ace_malloc(sizeof(int) * callbackData->eventarray.count));
+    if (!ids) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    for (uint32_t arrIndex = 0; arrIndex < callbackData->eventarray.count; arrIndex++) {
+        CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+        if (!event) {
+            FreeCallbackData(callbackData);
+            return;
+        }
+        if(memcpy_s(event, sizeof(CalendarEvent),
+            callbackData->eventarray.events + arrIndex, sizeof(CalendarEvent)) != EOK) {
+            FreeCallbackData(callbackData);
+            return;
+        }
+        ids[arrIndex] = AllocateAndSetCalendarEvent(event);
+        callbackData->eventarray.events[arrIndex].id = ids[arrIndex];
+        if (ids[arrIndex] <= 0) {
+            error = CALENDAR_EVENT_ID_ALLOC_FAILED;
+            for (uint32_t i = 0; i < arrIndex; i++) {
+                FreeEventId(ids[i]);
+            }
+            break;
+        }
+    }
+    ace_free(ids);
+    bool flag = true;
+    if (error == CALENDAR_SUCCESS) {
+        error = AppendEvents(GetCanlendarFilePath(), callbackData_->account.name, &callbackData->eventarray);
+        if (error != CALENDAR_SUCCESS) {
+            flag = false;
+        }
+    }
+    JSIValue args[ARGC_TWO];
+    JSIValue result[callbackData->eventarray.count];
+    if (error == CALENDAR_SUCCESS) {
+        JSIValue evnetArray = JSI::CreateArray(callbackData->eventarray.count);
+        for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+            result[evnetArrayCnt] = JSI::CreateNumber(callbackData->eventarray.events[evnetArrayCnt].id);
+            JSI::SetPropertyByIndex(evnetArray, evnetArrayCnt, result[evnetArrayCnt]);
+        }
+        args[1] = evnetArray;
+        args[0] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+            JSI::ReleaseValue(result[evnetArrayCnt]);
+        }
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    } else {
+        if (!flag) {
+            for (uint32_t arrIndex = 0; arrIndex < callbackData->eventarray.count; arrIndex++) {
+                FreeEventId(callbackData->eventarray.events[arrIndex].id);
+            }
+        }
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        args[1] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    }
+    if (callbackData->eventarray.events) {
+        free(static_cast<void*>(callbackData->eventarray.events));
+    }
+
+    delete callbackData;
+    callbackData = nullptr;
+}
+
+// Batch add events
+JSIValue CalendarModule::AddEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for batch adding events
+    if (callbackData_ == nullptr) {
+        return nullptr;
+    }
+    if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsArray(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for AddEvents");
+        return JSI::CreateUndefined();
+    }
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    uint32_t count = JSI::GetArrayLength(args[0]);
+    callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent) * count);
+    if (!callbackData->eventarray.events) {
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    for (uint32_t arrIndex = 0; arrIndex < count; arrIndex++) {
+        JSIValue point = JSI::GetPropertyByIndex(args[0], arrIndex);
+        if (strcpy_s(callbackData->eventarray.events[arrIndex].bundlename,
+            sizeof(callbackData->eventarray.events[arrIndex].bundlename),
+            GetBundleName()) != EOK) {
+            free(callbackData->eventarray.events);
+            delete callbackData;
+            return JSI::CreateUndefined();
+        }
+        callbackData->eventarray.events[arrIndex].startTime = (int64_t)JSI::GetNumberProperty(point, "startTime");
+        callbackData->eventarray.events[arrIndex].endTime = (int64_t)JSI::GetNumberProperty(point, "endTime");
+        callbackData->eventarray.events[arrIndex].type = (int)JSI::GetNumberProperty(point, "type");
+        callbackData->eventarray.events[arrIndex].isAllDay = JSI::GetBooleanProperty(point, "isAllDay");
+        callbackData->eventarray.events[arrIndex].hasReminder = JSI::GetBooleanProperty(point, "hasReminder");
+        callbackData->eventarray.events[arrIndex].isRepeat = JSI::GetBooleanProperty(point, "isRepeat");
+        callbackData->eventarray.events[arrIndex].recurrenceFrequency =
+            (int64_t)JSI::GetNumberProperty(point, "recurrenceFrequency");
+        char *eventContent = JSI::GetStringProperty(point, "eventContent");
+        if (strcpy_s(callbackData->eventarray.events[arrIndex].eventContent,
+            sizeof(callbackData->eventarray.events[arrIndex].eventContent),
+            eventContent) != EOK) {
+            free(callbackData->eventarray.events);
+            ace_free(eventContent);
+            delete callbackData;
+            return JSI::CreateUndefined();
+        }
+        ace_free(eventContent);
+        JSI::ReleaseValue(point);
+    }
+    callbackData->eventarray.count = count;
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[1]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(AddEventsCallback, static_cast<void *>(callbackData));
+    return JSI::CreateUndefined();
+}
+
+// Delete event
+void CalendarModule::DeleteEventCallback(void *data)
+{
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    error = CalendarDeleteEvent(GetCanlendarFilePath(),
+        callbackData_->account.name, callbackData->eventarray.events->id);
+    JSIValue args[ARGC_ONE];
+    if (error == CALENDAR_SUCCESS) {
+        FreeEventId(callbackData->eventarray.events->id);
+        args[0] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+    } else {
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+    }
+    free(static_cast<void*>(callbackData->eventarray.events));
+    delete callbackData;
+    callbackData = nullptr;
+}
+
+JSIValue CalendarModule::DeleteEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for deleting a single event
+    if (callbackData_ == nullptr) {
+        return nullptr;
+    }
+    if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsNumber(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for DeleteEvent");
+        return JSI::CreateUndefined();
+    }
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+    if (!callbackData->eventarray.events) {
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    callbackData->eventarray.events->id = static_cast<int64_t>(JSI::ValueToNumber(args[0]));
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[1]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(DeleteEventCallback, static_cast<void *>(callbackData));
+    return JSI::CreateUndefined();
+}
+
+// Batch delete events
+void CalendarModule::DeleteEventsCallback(void *data)
+{
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    int *eventIds = static_cast<int*>(ace_malloc(sizeof(int) * callbackData->eventarray.count));
+    if (!eventIds) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    for (uint32_t i = 0; i < callbackData->eventarray.count; i++) {
+        eventIds[i] = callbackData->eventarray.events[i].id;
+    }
+    error = CalendarDeleteEvents(GetCanlendarFilePath(),
+        callbackData_->account.name, eventIds, callbackData->eventarray.count);
+    ace_free(eventIds);
+    JSIValue args[ARGC_ONE];
+    if (error == CALENDAR_SUCCESS) {
+        for (uint32_t i = 0; i < callbackData->eventarray.count; i++) {
+            FreeEventId(callbackData->eventarray.events[i].id);
+        }
+        args[0] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+    } else {
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+    }
+    free(static_cast<void*>(callbackData->eventarray.events));
+    delete callbackData;
+    callbackData = nullptr;
+}
+
+JSIValue CalendarModule::DeleteEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for batch deleting events
+    if (callbackData_ == nullptr) {
+        return nullptr;
+    }
+    if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsArray(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for DeleteEvents");
+        return JSI::CreateUndefined();
+    }
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    uint32_t count = JSI::GetArrayLength(args[0]);
+    callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent) * count);
+    if (!callbackData->eventarray.events) {
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    for (uint32_t arrIndex = 0; arrIndex < count; arrIndex++) {
+        JSIValue point = JSI::GetPropertyByIndex(args[0], arrIndex);
+        callbackData->eventarray.events[arrIndex].id = static_cast<int64_t>(JSI::GetNumberProperty(point, "id"));
+        JSI::ReleaseValue(point);
+    }
+    callbackData->eventarray.count = count;
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[1]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(DeleteEventsCallback, static_cast<void *>(callbackData));
+    return JSI::CreateUndefined();
+}
+
+// Update event
+void CalendarModule::UpdateEventCallback(void *data)
+{
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    error = CalendarUpdateEvent(GetCanlendarFilePath(), callbackData_->account.name, callbackData->eventarray.events);
+    JSIValue args[ARGC_ONE];
+    if (error == CALENDAR_SUCCESS) {
+        FreeEventId(callbackData->eventarray.events->id);
+        CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+        if (!event) {
+            FreeCallbackData(callbackData);
+            return;
+        }
+        if(memcpy_s(event, sizeof(CalendarEvent), callbackData->eventarray.events, sizeof(CalendarEvent)) != EOK) {
+            HILOG_ERROR(HILOG_MODULE_ACE, "memcpy_s fail");
+        }
+        SetCalendarEventWithSpecificId(callbackData->eventarray.events->id, event);
+        args[0] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+    } else {
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_ONE);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], ARGS_END);
+    }
+    if (static_cast<void*>(callbackData->eventarray.events)) {
+        free(static_cast<void*>(callbackData->eventarray.events));
+    }
+    delete callbackData;
+    callbackData = nullptr;
+}
+
+JSIValue CalendarModule::UpdateEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for updating a single event
+    if (callbackData_ == nullptr) {
+        return nullptr;
+    }
+    if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsObject(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for UpdateEvent");
+        return JSI::CreateUndefined();
+    }
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+    if (!callbackData->eventarray.events) {
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    if (strcpy_s(callbackData->eventarray.events->bundlename,
+        sizeof(callbackData->eventarray.events->bundlename),
+        GetBundleName()) != EOK) {
+        free(callbackData->eventarray.events);
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    callbackData->eventarray.events->startTime = (int64_t)JSI::GetNumberProperty(args[0], "startTime");
+    callbackData->eventarray.events->endTime = (int64_t)JSI::GetNumberProperty(args[0], "endTime");
+    callbackData->eventarray.events->type = (int)JSI::GetNumberProperty(args[0], "type");
+    callbackData->eventarray.events->id = (int)JSI::GetNumberProperty(args[0], "id");
+    char *eventContent = JSI::GetStringProperty(args[0], "eventContent");
+    if (strcpy_s(callbackData->eventarray.events->eventContent,
+        sizeof(callbackData->eventarray.events->eventContent),
+        eventContent) != EOK) {
+        free(callbackData->eventarray.events);
+        ace_free(eventContent);
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    ace_free(eventContent);
+    callbackData->eventarray.events->isAllDay = JSI::GetBooleanProperty(args[0], "isAllDay");
+    callbackData->eventarray.events->hasReminder = JSI::GetBooleanProperty(args[0], "hasReminder");
+    callbackData->eventarray.events->isRepeat = JSI::GetBooleanProperty(args[0], "isRepeat");
+    callbackData->eventarray.events->recurrenceFrequency =
+        (int64_t)JSI::GetNumberProperty(args[0], "recurrenceFrequency");
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[1]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(UpdateEventCallback, static_cast<void *>(callbackData));
+    return JSI::CreateUndefined();
+}
+
+// Batch update events
+void CalendarModule::UpdateEventsCallback(void *data)
+{
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    error = CalendarUpdateEvents(GetCanlendarFilePath(), callbackData_->account.name, &callbackData->eventarray);
+    if (error == CALENDAR_SUCCESS) {
+        for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+            CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+            if (!event) {
+                FreeCallbackData(callbackData);
+                return;
+            }
+            memcpy_s(
+                event, sizeof(CalendarEvent), callbackData->eventarray.events + evnetArrayCnt, sizeof(CalendarEvent));
+            FreeEventId(callbackData->eventarray.events[evnetArrayCnt].id);
+            SetCalendarEventWithSpecificId(callbackData->eventarray.events[evnetArrayCnt].id, event);
+        }
+    }
+    JSIValue args[ARGC_TWO];
+    JSIValue result[callbackData->eventarray.count];
+    if (error == CALENDAR_SUCCESS) {
+        JSIValue evnetArray = JSI::CreateArray(callbackData->eventarray.count);
+        for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+            result[evnetArrayCnt] = JSI::CreateNumber(callbackData->eventarray.events[evnetArrayCnt].id);
+            JSI::SetPropertyByIndex(evnetArray, evnetArrayCnt, result[evnetArrayCnt]);
+        }
+        args[1] = evnetArray;
+        args[0] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        for (uint32_t evnetArrayCnt = 0; evnetArrayCnt < callbackData->eventarray.count; evnetArrayCnt++) {
+            JSI::ReleaseValue(result[evnetArrayCnt]);
+        }
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    } else {
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        args[1] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    }
+    if (callbackData->eventarray.events) {
+        free(static_cast<void*>(callbackData->eventarray.events));
+    }
+    delete callbackData;
+    callbackData = nullptr;
+}
+
+JSIValue CalendarModule::UpdateEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for batch updating events
+    if (callbackData_ == nullptr) {
+        return nullptr;
+    }
+    if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsArray(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for UpdateEvents");
+        return JSI::CreateUndefined();
+    }
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    uint32_t count = JSI::GetArrayLength(args[0]);
+    callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent) * count);
+    if (!callbackData->eventarray.events) {
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    for (uint32_t arrIndex = 0; arrIndex < count; arrIndex++) {
+        JSIValue point = JSI::GetPropertyByIndex(args[0], arrIndex);
+        if (strcpy_s(callbackData->eventarray.events[arrIndex].bundlename,
+            sizeof(callbackData->eventarray.events[arrIndex].bundlename),
+            GetBundleName()) != EOK) {
+            free(callbackData->eventarray.events);
+            delete callbackData;
+            return JSI::CreateUndefined();
+        }
+        callbackData->eventarray.events[arrIndex].startTime = (int64_t)JSI::GetNumberProperty(point, "startTime");
+        callbackData->eventarray.events[arrIndex].endTime = (int64_t)JSI::GetNumberProperty(point, "endTime");
+        callbackData->eventarray.events[arrIndex].type = (int)JSI::GetNumberProperty(point, "type");
+        callbackData->eventarray.events[arrIndex].id = (int64_t)JSI::GetNumberProperty(point, "id");
+        char *eventContent = JSI::GetStringProperty(point, "eventContent");
+        if (strcpy_s(callbackData->eventarray.events[arrIndex].eventContent,
+            sizeof(callbackData->eventarray.events[arrIndex].eventContent),
+            eventContent) != EOK) {
+            ace_free(eventContent);
+            free(callbackData->eventarray.events);
+            delete callbackData;
+            return JSI::CreateUndefined();
+        }
+        ace_free(eventContent);
+        callbackData->eventarray.events[arrIndex].isAllDay = JSI::GetBooleanProperty(point, "isAllDay");
+        callbackData->eventarray.events[arrIndex].hasReminder = JSI::GetBooleanProperty(point, "hasReminder");
+        callbackData->eventarray.events[arrIndex].isRepeat = JSI::GetBooleanProperty(point, "isRepeat");
+        callbackData->eventarray.events[arrIndex].recurrenceFrequency =
+            (int64_t)JSI::GetNumberProperty(point, "recurrenceFrequency");
+        JSI::ReleaseValue(point);
+    }
+    callbackData->eventarray.count = count;
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[1]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(UpdateEventsCallback, static_cast<void *>(callbackData));
+    return JSI::CreateUndefined();
+}
+
+// Get event
+void CalendarModule::GetEventCallback(void *data)
+{
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    CalendarEvent *event = CalendarGetEvent(GetCanlendarFilePath(),
+        callbackData_->account.name, callbackData->eventarray.events->id, &error);
+    JSIValue args[ARGC_TWO];
+    if (error == CALENDAR_SUCCESS && event != nullptr) {
+        args[1] = JSI::CreateObject();
+        JSI::SetNumberProperty(args[1], "startTime", event->startTime);
+        JSI::SetNumberProperty(args[1], "endTime", event->endTime);
+        JSI::SetNumberProperty(args[1], "type", event->type);
+        JSI::SetNumberProperty(args[1], "id", event->id);
+        JSI::SetStringProperty(args[1], "bundlename", event->bundlename);
+        JSI::SetBooleanProperty(args[1], "isAllDay", event->isAllDay);
+        JSI::SetBooleanProperty(args[1], "hasReminder", event->hasReminder);
+        JSI::SetBooleanProperty(args[1], "isRepeat", event->isRepeat);
+        JSI::SetNumberProperty(args[1], "recurrenceFrequency", event->recurrenceFrequency);
+        JSI::SetStringProperty(args[1], "eventContent", event->eventContent);
+        args[0] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    } else {
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        args[1] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    }
+    if (event) {
+        free(event);
+    }
+    free(callbackData->eventarray.events);
+    delete callbackData;
+    callbackData = nullptr;
+}
+
+JSIValue CalendarModule::GetEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for getting a single event
+    if (callbackData_ == nullptr) {
+        return nullptr;
+    }
+    if (argsNum < 1 || !JSI::ValueIsFunction(args[1]) || !JSI::ValueIsNumber(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for GetEvent");
+        return JSI::CreateUndefined();
+    }
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    callbackData->eventarray.events = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+    if (!callbackData->eventarray.events) {
+        delete callbackData;
+        return JSI::CreateUndefined();
+    }
+    callbackData->eventarray.events->id = static_cast<int64_t>(JSI::ValueToNumber(args[0]));
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[1]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(GetEventCallback, static_cast<void *>(callbackData));
+    return JSI::CreateUndefined();
+}
+
+// Get all events
+void CalendarModule::GetEventsCallback(void *data)
+{
+    CalendarCallback *callbackData = static_cast<CalendarCallback *>(data);
+    if (!callbackData || !JSI::ValueIsFunction(callbackData->callback)) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid callback data");
+        FreeCallbackData(callbackData);
+        return;
+    }
+    CalendarError error = CALENDAR_INVALID_PARAMETER;
+    CalendarEventArray *eventarray = CalendarGetEvents(GetCanlendarFilePath(), callbackData_->account.name, &error);
+    JSIValue args[ARGC_TWO];
+    if (error == CALENDAR_SUCCESS && eventarray != nullptr) {
+        args[1] = JSI::CreateArray(eventarray->count);
+        for (uint32_t arrIndex = 0; arrIndex < eventarray->count; arrIndex++) {
+            JSIValue point = JSI::CreateObject();
+            JSI::SetNumberProperty(point, "startTime", eventarray->events[arrIndex].startTime);
+            JSI::SetNumberProperty(point, "endTime", eventarray->events[arrIndex].endTime);
+            JSI::SetNumberProperty(point, "type", eventarray->events[arrIndex].type);
+            JSI::SetNumberProperty(point, "id", eventarray->events[arrIndex].id);
+            JSI::SetStringProperty(point, "bundlename", eventarray->events[arrIndex].bundlename);
+            JSI::SetBooleanProperty(point, "isAllDay", eventarray->events[arrIndex].isAllDay);
+            JSI::SetBooleanProperty(point, "hasReminder", eventarray->events[arrIndex].hasReminder);
+            JSI::SetBooleanProperty(point, "isRepeat", eventarray->events[arrIndex].isRepeat);
+            JSI::SetNumberProperty(point, "recurrenceFrequency", eventarray->events[arrIndex].recurrenceFrequency);
+            JSI::SetStringProperty(point, "eventContent", eventarray->events[arrIndex].eventContent);
+            JSI::SetPropertyByIndex(args[1], arrIndex, point);
+            JSI::ReleaseValue(point);
+        }
+        args[0] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    } else {
+        args[0] = JSI::CreateString(GetCalendarErrorString(error));
+        args[1] = JSI::CreateNull();
+        JSI::CallFunction(callbackData->callback, callbackData->jsCtx, args, ARGC_TWO);
+        JSI::ReleaseValueList(callbackData->callback, callbackData->jsCtx, args[0], args[1], ARGS_END);
+    }
+    if (eventarray) {
+        if (eventarray->events) {
+            free(eventarray->events);
+        }
+        free(eventarray);
+    }
+
+    delete callbackData;
+    callbackData = nullptr;
+}
+
+JSIValue CalendarModule::GetEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for getting all events
+    if (callbackData_ == nullptr) {
+        return nullptr;
+    }
+    if (argsNum < 1 || !JSI::ValueIsFunction(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for GetEvents");
+        return JSI::CreateUndefined();
+    }
+    CalendarCallback *callbackData = new CalendarCallback();
+    if (!callbackData) {
+        return JSI::CreateUndefined();
+    }
+    // Save callback function and context
+    callbackData->callback = JSI::AcquireValue(args[0]);
+    callbackData->jsCtx = JSI::AcquireValue(thisVal);
+
+    OHOS::ACELite::JsAsyncWork::DispatchAsyncWork(GetEventsCallback, static_cast<void *>(callbackData));
+    return JSI::CreateUndefined();
+}
+
+// Get account information
+JSIValue CalendarModule::GetAccount(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for getting account information
+    if (argsNum != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for GetAccount");
+        return JSI::CreateUndefined();
+    }
+    if (callbackData_) {
+        JSIValue point = JSI::CreateObject();
+        JSI::SetStringProperty(point, "name", callbackData_->account.name);
+        JSI::SetStringProperty(point, "displayName", callbackData_->account.displayName);
+        JSI::SetStringProperty(point, "type", callbackData_->account.type);
+        return point;
+    } else {
+        return JSI::CreateUndefined();
+    }
+}
+
+// Set Config information
+JSIValue CalendarModule::SetConfig(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for getting account information
+    if (argsNum < 1 || !JSI::ValueIsObject(args[0])) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for SetConfig");
+        return JSI::CreateBoolean(false);
+    }
+    if (callbackData_) {
+        callbackData_->enableReminder = JSI::GetBooleanProperty(args[0], "enableReminder");
+        callbackData_->color = JSI::GetNumberProperty(args[0], "color");
+        return JSI::CreateBoolean(true);
+    } else {
+        return JSI::CreateBoolean(false);
+    }
+}
+
+// Get Config information
+JSIValue CalendarModule::GetConfig(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    // Implement logic for getting account information
+    if (argsNum != 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid arguments for GetConfig");
+        return JSI::CreateUndefined();
+    }
+    if (callbackData_) {
+        JSIValue point = JSI::CreateObject();
+        JSI::SetBooleanProperty(point, "enableReminder", callbackData_->enableReminder);
+        JSI::SetNumberProperty(point, "color", callbackData_->color);
+        return point;
+    } else {
+        return JSI::CreateUndefined();
+    }
+}
+
+// Asynchronous callback for event operations
+void CalendarModule::EventOperationCallback(void *data)
+{
+    // Implement callback handling for event operations
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void SetCanlendarFilePath(char *canlendarFilePath)
+{
+    g_canlendarFilePath = canlendarFilePath;
+}
+
+const char *GetCanlendarFilePath(void)
+{
+    return g_canlendarFilePath.c_str();
+}
+#ifdef __cplusplus
+};
+#endif
+
+}  // namespace ACELite
+}  // namespace OHOS
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_module.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_module.h
new file mode 100644 (file)
index 0000000..7c31598
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef OHOS_ACELITE_CALENDAR_MODULE_H
+#define OHOS_ACELITE_CALENDAR_MODULE_H
+
+#include <string>
+#include "acelite_config.h"
+#include "jsi.h"
+#include "js_async_work.h"
+#include "non_copyable.h"
+#include "calendar_manager.h"
+#include "calendar_timer.h"
+
+namespace OHOS {
+namespace ACELite {
+
+// Calendar module callback structure
+struct CalendarCallback {
+    JSIValue callback;        // Asynchronous callback function
+    JSIValue jsCtx;           // JS context
+    CalendarAccount account;  // Calendar account
+    CalendarEventArray eventarray;
+    bool enableReminder;
+    uint64_t color;
+};
+
+class CalendarModule final : public MemoryHeap {
+public:
+    ACE_DISALLOW_COPY_AND_MOVE(CalendarModule);
+    CalendarModule() = default;
+    ~CalendarModule() = default;
+
+    // Module initialization
+    static void Init(JSIValue exports);
+
+    // Calendar management APIs
+    static JSIValue CreateCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue DeleteCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue GetCalendar(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+
+    // Calendar event operation APIs
+    static JSIValue AddEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue AddEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue DeleteEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue DeleteEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue UpdateEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue UpdateEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue GetEvent(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue GetEvents(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue GetAccount(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue SetConfig(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+    static JSIValue GetConfig(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
+
+    // Asynchronous operation callback functions
+    static void CreateCalendarCallback(void *data);
+    static void DeleteCalendarCallback(void *data);
+    static void GetCalendarCallback(void *data);
+    static void EventOperationCallback(void *data);
+    static void AddEventCallback(void *data);
+    static void AddEventsCallback(void *data);
+    static void DeleteEventCallback(void *data);
+    static void GetEventsCallback(void *data);
+    static void DeleteEventsCallback(void *data);
+    static void GetEventCallback(void *data);
+    static void UpdateEventCallback(void *data);
+    static void UpdateEventsCallback(void *data);
+
+    static const char *const MODULE_NAME;
+    static const char *const CREATE_CALENDAR;
+    static const char *const DELETE_CALENDAR;
+    static const char *const GET_CALENDAR;
+    static const char *const ADD_EVENT;
+    static const char *const ADD_EVENTS;
+    static const char *const DELETE_EVENT;
+    static const char *const DELETE_EVENTS;
+    static const char *const UPDATE_EVENT;
+    static const char *const UPDATE_EVENTS;
+    static const char *const GET_EVENT;
+    static const char *const GET_EVENTS;
+    static const char *const GET_ACCOUNT;
+    static const char *const GET_CONFIG;
+    static const char *const SET_CONFIG;
+
+private:
+    // Helper function: Convert JS object to CalendarAccount
+    static bool ConvertToCalendarAccount(const JSIValue jsAccount, CalendarAccount &account);
+    // Helper function: Convert CalendarEvent to JS object
+    static JSIValue ConvertToJSEvent(const CalendarEvent &event);
+    // Helper function: Convert CalendarAccount to JS object
+    static JSIValue ConvertToJSAccount(const CalendarAccount &account);
+    // Release callback data
+    static void FreeCallbackData(CalendarCallback *callbackData);
+
+    static CalendarCallback *callbackData_;
+};
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif  // OHOS_ACELITE_CALENDAR_MODULE_H
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_timer.cpp b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_timer.cpp
new file mode 100644 (file)
index 0000000..56293fb
--- /dev/null
@@ -0,0 +1,168 @@
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#include <securec.h>
+#include <cstdlib>
+#include <cstdlib>
+#include <cstring>
+#include <csignal>
+#include <cerrno>
+#include <cstdio>
+#include "ace_mem_base.h"
+#include "memory_heap.h"
+#include "ace_log.h"
+#include "calendar_timer.h"
+
+namespace OHOS {
+namespace ACELite {
+
+// Timer callback function
+static void TimerCallback(union sigval v)
+{
+    struct CalendarTimer *timer = (struct CalendarTimer *)v.sival_ptr;
+    if (timer != nullptr && timer->cb != nullptr) {
+        timer->cb(timer->arg);
+    }
+}
+
+CalendarTimer *CalendarTimerInit(int32_t periodMs, CalendarTimerCb cb, void *arg, bool isPeriodic)
+{
+    CalendarTimer *timer = CalendarTimerCreate(periodMs, cb, arg, isPeriodic);
+    if (timer) {
+        int ret = CalendarTimerSetTime(timer, periodMs, true);
+        if (ret != 0) {
+            CalendarTimerDelete(timer);
+            return nullptr;
+        }
+    } else {
+        return nullptr;
+    }
+    int ret = CalendarTimerStart(timer);
+    if (ret != 0) {
+        CalendarTimerDelete(timer);
+        return nullptr;
+    }
+    return timer;
+}
+
+CalendarTimer *CalendarTimerCreate(int32_t periodMs, CalendarTimerCb cb, void *arg, bool isPeriodic)
+{
+    // Parameter validation
+    if (periodMs <= 0 || periodMs > MAX_PERIOD_MS || cb == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer create failed, invalid parameters. period=%d", periodMs);
+        return nullptr;
+    }
+
+    // Allocate timer structure
+    struct CalendarTimer *timer = (struct CalendarTimer *)malloc(sizeof(struct CalendarTimer));
+    if (timer == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer create failed, out of memory.");
+        return nullptr;
+    }
+
+    // Initialize timer structure
+    memset_s(timer, sizeof(struct CalendarTimer), 0, sizeof(struct CalendarTimer));
+    timer->cb = cb;
+    timer->arg = arg;
+    timer->periodMs = periodMs;
+    timer->isPeriodic = isPeriodic;
+
+    // Create system timer
+    struct sigevent sev;
+    memset_s(&sev, sizeof(sev), 0, sizeof(sev));
+    sev.sigev_notify = SIGEV_THREAD;
+    sev.sigev_notify_function = TimerCallback;
+    sev.sigev_value.sival_ptr = timer;
+
+    if (timer_create(CLOCK_REALTIME, &sev, &timer->timerId) == -1) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer create failed. err=%s", strerror(errno));
+        free(timer);
+        return nullptr;
+    }
+
+    return timer;
+}
+
+int CalendarTimerSetTime(CalendarTimer *timer, int32_t periodMs, bool isPeriodic)
+{
+    if (timer == nullptr || periodMs <= 0 || periodMs > MAX_PERIOD_MS) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer set time failed, invalid parameters.");
+        return -1;
+    }
+
+    timer->periodMs = periodMs;
+    timer->isPeriodic = isPeriodic;
+    return 0;
+}
+
+int CalendarTimerStart(CalendarTimer *timer)
+{
+    if (timer == nullptr || timer->periodMs <= 0) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer start failed, invalid timer.\n");
+        return -1;
+    }
+
+    struct itimerspec its;
+    its.it_value.tv_sec = timer->periodMs / MS_PER_SECOND;
+    its.it_value.tv_nsec = (timer->periodMs % MS_PER_SECOND) * NS_PER_MS;
+
+    if (timer->isPeriodic) {
+        its.it_interval.tv_sec = its.it_value.tv_sec;
+        its.it_interval.tv_nsec = its.it_value.tv_nsec;
+    } else {
+        its.it_interval.tv_sec = 0;
+        its.it_interval.tv_nsec = 0;
+    }
+
+    if (timer_settime(timer->timerId, 0, &its, nullptr) == -1) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer start failed. err=%s\n", strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
+
+int CalendarTimerStop(CalendarTimer *timer)
+{
+    if (timer == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer stop failed, invalid timer.\n");
+        return -1;
+    }
+
+    struct itimerspec its;
+    memset_s(&its, sizeof(its), 0, sizeof(its));
+
+    if (timer_settime(timer->timerId, 0, &its, nullptr) == -1) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer stop failed. err=%s\n", strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
+
+int CalendarTimerDelete(CalendarTimer *timer)
+{
+    if (timer == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer delete failed, invalid timer.\n");
+        return -1;
+    }
+
+    // Stop the timer first
+    CalendarTimerStop(timer);
+
+    // Delete system timer
+    if (timer_delete(timer->timerId) == -1) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Timer delete failed. err=%s\n", strerror(errno));
+        free(timer);
+        return -1;
+    }
+
+    // Free timer structure
+    free(timer);
+    return 0;
+}
+}  // namespace ACELite
+}  // namespace OHOS
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_timer.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_timer.h
new file mode 100644 (file)
index 0000000..71d6173
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef CALENDAR_TIMER_H
+#define CALENDAR_TIMER_H
+
+#include <stdint.h>
+#include <ctime>
+#include <stdbool.h>
+#include "sys/time.h"
+
+#define MAX_PERIOD_MS 86400000  // Maximum period is 24 hours
+#define MS_PER_SECOND 1000
+#define NS_PER_MS 1000000
+
+static constexpr int16_t SEC_TO_MILLI = 1000;
+static constexpr int16_t USEC_TO_MILLI = 1000;
+static constexpr int16_t MIN_TO_HOUR = 60;
+static constexpr int16_t HOURLY_SYSTEM = 24;
+
+namespace OHOS {
+namespace ACELite {
+
+// Timer callback function type
+typedef void (*CalendarTimerCb)(void *arg);
+
+// Timer structure definition
+struct CalendarTimer {
+    timer_t timerId;     // System timer ID
+    CalendarTimerCb cb;  // Callback function
+    void *arg;           // Argument for callback function
+    int32_t periodMs;    // Period time (in milliseconds)
+    bool isPeriodic;     // Whether it's a periodic timer
+};
+
+// Timer handle structure (opaque type, users don't need to know the internal implementation)
+typedef struct CalendarTimer CalendarTimer;
+
+CalendarTimer *CalendarTimerInit(int32_t periodMs, CalendarTimerCb cb, void *arg, bool isPeriodic);
+
+/**
+ * Create a timer
+ * @param periodMs Period time in milliseconds. For one-shot timers, this is the first trigger time
+ * @param cb Timer callback function
+ * @param arg Argument passed to the callback function
+ * @param isPeriodic Whether it's a periodic timer
+ * @return Returns timer handle on success, nullptr on failure
+ */
+CalendarTimer *CalendarTimerCreate(int32_t periodMs, CalendarTimerCb cb, void *arg, bool isPeriodic);
+
+/**
+ * Set the timer's time
+ * @param timer Timer handle
+ * @param periodMs Period time in milliseconds
+ * @param isPeriodic Whether it's a periodic timer
+ * @return Returns 0 on success, -1 on failure
+ */
+int CalendarTimerSetTime(CalendarTimer *timer, int32_t periodMs, bool isPeriodic);
+
+/**
+ * Start the timer
+ * @param timer Timer handle
+ * @return Returns 0 on success, -1 on failure
+ */
+int CalendarTimerStart(CalendarTimer *timer);
+
+/**
+ * Stop the timer
+ * @param timer Timer handle
+ * @return Returns 0 on success, -1 on failure
+ */
+int CalendarTimerStop(CalendarTimer *timer);
+
+/**
+ * Delete the timer
+ * @param timer Timer handle
+ * @return Returns 0 on success, -1 on failure
+ */
+int CalendarTimerDelete(CalendarTimer *timer);
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif  // CALENDAR_TIMER_H
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_utils.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/calendar_utils.h
new file mode 100644 (file)
index 0000000..34967c1
--- /dev/null
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef OHOS_ACELITE_CALENDAR_UTILS_H
+#define OHOS_ACELITE_CALENDAR_UTILS_H
+
+#include <string>
+namespace OHOS {
+namespace ACELite {
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void SetCanlendarFilePath(char *hapPath);
+const char *GetCanlendarFilePath(void);
+#ifdef __cplusplus
+};
+#endif
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif  // OHOS_ACELITE_CALENDAR_MODULE_H
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/event_id_manager.cpp b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/event_id_manager.cpp
new file mode 100644 (file)
index 0000000..c960af1
--- /dev/null
@@ -0,0 +1,475 @@
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <sys/time.h>
+#include <cerrno>
+#include <iostream>
+#include "cJSON.h"
+#include "calendar_utils.h"
+#include "msg_center_msg.h"
+#include "msg_center_client.h"
+#include "event_id_manager.h"
+
+namespace OHOS {
+namespace ACELite {
+#define ALLOC_CALENDAR_EVENTID_FAILD -1
+#define MINUTE_IN_MILLISECONDS 60000
+// Global containers (after splitting)
+std::map<int64_t, CalendarEvent *> reminderEventMap;  // Reminder event container
+std::map<int64_t, CalendarEvent *> normalEventMap;    // Non-reminder event container
+std::unordered_set<int64_t> usedEventIds;             // Used ID set
+int64_t g_reminderEventCount = 0;                       // Reminder event count
+
+/**
+ * @brief Read file content into a string
+ */
+static char *ReadFileToString(const char *filePath)
+{
+    if (!filePath) {
+        printf("[ERROR] File path is nullptr\n");
+        return nullptr;
+    }
+
+    FILE *file = fopen(filePath, "r");
+    if (!file) {
+        printf("[ERROR] Failed to open file %s (errno: %d)\n", filePath, errno);
+        return nullptr;
+    }
+
+    fseek(file, 0, SEEK_END);
+    long fileSize = ftell(file);
+    fseek(file, 0, SEEK_SET);
+
+    if (fileSize < 0) {
+        printf("[ERROR] Failed to get file size (errno: %d)\n", errno);
+        fclose(file);
+        return nullptr;
+    }
+
+    char *buffer = (char *)malloc(fileSize + 1);
+    if (!buffer) {
+        printf("[ERROR] Malloc buffer failed\n");
+        fclose(file);
+        return nullptr;
+    }
+
+    size_t readSize = fread(buffer, 1, fileSize, file);
+    if (readSize != static_cast<size_t>(fileSize)) {
+        printf("[ERROR] Failed to read file content\n");
+        free(buffer);
+        fclose(file);
+        return nullptr;
+    }
+    buffer[readSize] = '\0';
+
+    fclose(file);
+    return buffer;
+}
+
+/**
+ * @brief Parse calendar event from JSON object
+ */
+static CalendarEvent *parseCalendarEvent(cJSON *eventJson)
+{
+    if (!eventJson) {
+        return nullptr;
+    }
+
+    CalendarEvent *event = (CalendarEvent *)malloc(sizeof(CalendarEvent));
+    if (!event) {
+        return nullptr;
+    }
+    memset_s(event, sizeof(CalendarEvent), 0, sizeof(CalendarEvent));
+
+    cJSON *idJson = cJSON_GetObjectItem(eventJson, "id");
+    cJSON *typeJson = cJSON_GetObjectItem(eventJson, "type");
+    cJSON *startTimeJson = cJSON_GetObjectItem(eventJson, "startTime");
+    cJSON *endTimeJson = cJSON_GetObjectItem(eventJson, "endTime");
+    cJSON *bundlenameJson = cJSON_GetObjectItem(eventJson, "bundlename");
+    cJSON *isAllDayJson = cJSON_GetObjectItem(eventJson, "isAllDay");
+    cJSON *hasReminderJson = cJSON_GetObjectItem(eventJson, "hasReminder");
+    cJSON *isRepeatJson = cJSON_GetObjectItem(eventJson, "isRepeat");
+    cJSON *recurrenceFrequencyJson = cJSON_GetObjectItem(eventJson, "recurrenceFrequency");
+    cJSON *eventContentJson = cJSON_GetObjectItem(eventJson, "eventContent");
+
+    event->id = idJson ? idJson->valueint : 0;
+    event->type = typeJson ? typeJson->valueint : 0;
+    event->startTime = startTimeJson ? (int64_t)startTimeJson->valuedouble : 0;
+    event->endTime = endTimeJson ? (int64_t)endTimeJson->valuedouble : 0;
+
+    if (bundlenameJson && bundlenameJson->valuestring) {
+        strncpy_s(event->bundlename, sizeof(event->bundlename) - 1,
+            bundlenameJson->valuestring, sizeof(event->bundlename) - 1);
+    }
+
+    event->isAllDay = isAllDayJson ? (isAllDayJson->type == cJSON_True) : false;
+    event->hasReminder = hasReminderJson ? (hasReminderJson->type == cJSON_True) : false;
+    event->isRepeat = isRepeatJson ? (isRepeatJson->type == cJSON_True) : false;
+    event->recurrenceFrequency = recurrenceFrequencyJson ? recurrenceFrequencyJson->valuedouble : 0;
+
+    if (eventContentJson && eventContentJson->valuestring) {
+        strncpy_s(event->eventContent, sizeof(event->eventContent) - 1,
+            eventContentJson->valuestring, sizeof(event->eventContent) - 1);
+    }
+    return event;
+}
+
+/**
+ * @brief Get current timestamp (in milliseconds)
+ */
+static int64_t GetCurrentTimestamp()
+{
+    struct timeval tv;
+    gettimeofday(&tv, nullptr);
+    return static_cast<int64_t>(
+        static_cast<uint64_t>(tv.tv_sec) * SEC_TO_MILLI +
+        static_cast<uint64_t>(tv.tv_usec) / SEC_TO_MILLI
+    );
+}
+
+/**
+ * @brief Calendar timer callback function
+ */
+static void CalendarTimerCallback(void *arg)
+{
+    struct timeval tv;
+    gettimeofday(&tv, nullptr);
+    uint64_t currentTimeMs = GetCurrentTimestamp();
+
+    // Use iterator for traversal to support safe element deletion
+    auto it = reminderEventMap.begin();
+    while (it != reminderEventMap.end()) {
+        // Remove const qualifier since we need to modify startTime and endTime
+        CalendarEvent *event = it->second;
+        if (!event) {
+            // Handle null pointer event, delete directly
+            it = reminderEventMap.erase(it);
+            g_reminderEventCount--;
+            continue;
+        }
+
+        // Logic correction: consider "triggered" when current time exceeds start time
+        bool isTriggered = (currentTimeMs > event->startTime);
+        if (isTriggered) {
+            MsgCenterSendMsg(CALENDAR_TO_MSGCENTER, 0, (void *)event, sizeof(CalendarEvent));
+            if (event->isRepeat) {
+                // Calculate next trigger time for recurring events
+                uint64_t times = (currentTimeMs - event->startTime) / event->recurrenceFrequency;
+                event->startTime += (times + 1) * event->recurrenceFrequency;
+                event->endTime += (times + 1) * event->recurrenceFrequency;
+                ++it;  // Move to next element
+            } else {
+                // Insert key-value pair (not iterator) to normalEventMap
+                normalEventMap.insert(*it);
+                // Remove from reminderEventMap and move iterator
+                it = reminderEventMap.erase(it);
+                g_reminderEventCount--;
+            }
+        } else {
+            // Untriggered events: keep in reminder list
+            ++it;  // Move to next element
+        }
+    }
+}
+
+// Check if it's a valid reminder event
+static bool CheckValidReminderEvent(int64_t currentTimeMs, CalendarEvent *event)
+{
+    bool isActiveReminder = false;
+    if (event->hasReminder) {
+        bool isExpired = (currentTimeMs > event->startTime);
+        if (!(isExpired && !event->isRepeat)) {
+            isActiveReminder = true;
+            if (isExpired && event->isRepeat) {
+                uint64_t times = (currentTimeMs - event->startTime) / event->recurrenceFrequency;
+                event->startTime += ((times + 1) * event->recurrenceFrequency);
+                event->endTime += ((times + 1) * event->recurrenceFrequency);
+            }
+        }
+    }
+    return isActiveReminder;
+}
+
+/**
+ * @brief Initialize event maps from JSON file
+ */
+bool InitEventMaps()
+{
+    ClearAllEvents();
+    char *jsonContent = ReadFileToString(GetCanlendarFilePath());
+    if (!jsonContent) {
+        return false;
+    }
+    cJSON *root = cJSON_Parse(jsonContent);
+    free(jsonContent);
+    if (!root) {
+        return false;
+    }
+    int64_t currentTimeMs = GetCurrentTimestamp();
+
+    cJSON *userNode = nullptr;
+    cJSON_ArrayForEach(userNode, root)
+    {
+        cJSON *userProp = nullptr;
+        cJSON_ArrayForEach(userProp, userNode)
+        {
+            if (strcmp(userProp->string, "events") == 0 && cJSON_IsArray(userProp)) {
+                cJSON *eventNode = nullptr;
+                cJSON_ArrayForEach(eventNode, userProp)
+                {
+                    CalendarEvent *event = parseCalendarEvent(eventNode);
+                    if (!event) {
+                        continue;
+                    }
+
+                    usedEventIds.insert(event->id);
+                    if (CheckValidReminderEvent(currentTimeMs, event)) {
+                        reminderEventMap[event->id] = event;
+                        g_reminderEventCount++;
+                    } else {
+                        normalEventMap[event->id] = event;
+                    }
+                }
+            }
+        }
+    }
+    CalendarTimerInit(MINUTE_IN_MILLISECONDS, CalendarTimerCallback, nullptr, true);
+
+    cJSON_Delete(root);
+    return true;
+}
+
+/**
+ * @brief Clear all event data
+ */
+void ClearAllEvents()
+{
+    // Free reminder event memory
+    for (auto &pair : reminderEventMap) {
+        if (pair.second)
+            free(pair.second);
+    }
+    reminderEventMap.clear();
+
+    // Free non-reminder event memory
+    for (auto &pair : normalEventMap) {
+        if (pair.second)
+            free(pair.second);
+    }
+    normalEventMap.clear();
+
+    usedEventIds.clear();
+    g_reminderEventCount = 0;
+}
+
+/**
+ * @brief Check if specified ID is already in use
+ */
+bool IsEventIdInUse(int64_t id)
+{
+    if (id < MIN_EVENT_ID || id > MAX_EVENT_ID) {
+        return false;
+    }
+    return usedEventIds.find(id) != usedEventIds.end();
+}
+
+/**
+ * @brief Automatically allocate ID and set event
+ */
+int64_t AllocateAndSetCalendarEvent(CalendarEvent *event)
+{
+    if (!event) {
+        return ALLOC_CALENDAR_EVENTID_FAILD;
+    }
+
+    // Check reminder event count
+    if (event->hasReminder && g_reminderEventCount >= MAX_REMINDER_COUNT) {
+        fprintf(stderr, "Reminder events have reached maximum limit\n");
+        return ALLOC_CALENDAR_EVENTID_FAILD;
+    }
+    int64_t currentTime = GetCurrentTimestamp();
+    // Find available ID
+    for (int64_t id = MIN_EVENT_ID; id <= MAX_EVENT_ID; ++id) {
+        if (!IsEventIdInUse(id)) {
+            event->id = id;
+            usedEventIds.insert(id);
+
+            // Add to corresponding container based on reminder property
+            if (event->hasReminder && ((event->startTime > currentTime || event->isRepeat))) {
+                reminderEventMap[id] = event;
+                g_reminderEventCount++;
+            } else {
+                normalEventMap[id] = event;
+            }
+            return id;
+        }
+    }
+    fprintf(stderr, "No available event ID\n");
+    return ALLOC_CALENDAR_EVENTID_FAILD;
+}
+
+/**
+ * @brief Set event with specified ID
+ */
+bool SetCalendarEventWithSpecificId(int64_t id, CalendarEvent *event)
+{
+    if (!event || id < MIN_EVENT_ID || id > MAX_EVENT_ID) {
+        return false;
+    }
+    if (IsEventIdInUse(id)) {
+        return false;
+    }
+
+    // Check reminder event count
+    if (event->hasReminder && g_reminderEventCount >= MAX_REMINDER_COUNT) {
+        return false;
+    }
+
+    event->id = id;
+    usedEventIds.insert(id);
+
+    // Add to corresponding container based on reminder property
+    if (event->hasReminder) {
+        reminderEventMap[id] = event;
+        g_reminderEventCount++;
+    } else {
+        normalEventMap[id] = event;
+    }
+
+    return true;
+}
+
+/**
+ * @brief Free resources for event with specified ID
+ */
+int FreeEventId(int64_t id)
+{
+    if (id < MIN_EVENT_ID || id > MAX_EVENT_ID) {
+        return 0;
+    }
+    if (!IsEventIdInUse(id)) {
+        return 0;
+    }
+
+    // Free from corresponding container
+    auto remIt = reminderEventMap.find(id);
+    if (remIt != reminderEventMap.end()) {
+        free(remIt->second);
+        reminderEventMap.erase(remIt);
+        g_reminderEventCount--;
+        usedEventIds.erase(id);
+        return 1;
+    }
+
+    auto normIt = normalEventMap.find(id);
+    if (normIt != normalEventMap.end()) {
+        free(normIt->second);
+        normalEventMap.erase(normIt);
+        usedEventIds.erase(id);
+        return 1;
+    }
+
+    return 0;
+}
+
+/**
+ * @brief Get event with specified ID
+ */
+CalendarEvent *GetCalendarEvent(int64_t id)
+{
+    if (id < MIN_EVENT_ID || id > MAX_EVENT_ID) {
+        return nullptr;
+    }
+
+    auto remIt = reminderEventMap.find(id);
+    if (remIt != reminderEventMap.end())
+        return remIt->second;
+
+    auto normIt = normalEventMap.find(id);
+    if (normIt != normalEventMap.end())
+        return normIt->second;
+
+    return nullptr;
+}
+
+/**
+ * @brief Get current count of reminder events
+ */
+int GetReminderEventCount()
+{
+    return g_reminderEventCount;
+}
+
+/**
+ * @brief Check if more reminder events can be added
+ */
+bool CanAddMoreReminders()
+{
+    return g_reminderEventCount < MAX_REMINDER_COUNT;
+}
+
+/**
+ * @brief Update non-reminder event to reminder event
+ */
+bool UpdateNonReminderToReminder(int64_t id, CalendarEvent *updatedEvent)
+{
+    if (id < MIN_EVENT_ID || id > MAX_EVENT_ID || !updatedEvent || !updatedEvent->hasReminder) {
+        return false;
+    }
+
+    // Check if original event is a non-reminder event
+    auto normIt = normalEventMap.find(id);
+    if (normIt == normalEventMap.end() || !normIt->second) {
+        return false;
+    }
+
+    // Check reminder event count
+    if (g_reminderEventCount >= MAX_REMINDER_COUNT) {
+        return false;
+    }
+
+    // Free original event, add new event to reminder container
+    free(normIt->second);
+    normalEventMap.erase(normIt);
+
+    updatedEvent->id = id;
+    reminderEventMap[id] = updatedEvent;
+    g_reminderEventCount++;
+
+    return true;
+}
+
+/**
+ * @brief Timer initialization function (external implementation)
+ */
+void CalendarTimerInit(uint32_t intervalMs, void (*callback)(void *), void *arg, bool isLoop)
+{
+    // Timer implementation provided externally
+    printf("Timer initialized, interval: %u ms\n", intervalMs);
+}
+
+/**
+ * @brief Get reminder event container
+ */
+const std::map<int64_t, CalendarEvent *> &GetReminderEventMap()
+{
+    return reminderEventMap;
+}
+
+/**
+ * @brief Get non-reminder event container
+ */
+const std::map<int64_t, CalendarEvent *> &GetNormalEventMap()
+{
+    return normalEventMap;
+}
+
+}  // namespace ACELite
+}  // namespace OHOS
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/event_id_manager.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/calendarManager/event_id_manager.h
new file mode 100644 (file)
index 0000000..892df3c
--- /dev/null
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) CompanyNameMagicTag 2025-2025. All rights reserved.
+ * Description: appmanger_module module.
+ * Author: CompanyName
+ * Create: 2025-09-04
+ */
+#ifndef EVENT_ID_MANAGER_H
+#define EVENT_ID_MANAGER_H
+
+#include <cstdint>
+#include <map>
+#include <unordered_set>
+#include "calendar_timer.h"
+#include "calendar_manager.h"
+
+namespace OHOS {
+namespace ACELite {
+
+// Event ID range constants
+const int64_t MIN_EVENT_ID = 1;         // Minimum event ID
+const int64_t MAX_EVENT_ID = 64;        // Maximum event ID
+const int64_t MAX_REMINDER_COUNT = 32;  // Maximum number of reminder events
+
+// Global container declarations
+extern std::map<int64_t, CalendarEvent *> reminderEventMap;  // Reminder event container
+extern std::map<int64_t, CalendarEvent *> normalEventMap;    // Non-reminder event container
+extern std::unordered_set<int64_t> usedEventIds;             // Set of used IDs
+extern int64_t g_reminderEventCount;
+
+// Function declarations
+/**
+ * @brief Initialize event containers from JSON file (automatically split into reminder and non-reminder containers)
+ * @param jsonFilePath Path to the JSON file
+ * @return Returns true if initialization is successful, false otherwise
+ */
+bool InitEventMaps();
+
+/**
+ * @brief Clear all event containers and free memory
+ */
+void ClearAllEvents();
+
+/**
+ * @brief Check if the specified ID is already in use
+ * @param id Event ID
+ * @return Returns true if the ID is in use, false otherwise
+ */
+bool IsEventIdInUse(int64_t id);
+
+/**
+ * @brief Automatically allocate ID and add event (classified into corresponding container based on hasReminder
+ * property)
+ * @param event Pointer to the event
+ * @return Returns the allocated ID on success, 0 on failure
+ */
+int64_t AllocateAndSetCalendarEvent(CalendarEvent *event);
+
+/**
+ * @brief Add event with specified ID (classified into corresponding container based on hasReminder property)
+ * @param id Event ID
+ * @param event Pointer to the event
+ * @return Returns true on success, false on failure
+ */
+bool SetCalendarEventWithSpecificId(int64_t id, CalendarEvent *event);
+
+/**
+ * @brief Free the event with the specified ID
+ * @param id Event ID
+ * @return Returns 1 on success, 0 on failure
+ */
+int FreeEventId(int64_t id);
+
+/**
+ * @brief Get the event with the specified ID
+ * @param id Event ID
+ * @return Returns pointer to the event on success, nullptr on failure
+ */
+CalendarEvent *GetCalendarEvent(int64_t id);
+
+/**
+ * @brief Get the count of reminder events
+ * @return Number of reminder events
+ */
+int GetReminderEventCount();
+
+/**
+ * @brief Check if more reminder events can be added
+ * @return Returns true if more reminders can be added, false otherwise
+ */
+bool CanAddMoreReminders();
+
+/**
+ * @brief Update a non-reminder event to a reminder event
+ * @param id Event ID
+ * @param updatedEvent Updated event
+ * @return Returns true on success, false on failure
+ */
+bool UpdateNonReminderToReminder(int64_t id, CalendarEvent *updatedEvent);
+
+/**
+ * @brief Timer initialization function
+ * @param intervalMs Timer interval in milliseconds
+ * @param callback Callback function
+ * @param arg Callback argument
+ * @param isLoop Whether to loop periodically
+ */
+void CalendarTimerInit(uint32_t intervalMs, void (*callback)(void *), void *arg, bool isLoop);
+
+/**
+ * @brief Get the reminder event container (for external traversal)
+ * @return Constant reference to the reminder event container
+ */
+const std::map<int64_t, CalendarEvent *> &GetReminderEventMap();
+
+/**
+ * @brief Get the non-reminder event container (for external traversal)
+ * @return Constant reference to the non-reminder event container
+ */
+const std::map<int64_t, CalendarEvent *> &GetNormalEventMap();
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif  // EVENT_ID_MANAGER_H
index 3fc7f1d..99f6009 100644 (file)
@@ -89,8 +89,10 @@ JSIValue DisplayModule::SetKeepScreenOn(const JSIValue thisVal, const JSIValue *
         if (display_api->get_screen_state() != SCREEN_ON) {\r
             display_api->turn_on_screen();\r
         }\r
+        result = display_api->set_screen_set_keepon_timeout(0);\r
         result = display_api->set_screen_set_keepon_timeout(3600000); // 3600000ms\r
     }  else {\r
+        result = display_api->set_screen_set_keepon_timeout(0);\r
         result = display_api->set_screen_set_keepon_timeout(g_keepOnTimeout);\r
     }\r
     if (result == ERRCODE_SUCC) {\r
index ae517f8..a659472 100644 (file)
@@ -27,15 +27,31 @@ namespace ACELite {
 \r
 using namespace OHOS::Location;\r
 \r
-const double LocationModule::LONGITUDE = 123.456789;\r
-const double LocationModule::LATITUDE = 45.678901;\r
-const double LocationModule::ALTITUDE = 100.0;\r
-const double LocationModule::ACCURACY = 10.0;\r
-const uint32_t LocationModule::TIME = 163456789;\r
+double LocationModule::LONGITUDE = 123.456789;\r
+double LocationModule::LATITUDE = 45.678901;\r
+double LocationModule::ALTITUDE = 100.0;\r
+double LocationModule::ACCURACY = 10.0;\r
+uint32_t LocationModule::TIME = 163456789;\r
+double LocationModule::SPEED_ACCURACY = 14.72;\r
+double LocationModule::ALTITUDE_ACCURACY = 8.4;\r
+double LocationModule::DIRECTION_ACCURACY = 0;\r
+double LocationModule::VELOCITY_NORTH = -43.311;\r
+double LocationModule::VELOCITY_EAST = 16.366;\r
+double LocationModule::VELOCITY_DESCEND = 10;\r
+int32_t LocationModule::SATELLITE_NUMBER = 49;\r
+int32_t LocationModule::STATUS_NUMBER = 1;\r
 const char *const LocationModule::LONGITUDE_NAME = "longitude";\r
 const char *const LocationModule::LATITUDE_NAME = "latitude";\r
 const char *const LocationModule::ALTITUDE_NAME = "altitude";\r
 const char *const LocationModule::ACCURACY_NAME = "accuracy";\r
+const char *const LocationModule::SPEED_ACCURACY_NAME = "speedAccuracy";\r
+const char *const LocationModule::ALTITUDE_ACCURACY_NAME = "altitudeAccuracy";\r
+const char *const LocationModule::DIRECTION_ACCURACY_NAME = "directionAccuracy";\r
+const char *const LocationModule::VELOCITY_NORTH_NAME = "velocityNorth";\r
+const char *const LocationModule::VELOCITY_EAST_NAME = "velocityEast";\r
+const char *const LocationModule::VELOCITY_DESCEND_NAME = "velocityDescend";\r
+const char *const LocationModule::STATUS_NUMBER_NAME = "statusNumber";\r
+const char *const LocationModule::SATELLITE_NUMBER_NAME = "satelliteNubmer";\r
 const char *const LocationModule::TIME_NAME = "time";\r
 const char *const LocationModule::COORD_TYPES_NAME = "coordType";\r
 const char *const LocationModule::LOCATIONTYPE_NAME = "types";\r
@@ -48,6 +64,7 @@ typedef struct {
 } CoordTypeMap;\r
 \r
 LocatorCallback *LocationModule::locatorCallback_ = nullptr;\r
+GnssStatusCallback *LocationModule::gnssStatusCallback_ = nullptr;\r
 \r
 static CoordTypeMap g_coordTypeMap[] = {\r
     {WGS84, "WGS84"},\r
@@ -86,7 +103,7 @@ JSIValue LocationModule::GetSupportCoordTypes(const JSIValue thisVal, const JSIV
 JSIValue LocationModule::Unsubscribe(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
 {\r
 #if defined(ENABLE_LOCATION)\r
-    ExecuteUnsubscribe();\r
+    JsAsyncWork::DispatchAsyncWork(ExecuteUnsubscribe, nullptr);\r
 #endif\r
     return JSI::CreateUndefined();\r
 }\r
@@ -139,14 +156,44 @@ JSIValue LocationModule::ExecuteAsyncWork(
     return undefValue;\r
 }\r
 \r
+void LocationModule::OnDestroy()\r
+{\r
+    UnsubscribeAndStopLocating();\r
+}\r
+\r
+void GnssStatusCallback::OnStatusChange(const std::shared_ptr<SatelliteStatus> &statusInfo)\r
+{\r
+    LocationModule::SATELLITE_NUMBER = statusInfo->GetSatellitesNumber();\r
+}\r
+\r
 void LocatorCallback::OnLocationReport(const std::shared_ptr<OHOS::Location::Location> &location)\r
 {\r
     JSIValue result = JSI::CreateObject();\r
+    LocationModule::LONGITUDE = location->GetLongitude();\r
+    LocationModule::LATITUDE = location->GetLatitude();\r
+    LocationModule::ALTITUDE = location->GetAltitude();\r
+    LocationModule::ACCURACY = location->GetAccuracy();\r
+    LocationModule::TIME = static_cast<double>(location->GetTimeStamp());\r
+    LocationModule::SPEED_ACCURACY = location->GetSpeedAccuracy();\r
+    LocationModule::ALTITUDE_ACCURACY = location->GetAltitudeAccuracy();\r
+    LocationModule::DIRECTION_ACCURACY = location->GetDirectionAccuracy();\r
+    LocationModule::VELOCITY_NORTH = location->GetNorthVelocity();\r
+    LocationModule::VELOCITY_EAST = location->GetEastVelocity();\r
+    LocationModule::VELOCITY_DESCEND = location->GetDescendVelocity();\r
+    LocationModule::STATUS_NUMBER = location->GetStatusNumber();\r
     JSI::SetNumberProperty(result, LocationModule::LONGITUDE_NAME, location->GetLatitude());\r
     JSI::SetNumberProperty(result, LocationModule::LATITUDE_NAME, location->GetLongitude());\r
     JSI::SetNumberProperty(result, LocationModule::ALTITUDE_NAME, location->GetAltitude());\r
     JSI::SetNumberProperty(result, LocationModule::ACCURACY_NAME, location->GetAccuracy());\r
     JSI::SetNumberProperty(result, LocationModule::TIME_NAME, static_cast<double>(location->GetTimeStamp()));\r
+    JSI::SetNumberProperty(result, LocationModule::SPEED_ACCURACY_NAME, location->GetSpeedAccuracy());\r
+    JSI::SetNumberProperty(result, LocationModule::ALTITUDE_ACCURACY_NAME, location->GetAltitudeAccuracy());\r
+    JSI::SetNumberProperty(result, LocationModule::DIRECTION_ACCURACY_NAME, location->GetDirectionAccuracy());\r
+    JSI::SetNumberProperty(result, LocationModule::VELOCITY_NORTH_NAME, location->GetNorthVelocity());\r
+    JSI::SetNumberProperty(result, LocationModule::VELOCITY_EAST_NAME, location->GetEastVelocity());\r
+    JSI::SetNumberProperty(result, LocationModule::VELOCITY_DESCEND_NAME, location->GetDescendVelocity());\r
+    JSI::SetNumberProperty(result, LocationModule::STATUS_NUMBER_NAME, location->GetStatusNumber());\r
+    JSI::SetNumberProperty(result, LocationModule::SATELLITE_NUMBER_NAME, LocationModule::SATELLITE_NUMBER);\r
     LocationModule::SuccessCallBack(thisVal_, args_, result);\r
     JSI::ReleaseValueList(result, ARGS_END);\r
 }\r
@@ -166,6 +213,18 @@ LocatorCallback::~LocatorCallback()
     JSI::ReleaseValueList(args_, thisVal_, ARGS_END);\r
 }\r
 \r
+void LocationModule::DestroyResources()\r
+{\r
+    if (locatorCallback_ != nullptr) {\r
+        delete locatorCallback_;\r
+        locatorCallback_ = nullptr;\r
+    }\r
+    if (gnssStatusCallback_ != nullptr) {\r
+        delete gnssStatusCallback_;\r
+        gnssStatusCallback_ = nullptr;\r
+    }\r
+}\r
+\r
 int32_t LocationModule::SubscribeAndStartLocating(void *data)\r
 {\r
     LocationParams *params = reinterpret_cast<LocationParams *>(data);\r
@@ -184,6 +243,16 @@ int32_t LocationModule::SubscribeAndStartLocating(void *data)
         HILOG_ERROR(HILOG_MODULE_ACE, "locator EnableAbility failed:%d", errCode);\r
         return errCode;\r
     }\r
+    gnssStatusCallback_ = new (std::nothrow) GnssStatusCallback;\r
+    if (gnssStatusCallback_ == nullptr) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "locator gnssStatusCallback_ null");\r
+        return ERRCODE_FAILURE;\r
+    }\r
+    errCode = Locator::GetInstance().RegisterGnssStatusCallback(gnssStatusCallback_);\r
+    if (errCode != ERRCODE_SUCCESS) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "locator RegisterGnssStatusCallback failed:%d\n", errCode);\r
+        return errCode;\r
+    }\r
     locatorCallback_ = new (std::nothrow) LocatorCallback(params->args, params->thisVal);\r
     if (locatorCallback_ == nullptr) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "locator locatorCallback_ null");\r
@@ -211,6 +280,10 @@ int32_t LocationModule::UnsubscribeAndStopLocating()
         HILOG_ERROR(HILOG_MODULE_ACE, "locator Is not LocationEnabled");\r
         return ERRCODE_FAILURE;\r
     }\r
+    errCode = Locator::GetInstance().UnregisterGnssStatusCallback(gnssStatusCallback_);\r
+    if (errCode != ERRCODE_SUCCESS) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "locator UnregisterGnssStatusCallback failed:%d", errCode);\r
+    }\r
     errCode = Locator::GetInstance().StopLocating(locatorCallback_);\r
     if (errCode != ERRCODE_SUCCESS) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "locator StopLocating failed:%d", errCode);\r
@@ -219,10 +292,7 @@ int32_t LocationModule::UnsubscribeAndStopLocating()
     if (errCode != ERRCODE_SUCCESS) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "locator EnableAbility failed:%d", errCode);\r
     }\r
-    if (locatorCallback_ != nullptr) {\r
-        delete locatorCallback_;\r
-        locatorCallback_ = nullptr;\r
-    }\r
+    DestroyResources();\r
     return ERRCODE_SUCCESS;\r
 }\r
 \r
@@ -242,7 +312,7 @@ void LocationModule::ExecuteSubscribe(void *data)
     delete params;\r
 }\r
 \r
-void LocationModule::ExecuteUnsubscribe()\r
+void LocationModule::ExecuteUnsubscribe(void *data)\r
 {\r
     int32_t ret = UnsubscribeAndStopLocating();\r
     if (ret != ERRCODE_SUCCESS) {\r
@@ -286,30 +356,54 @@ void LocationModule::ExecuteGetLocation(void *data)
     JSI::SetNumberProperty(result, ALTITUDE_NAME, ALTITUDE);\r
     JSI::SetNumberProperty(result, ACCURACY_NAME, ACCURACY);\r
     JSI::SetNumberProperty(result, TIME_NAME, static_cast<double>(TIME));\r
+    JSI::SetNumberProperty(result, SPEED_ACCURACY_NAME, SPEED_ACCURACY);\r
+    JSI::SetNumberProperty(result, ALTITUDE_ACCURACY_NAME, ALTITUDE_ACCURACY);\r
+    JSI::SetNumberProperty(result, DIRECTION_ACCURACY_NAME, DIRECTION_ACCURACY);\r
+    JSI::SetNumberProperty(result, VELOCITY_NORTH_NAME, VELOCITY_NORTH);\r
+    JSI::SetNumberProperty(result, VELOCITY_EAST_NAME, VELOCITY_EAST);\r
+    JSI::SetNumberProperty(result, VELOCITY_DESCEND_NAME, VELOCITY_DESCEND);\r
+    JSI::SetNumberProperty(result, STATUS_NUMBER_NAME, STATUS_NUMBER);\r
+    JSI::SetNumberProperty(result, SATELLITE_NUMBER_NAME, SATELLITE_NUMBER);\r
     SuccessCallBack(thisVal, args, result);\r
     JSI::ReleaseString(coordType);\r
     JSI::ReleaseValueList(args, thisVal, result, ARGS_END);\r
     delete params;\r
 }\r
 \r
-void LocationModule::SuccessCallBack(const JSIValue thisVal, const JSIValue args, JSIValue jsiValue)\r
+void LocationModule::SuccessCallBackDispatch(void *data)\r
 {\r
-    if (JSI::ValueIsUndefined(args)) {\r
+    LocationParams *param = (LocationParams *)data;\r
+    if (JSI::ValueIsUndefined(param->args) || JSI::ValueIsUndefined(param->thisVal)) {\r
+        JSI::ReleaseValueList(param->jsiValue, param->args, param->thisVal);\r
+        delete param;\r
         return;\r
     }\r
-    JSIValue success = JSI::GetNamedProperty(args, CB_SUCCESS);\r
-    JSIValue complete = JSI::GetNamedProperty(args, CB_COMPLETE);\r
+    JSIValue success = JSI::GetNamedProperty(param->args, CB_SUCCESS);\r
+    JSIValue complete = JSI::GetNamedProperty(param->args, CB_COMPLETE);\r
     if (!JSI::ValueIsUndefined(success)) {\r
-        if (JSI::ValueIsUndefined(jsiValue)) {\r
-            JSI::CallFunction(success, thisVal, nullptr, 0);\r
+        if (JSI::ValueIsUndefined(param->jsiValue)) {\r
+            JSI::CallFunction(success, param->thisVal, nullptr, 0);\r
         } else {\r
-            JSI::CallFunction(success, thisVal, &jsiValue, ARGC_ONE);\r
+            JSI::CallFunction(success, param->thisVal, &param->jsiValue, ARGC_ONE);\r
         }\r
     }\r
     if (!JSI::ValueIsUndefined(complete)) {\r
-        JSI::CallFunction(complete, thisVal, nullptr, 0);\r
+        JSI::CallFunction(complete, param->thisVal, nullptr, 0);\r
     }\r
-    JSI::ReleaseValueList(success, complete, ARGS_END);\r
+    JSI::ReleaseValueList(param->jsiValue, param->args, param->thisVal, success, complete, ARGS_END);\r
+    delete param;\r
+}\r
+\r
+void LocationModule::SuccessCallBack(const JSIValue thisVal, const JSIValue args, JSIValue jsiValue)\r
+{\r
+    LocationParams *params = new (std::nothrow) LocationParams();\r
+    if (params == nullptr) {\r
+        return;\r
+    }\r
+    params->thisVal = JSI::AcquireValue(thisVal);\r
+    params->args = JSI::AcquireValue(args);\r
+    params->jsiValue = JSI::AcquireValue(jsiValue);\r
+    JsAsyncWork::DispatchAsyncWork(SuccessCallBackDispatch, reinterpret_cast<void *>(params));\r
 }\r
 \r
 void LocationModule::FailCallBack(const JSIValue thisVal, const JSIValue args, int ret)\r
index 422635f..505fce2 100644 (file)
@@ -31,6 +31,16 @@ namespace ACELite {
 struct LocationParams {\r
     JSIValue args = JSI::CreateUndefined();\r
     JSIValue thisVal = JSI::CreateUndefined();\r
+    JSIValue jsiValue = JSI::CreateUndefined();\r
+};\r
+\r
+class GnssStatusCallback : public Location::IGnssStatusCallback {\r
+public:\r
+    GnssStatusCallback() {};\r
+    ~GnssStatusCallback() {};\r
+\r
+    void OnStatusChange(const std::shared_ptr<OHOS::Location::SatelliteStatus> &statusInfo) override;\r
+private:\r
 };\r
 \r
 class LocatorCallback : public Location::ILocatorCallback {\r
@@ -56,11 +66,19 @@ public:
     LocationModule() = default;\r
     ~LocationModule() = default;\r
     static const char * const COORD_TYPES;\r
-    static const double LONGITUDE;\r
-    static const double LATITUDE;\r
-    static const double ALTITUDE;\r
-    static const double ACCURACY;\r
-    static const uint32_t TIME;\r
+    static double LONGITUDE;\r
+    static double LATITUDE;\r
+    static double ALTITUDE;\r
+    static double ACCURACY;\r
+    static uint32_t TIME;\r
+    static double SPEED_ACCURACY;\r
+    static double ALTITUDE_ACCURACY;\r
+    static double DIRECTION_ACCURACY;\r
+    static double VELOCITY_NORTH;\r
+    static double VELOCITY_EAST;\r
+    static double VELOCITY_DESCEND;\r
+    static int32_t SATELLITE_NUMBER;\r
+    static int32_t STATUS_NUMBER;\r
     static const char * const LONGITUDE_NAME;\r
     static const char * const LATITUDE_NAME;\r
     static const char * const ALTITUDE_NAME;\r
@@ -70,25 +88,35 @@ public:
     static const char * const LOCATIONTYPE_NAME;\r
     static const char * const LOCATIONTYPE;\r
     static const char * const TIMEOUT;\r
+    static const char * const SPEED_ACCURACY_NAME;\r
+    static const char * const ALTITUDE_ACCURACY_NAME;\r
+    static const char * const DIRECTION_ACCURACY_NAME;\r
+    static const char * const VELOCITY_NORTH_NAME;\r
+    static const char * const VELOCITY_EAST_NAME;\r
+    static const char * const VELOCITY_DESCEND_NAME;\r
+    static const char * const STATUS_NUMBER_NAME;\r
+    static const char * const SATELLITE_NUMBER_NAME;\r
     static JSIValue GetSupportCoordTypes(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
     static JSIValue Unsubscribe(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
     static JSIValue Subscribe(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
     static JSIValue GetLocationType(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
     static JSIValue GetLocation(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
     static void ExecuteSubscribe(void* data);\r
-    static void ExecuteUnsubscribe();\r
+    static void ExecuteUnsubscribe(void* data);\r
     static void ExecuteGetLocationType(void* data);\r
     static void ExecuteGetLocation(void* data);\r
-\r
+    static void OnDestroy();\r
 private:\r
     friend class LocatorCallback;\r
     static JSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum, AsyncWorkHandler ExecuteFunc);\r
     static void SuccessCallBack(const JSIValue thisVal, const JSIValue args, JSIValue jsiValue);\r
+    static void SuccessCallBackDispatch(void *data);\r
     static void FailCallBack(const JSIValue thisVal, const JSIValue args, int ret);\r
     static int32_t SubscribeAndStartLocating(void *data);\r
     static int32_t UnsubscribeAndStopLocating();\r
+    static void DestroyResources();\r
     static LocatorCallback *locatorCallback_;\r
-    \r
+    static GnssStatusCallback *gnssStatusCallback_;\r
 };\r
 \r
 void InitLocationModule(JSIValue exports)\r
@@ -98,6 +126,8 @@ void InitLocationModule(JSIValue exports)
     JSI::SetModuleAPI(exports, "subscribe", LocationModule::Subscribe);\r
     JSI::SetModuleAPI(exports, "getLocationType", LocationModule::GetLocationType);\r
     JSI::SetModuleAPI(exports, "getLocation", LocationModule::GetLocation);\r
+    JSI::SetOnDestroy(exports, LocationModule::OnDestroy);\r
+    JSI::SetOnTerminate(exports, LocationModule::OnDestroy);\r
 }\r
 \r
 } // namespace ACELite\r
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_callback.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_callback.h
new file mode 100644 (file)
index 0000000..ee078b2
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: http callback interfaces
+ * Author: Software Group
+ * Create: 2025-09-1
+ */
+
+#ifndef HTTP_CALLBACK_H
+#define HTTP_CALLBACK_H
+
+#include "jsi.h"
+#include "httpclient.h"
+#include "http_errcode.h"
+#include "ace_mem_base.h"
+
+namespace OHOS {
+namespace ACELite {
+
+typedef HTTP_REQUEST_TYPE HttpRequestType;
+typedef HTTP_ERRCODE HttpErrcode;
+typedef HTTPC_RESULT HttpcResult;
+
+enum HttpDataType {
+    DATA_TYPE_STRING = 0,
+    DATA_TYPE_OBJECT = 1,
+    DATA_TYPE_ARRAY_BUFFER = 2
+};
+
+enum HttpEventId {
+    HTTP_EVENT_RECEIVE = 0,
+    HTTP_EVENT_PROGRESS = 1,
+    HTTP_EVENT_END = 2,
+    HTTP_EVENT_MAX = 3
+};
+
+struct HttpResult {
+    HttpErrcode resCode;
+    int responseCode;
+    const char *errMsg;
+    uint8_t *data;
+    int dataLen;
+    int receiveSize;
+    int totalSize;
+    bool isMore;
+    bool isFinish;
+    HttpDataType datatype;
+    HttpEventId eventId;
+    JSIValue context;
+    JSIValue callback;
+};
+
+class HttpCallback : public MemoryHeap {
+public:
+    virtual ~HttpCallback() {}
+    virtual void CreateCallback(HttpResult* result) {}
+    virtual void CreateSubscription(HttpResult* result){}
+};
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_module.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_module.h
new file mode 100644 (file)
index 0000000..8d817bc
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+ * Copyright (c) CompanyNameMagicTag. 2024-2025. All rights reserved.\r
+ * Description: http control interfaces\r
+ * Author: Software Group\r
+ * Create: 2025-03-28\r
+ */\r
+\r
+#ifndef HTTP_MODULE_H\r
+#define HTTP_MODULE_H\r
+\r
+#include <stdint.h>\r
+#include <map>\r
+#include <cstring>\r
+#include "cmsis_os2.h"\r
+#include "jsi.h"\r
+#include "httpclient.h"\r
+\r
+namespace OHOS {\r
+namespace ACELite {\r
+\r
+class HttpModule final : public MemoryHeap {\r
+public:\r
+    HttpModule() = default;\r
+    ~HttpModule() = default;\r
+\r
+    static JSIValue CreateHttp(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Request(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue RequestInStream(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Download(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Upload(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue On(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Once(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Off(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Destroy(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static void OnTerminate();\r
+\r
+private:\r
+    static HttpRequestType GetRequestType(const char *method);\r
+    static HttpEventId GetEventId(const char *event);\r
+    static char *HeaderJsonToString(char* headerJson);\r
+};\r
+void InitHttpClientModule(JSIValue exports);\r
+\r
+}  // namespace ACELite\r
+}  // namespace OHOS\r
+\r
+#endif  // HTTP_MODULE_H
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_module_callback.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_module_callback.h
new file mode 100644 (file)
index 0000000..42f8353
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: http module callback interfaces
+ * Author: Software Group
+ * Create: 2025-09-1
+ */
+
+#ifndef HTTP_MODULE_CALLBACK_H
+#define HTTP_MODULE_CALLBACK_H
+
+#include "jsi.h"
+#include "http_errcode.h"
+#include "http_callback.h"
+
+namespace OHOS {
+namespace ACELite {
+
+class HttpModuleCallback final : public HttpCallback {
+public:
+
+    static HttpModuleCallback* GetInstance()
+    {
+        static HttpModuleCallback instance;
+        return &instance;
+    }
+
+    void CreateCallback(HttpResult* result) override;
+    void CreateSubscription(HttpResult* result) override;
+
+    static void ExecuteCallFunc(void *params);
+    static void ExecuteSubscription(void *params);
+private:
+    HttpModuleCallback() = default;
+    ~HttpModuleCallback() = default;
+
+    static void SendData(HttpResult* result);
+    static void SendStateInfo(HttpResult* result);
+};
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif // HTTP_MODULE_CALLBACK_H
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_module_client.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/http/http_module_client.h
new file mode 100644 (file)
index 0000000..5076f79
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: http client interfaces
+ * Author: Software Group
+ * Create: 2025-10-20
+ */
+
+#ifndef HTTP_MODULE_CLIENT_H
+#define HTTP_MODULE_CLIENT_H
+
+#include <mutex>
+#include "cmsis_os2.h"
+#include "http_errcode.h"
+#include "httpclient.h"
+#include "http_module_callback.h"
+
+namespace OHOS {
+namespace ACELite {
+
+enum HttpRequestId {
+    HTTP_REQUEST,
+    HTTP_REQUESTINSTREAM,
+    HTTP_DOWNLOAD,
+    HTTP_UPLOAD,
+    HTTP_FINISH,
+};
+
+struct HttpParam {
+    const char *url;
+    const char *header;
+    const char *filePath;
+    const char *clientCert;
+    char *postBuf;
+};
+
+struct HttpMessage {
+    HttpRequestId requestId;
+    HttpRequestType requestType;
+    HttpParam param;
+    int dataType;
+    JSIValue context;
+    JSIValue callback;
+};
+
+struct HttpRequest {
+    JSIValue request;
+    JSIValue requestInStream;
+    JSIValue download;
+    JSIValue upload;
+    JSIValue on;
+    JSIValue once;
+    JSIValue off;
+    JSIValue destroy;
+};
+
+struct HttpEvent {
+    JSIValue callback;
+    bool isOnce;
+};
+
+class HttpModuleClient final : public MemoryHeap {
+public:
+    HttpModuleClient();
+    ~HttpModuleClient();
+
+    bool IsRunning(void) const
+    {
+        return isRunning_ ;
+    }
+
+    void InitCallback(HttpCallback* cbkInstance)
+    {
+        cbkInstance_ = cbkInstance;
+    }
+
+    void Request(HttpParam &param, HttpRequestType requestType, int expectDataType, JSIValue context, JSIValue callback);
+    void RequestInStream(HttpParam &param, HttpRequestType requestType, int expectDataType, JSIValue context, JSIValue callback);
+    void Download(HttpParam &param, JSIValue context, JSIValue callback);
+    void Upload(HttpParam &param, JSIValue context, JSIValue callback);
+
+    bool InitClient(void);
+    bool CreateHttpThread(void);
+    void StopThread(void);
+    osStatus_t HttpMessagePut(HttpMessage *message);
+    osStatus_t HttpMessageGet(HttpMessage *message);
+    HttpErrcode GetErrorCode(int errorCode);
+
+    void SetHttpEvent(JSIValue callback, bool isOnce, HttpEventId id);
+    JSIValue GetHttpEvent(HttpEventId id);
+
+    HttpClient client_{};
+    HttpClientData clientData_{};
+    osMessageQueueId_t httpQueueId_ = nullptr;
+    HttpRequest request_;
+    HttpEvent httpEvents_[HTTP_EVENT_MAX];
+private:
+    void ReleaseJSIValue(JSIValue value)
+    {
+        if (!JSI::ValueIsUndefined(value)) {
+            JSI::ReleaseValue(value);
+        }
+    }
+
+    HttpDataType GetContentType(int expectDataType);
+    void CheckSubscription(HttpResult result);
+
+    void ResetClient(void);
+    void CloseClient(void);
+    void ReleaseThread(void);
+
+    static const uint32_t REQ_BUF_SIZE = 2048;
+    static const uint32_t RSP_BUF_SIZE = 2048;
+    bool isRunning_  = false;
+    void *stackMem_ = nullptr;
+    osThreadId_t streamId_ = nullptr;
+    HttpCallback* cbkInstance_;
+    std::mutex clientMutex_;
+};
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif  // HTTP_MODULE_CLIENT_H
\ No newline at end of file
index ce683ec..f7c90a0 100644 (file)
@@ -18,7 +18,7 @@
 
 /** @brief   http requst type */
 typedef enum {
-    NET_SUCCESS               =  200,
+    NET_SUCCESS               =  0,
     NET_PARAMETER_ERROR       =  401,
     NET_PERMISSION_DENIED     =  201,
     NET_UNSUPPORTED_PROTOCOL  =  2300001,
@@ -52,5 +52,21 @@ typedef enum {
     NET_UNKNOWN_ERROR         =  2300999,
 } HTTP_ERRCODE;
 
+typedef enum {
+    WEBSOCKET_SUCCESS   =  0,
+    WEBSOCKET_CONNECT_FAILED   =  200,
+    WEBSOCKET_URL_ERROR        =  2302001,
+    WEBSOCKET_CERT_MISSING     =  2302002,
+    WEBSOCKET_CONN_EXISTS      =  2302003,
+    WEBSOCKET_NIC_ERROR        =  2302004,
+    WEBSOCKET_PORT_ERROR       =  2302005,
+    WEBSOCKET_DOMAIN_DENIED    =  2302998,
+    WEBSOCKET_INTERNAL_ERROR   =  2302999,
+    WEBSOCKET_AUTH_FAILED      =  201,
+    WEBSOCKET_API_AUTH_FAILED  =  202,
+    WEBSOCKET_FUNC_DENIED      =  203,
+    WEBSOCKET_PARAM_ERROR      =  401,
+    WEBSOCKET_API_UNSUPPORTED  =  801
+} WEBSOCKET_ERRCODE;
 
 #endif /* HTTPCLIENT_H */
\ No newline at end of file
index 9a4712a..28d2b03 100644 (file)
@@ -76,6 +76,8 @@ typedef struct {
     char *headerBuf;        /**< buffer to store the response head data. */
     bool isRedirected;      /**< redirected URL? if 1, has redirect url; if 0, no redirect url */
     char *redirectUrl;      /**< redirect url when got http 3** response code. */
+    char *leftBuffer;       /**< buffer to store last recv not report to user */
+    int leftBufferLen;      /**< last recv buffer length, not report to user */
 } HttpClientData;
 
 /**
@@ -186,6 +188,15 @@ HTTPC_RESULT HttpClientRecvResponse(HttpClient *client, HttpClientData *clientDa
  */
 void HttpClientClse(HttpClient *client);
 
+/**
+ * This function sends HTTP request.
+ * @param[in] client            a pointer to the #HttpClient.
+ * @param[in] data              post data buffer
+ * @param[in] length            buffer length
+ * @return   length of data be uploaded to server; value < 0, if errors occurred.
+ */
+int HttpClientSendData(HttpClient *client, const char *postData, size_t length);
+
 /**
  * This function sets a custom header.
  * @param[in] client               client is a pointer to the #HttpClient.
@@ -211,6 +222,33 @@ int HttpClientGetResponseCode(HttpClient *client);
  */
 int HttpClientGetResponseHeaderValue(char *headerBuf, char *name, int *valPos, int *valLen);
 
+/**
+ * This function add text formdata information.
+ * @param[in] clientData          clientData is a pointer to the #HttpClientData.
+ * @param[in] contentType         contentType is a pointer to the content type string.
+ * @param[in] name                 name is a pointer to the name string.
+ * @param[in] data                 data is a pointer to the data.
+ * @param[in] dataLen             dataLen is the data length.
+ * @return           The HTTP response code of the last request.
+ */
+int HttpClientFormdataAddText(HttpClientData *clientData, char *contentType, char *name, char *data, int dataLen);
+
+/**
+ * This function add file formdata information.
+ * @param[in] clientData          clientData is a pointer to the #HttpClientData.
+ * @param[in] name                 name is a pointer to the name string.
+ * @param[in] contentType         contentType is a pointer to the content type string.
+ * @param[in] filePath            filePath is a pointer to the file path.
+ * @return           The HTTP response code of the last request.
+ */
+int HttpClientFormdataAddfile(HttpClientData *clientData, char *name, char *contentType, char *filePath);
+
+/**
+ * This function clear file formdata information.
+ * @param[in] clientData          clientData is a pointer to the #HttpClientData.
+ * @return           None.
+ */
+void HttpClientClearFormData(HttpClientData *clientData);
 #ifdef __cplusplus
 }
 #endif
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/http/internal/http_form_data.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/http/internal/http_form_data.h
new file mode 100644 (file)
index 0000000..7c5e1bf
--- /dev/null
@@ -0,0 +1,41 @@
+/*\r
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.\r
+ */\r
+#ifndef HTTP_FORM_DATA\r
+#define HTTP_FORM_DATA\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define FORM_DATA_PATH_MAXLEN 64\r
+#define CLIENT_FORM_DATA_NUM 1\r
+\r
+#define FORM_DATA_BOUNDARY "----WebKitFormBoundarypXEfCkZnHjoOSnPc0"\r
+#define FORM_DATA_BOUNDARY_START "\r\n--" FORM_DATA_BOUNDARY\r
+#define FORM_DATA_BOUNDARY_END FORM_DATA_BOUNDARY_START "--\r\n"\r
+\r
+typedef struct HttpFormDataNode HttpFormDataNode;\r
+struct HttpFormDataNode {\r
+    HttpFormDataNode *next;\r
+    int isFile;\r
+    char filePath[FORM_DATA_PATH_MAXLEN];\r
+    char *formatContent;\r
+    int formatLen;\r
+};\r
+\r
+typedef struct {\r
+    int isUsed;\r
+    HttpFormDataNode *formDataNode;\r
+    HttpClient *clientData;\r
+} FormDataInfo;\r
+\r
+void HttpClientClearFormData(HttpClientData *clientData);\r
+int HttpClientFormdataLen(HttpClientData *clientData);\r
+int HttpClientSendFormdata(HttpClient *client, HttpClientData *clientData);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif
\ No newline at end of file
index 2129599..9d8232e 100644 (file)
@@ -14,10 +14,10 @@ extern "C" {
 #define http_debug
 
 #ifndef HTTP_MIN
-#define HTTP_MIN(x,y) (((x)<(y))?(x):(y))
+#define HTTP_MIN(x, y) (((x) < (y)) ? (x) : (y))
 #endif
 #ifndef HTTP_MAX
-#define HTTP_MAX(x,y) (((x)>(y))?(x):(y))
+#define HTTP_MAX(x, y) (((x) > (y)) ? (x) : (y))
 #endif
 
 int HttpTcpConnWrapper(HttpClient *client, const char *host);
index c9d6278..41829d4 100644 (file)
@@ -39,7 +39,6 @@ struct WebSocketErrorResult {
  * @brief Defines the callback function invoked when an <b>open</b> message is received.
  *
  * @param client WebSocket client fd.
- * @param openResult Content of the <b>open</b> message received by the WebSocket client.
  * @since 11
  * @version 1.0
  */
@@ -73,7 +72,7 @@ typedef void (*WebSocketOnErrorCallback)(int client, struct WebSocketErrorResult
  *
  * @param client WebSocket client.
  */
-typedef void (*WebSocketOnCloseCallback)(int client);
+typedef void (*WebSocketOnCloseCallback)(int client, struct WebSocketErrorResult errorResult);
 
 
 typedef enum WebSocketErrCode {
@@ -158,6 +157,8 @@ typedef enum WebSocketErrCode {
     WEBSOCKET_ERROR_CONNECT_TO_HOST = (-19),
 
     WEBSOCKET_ERROR_CONNECT_CLOSED = (-20),
+
+    WEBSOCKE_ERROR_CONNECTION_NOT_CLOSED = (-21),
 } WebSocketErrCode;
 
 
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_debug.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_debug.h
new file mode 100644 (file)
index 0000000..4e4a0be
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef __NET_WEBSOCKET_DEBUG_H__
+#define __NET_WEBSOCKET_DEBUG_H__
+
+#include <stdio.h>
+
+#define WS_DBG_LEVEL WEBSOCKET_DBG_OFF
+
+#define WS_INFO_LEVEL WEBSOCKET_DBG_ON
+
+#define WS_ERR_LEVEL WEBSOCKET_DBG_ON
+
+/** flag for WEBSOCKET_DEBUGF to enable that debug message */
+#define WEBSOCKET_DBG_ON 0x80U
+/** flag for WEBSOCKET_DEBUGF to disable that debug message */
+#define WEBSOCKET_DBG_OFF 0x00U
+
+#define WEBSOCKET_DEBUG
+
+#ifdef WEBSOCKET_DEBUG
+#define WS_PLATFORM_DIAG(x) \
+    do {                    \
+        printf x;           \
+    } while (0)
+#define WEBSOCKET_DEBUGF(debug, message)  \
+    do {                                  \
+        if (((debug)&WEBSOCKET_DBG_ON)) { \
+            WS_PLATFORM_DIAG(message);    \
+        }                                 \
+    } while (0)
+
+#else /* WEBSOCKET_DEBUG */
+#define WEBSOCKET_DEBUGF(debug, message)
+#endif /* WEBSOCKET_DEBUG */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_frame.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_frame.h
new file mode 100644 (file)
index 0000000..fd6971d
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef _NET_WS_FRAME_H__
+#define _NET_WS_FRAME_H__
+
+#include <stdint.h>
+#include "net_websocket.h"
+#include "net_websocket_priv.h"
+
+typedef enum {
+    WS_OPCODE_CONTINUATION = 0x0,      // %x0 denotes a continuation frame
+    WS_OPCODE_TEXT_FRAME = 0x1,        // %x1 denotes a text frame
+    WS_OPCODE_BINARY_FRAME = 0x2,      // %x2 denotes a binary frame
+    WS_OPCODE_CONNECTION_CLOSE = 0x8,  // %x8 denotes a connection close
+    WS_OPCODE_PING = 0x9,              // %x9 denotes a ping
+    WS_OPCODE_PONG = 0xA               // %xA denotes a pong
+} WsOpcode;
+
+typedef enum WsBinaryCode { WS_BINARY_START, WS_BINARY_CONTINUE, WS_BINARY_END } WsBinary;
+
+typedef struct WsFrameStruct {
+    uint8_t *data;
+    size_t length;
+    WsOpcode opcode;
+    uint8_t mask[4]; /* 4: mask length */
+    bool isMasked;
+    bool isFinished;
+    uint8_t headerSize;
+} WsFrame;
+
+size_t WsCheckRecvFrameSize(const uint8_t *data, const size_t data_size);
+
+WsFrame *WsFrameCreateWithRecvData(struct WebSocketClient *clientPtr, const uint8_t *data, const size_t length);
+
+void WsFrameFillWithSendBinData(WsFrame *frame, const uint8_t *data, const size_t length, WsBinary binType);
+
+// data - should be null, and setted by newly created. 'data' & 'data_size' can be null
+void WsFrameFillWithSendData(WsFrame *frame, const uint8_t *data, const size_t data_size, bool is_finish);
+
+// combine datas of 2 frames. combined is 'to'
+void WsFrameCombineDatas(WsFrame *to, WsFrame *from);
+
+WsFrame *WsFrameCreate(struct WebSocketClient *clientPtr);
+
+void WsDeleteFrame(WsFrame *frame);
+
+void WsInitFrameRandom(struct WebSocketClient *clientPtr);
+
+void WsFreeRandom(struct WebSocketClient *clientPtr);
+
+#endif
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_list.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_list.h
new file mode 100644 (file)
index 0000000..74bd274
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef __NET_WS_LIST_H__
+#define __NET_WS_LIST_H__
+
+#include <stdio.h>
+
+typedef union WsNodeValueUnion {
+    void *object;
+    char *string;
+} WsNodeValue;
+
+typedef struct WsNodeStruct {
+    WsNodeValue value;
+    struct WsNodeStruct *next;
+} WsNode, WsList;
+
+WsList *WsListCreate(void);
+
+void WsListDelete(WsList *list);
+
+void WsListDeleteClean(WsList **list);
+
+int WsListAppend(WsList *list, WsNodeValue value);
+
+#endif
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_opts.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_opts.h
new file mode 100644 (file)
index 0000000..54dca87
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+ 
+#ifndef NET_WEBSOCKET_OPTS_H
+#define NET_WEBSOCKET_OPTS_H
+
+#define WEBSOCKET_RECV_BUFF_SIZE (20 * 1024)
+
+#define WS_MAX_THRESH_VAL (20 * 1024) /* common TTS play size */
+
+#define WS_MAX_CLIENT_NUM 4
+
+#define WS_MAX_DATA_LENGTH (20 * 1024)
+
+#define WSS_READ_TIMEOUT_MS 100
+
+#define WS_THREAD_STACK_SIZE (6 * 1024)
+
+#define WS_THREAD_SLEEP_MS 100
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_priv.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_priv.h
new file mode 100644 (file)
index 0000000..0151115
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef __NET_WEBSOCKET_PRIV_H__
+#define __NET_WEBSOCKET_PRIV_H__
+
+#include "lwip/sockets.h"
+#include <lwip/netdb.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "net_websocket.h"
+#include "net_websocket_type.h"
+#include "net_websocket_opts.h"
+#include "net_websocket_thread.h"
+#include "net_websocket_frame.h"
+#include "net_websocket_list.h"
+
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/entropy.h"
+
+#ifdef WEBSOCKET_SSL_ENABLE
+#include "mbedtls/net_sockets.h"
+#include "mbedtls/ssl.h"
+#endif
+
+typedef int WsSocket;
+#define WS_INVALID_SOCKET -1
+#define WS_SOCK_CLOSE(sock) closesocket(sock)
+
+#define O_NONBLOCK 04000
+
+#ifdef WEBSOCKET_SSL_ENABLE
+typedef struct WsSslStruct {
+    mbedtls_ssl_context sslCtx; /* mbedtls ssl context */
+    mbedtls_net_context netCtx; /* Fill in socket id */
+    mbedtls_ssl_config sslConf; /* SSL configuration */
+    mbedtls_entropy_context entropy;
+    mbedtls_ctr_drbg_context ctrDrbg;
+    mbedtls_x509_crt_profile profile;
+    mbedtls_x509_crt cacert;
+    mbedtls_x509_crt clicert;
+    mbedtls_pk_context pkey;
+} WsSsl;
+#endif
+
+#define WS_MAX_SCHEME_LEN 16
+
+struct WebSocketClient {
+    int clientfd;
+    int port;
+    WsSocket socket;
+    char scheme[WS_MAX_SCHEME_LEN];
+    char *url;
+    char *host;
+    char *requestOption;
+
+    char *secWsProtocol;  // "Sec-WebSocket-Protocol" field
+    char *secWsAccept;    // "Sec-WebSocket-Accept" field from handshake
+
+    WsThread workThread;
+
+    int command;
+
+    bool isConnected;  // sock connected + handshake done
+
+    /** Pointer to the callback invoked when a connection message is received */
+    WebSocketOnOpenCallback onOpen;
+    /** Pointer to the callback invoked when a message is received */
+    WebSocketOnMessageCallback onMessage;
+    /** Pointer to the callback invoked when an error message is received */
+    WebSocketOnErrorCallback onError;
+    /** Pointer to the callback invoked when a close message is received */
+    WebSocketOnCloseCallback onClose;
+
+    uint8_t *received;
+    size_t receivedSize;  // size of 'received' memory
+    size_t receivedLen;   // length of actualy readed message
+
+    WsList *sendFrames;
+    WsList *recvdFrames;
+
+    WsMutex workMutex;
+    WsMutex sendMutex;
+
+    mbedtls_entropy_context randomEntropy; /* random entropy */
+    mbedtls_ctr_drbg_context randomCtrDrbg;
+
+#ifdef WEBSOCKET_SSL_ENABLE
+    const char *serverCert; /**< Server certification. */
+    const char *clientCert; /**< Client certification. */
+    const char *clientPk;   /**< Client private key. */
+    int serverCertLen;      /**< Server certification lenght, server_cert buffer size. */
+    int clientCertLen;      /**< Client certification lenght, client_cert buffer size. */
+    int clientPkLen;        /**< Client private key lenght, client_pk buffer size. */
+    WsSsl *ssl;             /**< Ssl content. */
+#endif
+    char *recvBuffer;
+    int recvBufferSize;
+
+    struct WebSocketErrorResult errorResult;
+};
+
+void WebSocketClientClosePriv(struct WebSocketClient *clientPtr);
+
+struct WebSocketClient *WsGetClient(int fd);
+
+int AllocWsClient(void);
+
+int WsSocketSendTextPriv(struct WebSocketClient *clientPtr, const char *text);
+
+int WsClientSendBinStartPriv(struct WebSocketClient *clientPtr, const char *data, size_t length);
+
+int WsClientIdleDataSend(struct WebSocketClient *clientPtr);
+
+#define COMMAND_IDLE -1
+#define COMMAND_NONE 0
+#define COMMAND_CONNECT_TO_HOST 1
+#define COMMAND_SEND_HANDSHAKE 2
+#define COMMAND_WAIT_HANDSHAKE_RESPONCE 3
+#define COMMAND_INFORM_CONNECTED 4
+#define COMMAND_INFORM_DISCONNECTED 5
+
+#define COMMAND_END 9999
+
+#endif
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_string.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_string.h
new file mode 100644 (file)
index 0000000..2e4325c
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+#ifndef __NET_WS_STRING_H__
+#define __NET_WS_STRING_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *WsStringCopy(const char *str);
+
+char *WsStringCopyLen(const char *str, const size_t len);
+
+void WsStringDelete(char *str);
+
+void WsStringDeleteClean(char **str);
+
+#endif
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_thread.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/internal/net_websocket_thread.h
new file mode 100644 (file)
index 0000000..08d6fea
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#ifndef __NET_WS_THREAD_H__
+#define __NET_WS_THREAD_H__
+
+#include <stdio.h>
+#include "cmsis_os2.h"
+
+#define RWS_WAIT_FOREVER 0xffffffffu
+
+/**
+ @brief Callback type of thread function.
+ @param userObject User object provided during thread creation.
+ */
+typedef void (*WsThreadFunct)(void *userObject);
+
+struct WsThreadStruct {
+    WsThreadFunct threadFunction;
+    osThreadId_t thread;
+    void *stackMem;
+};
+
+/**
+ @brief Type of all public objects.
+ */
+typedef void *WsHandle;
+
+/**
+ @brief Mutex object handle.
+ */
+typedef WsHandle WsMutex;
+
+/**
+ @brief Mutex object handle.
+ */
+typedef WsHandle WsSem;
+
+/**
+ @brief Thread object handle.
+ */
+typedef struct WsThreadStruct *WsThread;
+
+WsThread WsThreadCreate(WsThreadFunct threadFunction, void *userObject);
+
+void WsThreadMsleep(const unsigned int millisec);
+
+WsMutex WsMutexCreateRecursive(void);
+
+void WsMutexLock(WsMutex mutex);
+
+void WsMutexUnLock(WsMutex mutex);
+
+void WsMutexDelete(WsMutex mutex);
+
+WsSem WsSemCreate(void);
+
+void WsSemDelete(WsSem sem);
+
+void WsSemSignal(WsSem sem);
+
+int WsThreadSuspend(WsThread workThread);
+
+int WsThreadResume(WsThread workThread);
+
+#endif
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/connection_manage/connection_manage.cpp b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/connection_manage/connection_manage.cpp
new file mode 100644 (file)
index 0000000..d0da474
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: network connection manage
+ * Author: SoftwarePlatform Group
+ * Create: 2025-11-12
+ */
+
+#include <list>
+#include <mutex>
+#include "settings/model/SettingBluetoothModel.h"
+#include "msg_center_protocol.h"
+#include "connection_manage.h"
+
+typedef struct NetConnectionParam {
+    uint8_t networkType;
+    NetConnectionCallback callback;
+} NetConnectionParam;
+
+static std::list<NetConnectionParam *> g_callbackList;
+static std::mutex g_callbackMutex;
+static int g_registerCount = 0;
+
+
+void NetConnectChange(uint8_t networkType, uint8_t netConnectState)
+{
+    g_callbackMutex.lock();
+    for (auto iter = g_callbackList.begin(); iter != g_callbackList.end(); iter++) {
+        NetConnectionCallback callback = (*iter)->callback;
+        uint8_t type = (*iter)->networkType;
+
+        if (type == networkType && callback != nullptr) {
+            g_callbackMutex.unlock();
+            callback(networkType, netConnectState);
+            g_callbackMutex.lock();
+        }
+    }
+    g_callbackMutex.unlock();
+}
+
+static void LwipNetConnectionChange(uint8_t netifType, uint8_t netConnectState)
+{
+    uint8_t networkType = NETWORK_TYPE_UNKNOWN;
+    if (netifType == LWIP_NETIF_VOLTE) {
+        networkType = NETWORK_TYPE_CELL_LTE_CAT1;
+    }
+    if (netifType == LWIP_NETIF_BT_PAN) {
+        networkType = NETWORK_TYPE_BLUETOOTH_PAN;
+    }
+    NetConnectChange(networkType, netConnectState);
+}
+
+static void RegisterLwipNetListener(uint8_t networkType)
+{
+    if (networkType != NETWORK_TYPE_BLUETOOTH_PAN && networkType != NETWORK_TYPE_CELL_LTE_CAT1) {
+        return;
+    }
+    if (g_registerCount == 0) {
+        lwip_register_connect_listener(LwipNetConnectionChange);
+    }
+    g_registerCount++;
+}
+
+static void UnRegisterLwipNetListener(uint8_t networkType)
+{
+    if (networkType == NETWORK_TYPE_BLUETOOTH_PAN || networkType == NETWORK_TYPE_CELL_LTE_CAT1) {
+        g_registerCount--;
+        if (g_registerCount == 0) {
+            lwip_unregister_connect_listener(LwipNetConnectionChange);
+        }
+    }
+}
+
+int RegisterConnectListener(uint8_t networkType, NetConnectionCallback callback)
+{
+    if (callback == nullptr) {
+        return -1;
+    }
+    NetConnectionParam *param = (NetConnectionParam *)malloc(sizeof(NetConnectionParam));
+    if (param == nullptr) {
+        return -1;
+    }
+    param->networkType = networkType;
+    param->callback = callback;
+
+    g_callbackMutex.lock();
+    for (auto iter = g_callbackList.begin(); iter != g_callbackList.end(); iter++) {
+        if ((*iter)->callback == callback && (*iter)->networkType == networkType) {
+            g_callbackMutex.unlock();
+            free(param);
+            return 0;
+        }
+    }
+    g_callbackList.push_back(param);
+    g_callbackMutex.unlock();
+    RegisterLwipNetListener(networkType);
+    return 0;
+}
+
+void UnregisterConnectListener(uint8_t networkType, NetConnectionCallback callback)
+{
+    if (callback == nullptr) {
+        return;
+    }
+    g_callbackMutex.lock();
+    for (auto iter = g_callbackList.begin(); iter != g_callbackList.end();) {
+        if ((*iter)->networkType == networkType && (*iter)->callback == callback) {
+            UnRegisterLwipNetListener((*iter)->networkType);
+            free(*iter);
+            *iter = nullptr;
+            iter = g_callbackList.erase(iter);
+        } else {
+            iter++;
+        }
+    }
+    g_callbackMutex.unlock();
+}
+
+uint8_t GetNetConnectState(uint8_t netType)
+{
+    uint8_t state = CONNECTION_STATUS_UNKNOWN;
+    switch (netType) {
+        case NETWORK_TYPE_WIFI:
+            break;
+        case NETWORK_TYPE_BLUETOOTH:
+            state = OHOS::SettingBluetoothModel::GetInstance()->GetAclConnected() ? CONNECTION_STATUS_CONNECTED
+                                                                           : CONNECTION_STATUS_DISCONNECTED;
+            break;
+        case NETWORK_TYPE_BLUETOOTH_LE:
+            state = (msg_center_get_ble_conn_state() == GAP_BLE_STATE_CONNECTED) ? CONNECTION_STATUS_CONNECTED
+                                                                                 : CONNECTION_STATUS_DISCONNECTED;
+            break;
+        case NETWORK_TYPE_BLUETOOTH_PAN:
+            lwip_get_connect_status(LWIP_NETIF_BT_PAN, &state);
+            break;
+        case NETWORK_TYPE_CELL_LTE_CAT1:
+            lwip_get_connect_status(LWIP_NETIF_VOLTE, &state);
+            break;
+        default:
+            state = CONNECTION_STATUS_UNKNOWN;
+            break;
+    }
+    return state;
+}
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/connection_manage/connection_manage.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/connection_manage/connection_manage.h
new file mode 100644 (file)
index 0000000..d40d8f4
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: network connection manage
+ * Author: SoftwarePlatform Group
+ * Create: 2025-11-12
+ */
+
+
+#include "lwip_driver_adapter.h"
+#include "network_listener.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Defines the callback function net connection status change.
+ *
+ * @param networkType network type, refer to #NetworkType.
+ * @param netConnectState net connection status, refer to #ConnectionState.
+ */
+typedef void (*NetConnectionCallback)(const uint8_t networkType, const uint8_t netConnectState);
+
+/**
+ * @brief This function register network connection status listener.
+ * @param[in] networkType network type, refer to #NetworkType.
+ * @param[in] callback   net connection callback.
+ * @return 0 if success; non-0 otherwise.
+ */
+int RegisterConnectListener(uint8_t networkType, NetConnectionCallback callback);
+
+/**
+ * @brief Defines the callback unregister function for listening net connection status change.
+ * @param[in] networkType network type, refer to #NetworkType.
+ * @param[in] callback   net connection callback.
+ * @return 0 if success; non-0 otherwise.
+ */
+void UnregisterConnectListener(uint8_t networkType, NetConnectionCallback callback);
+
+/**
+ * @brief This function get current network connection status.
+ * @param[in] networkType network type, refer to #NetworkType.
+ * @return netConnectState net connection status, refer to #ConnectionState.
+ */
+uint8_t GetNetConnectState(uint8_t networkType);
+
+void NetConnectChange(uint8_t networkType, uint8_t netConnectState);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/network_listener.cpp b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/network/network_listener.cpp
new file mode 100644 (file)
index 0000000..ab2df11
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2024-2025. All rights reserved.
+ * Description: network wrapper
+ * Author: SoftwarePlatform Group
+ * Create: 2025-11-14
+ */
+
+#include "connection_manage.h"
+#include "network_listener.h"
+
+void net_connect_status_change(uint8_t type, uint8_t netConnectState)
+{
+    NetConnectChange(type, netConnectState);
+}
\ No newline at end of file
index 8d76a8c..097bd13 100644 (file)
@@ -8,25 +8,36 @@
 #ifndef OHOS_ACELITE_NETWORK_LISTENER_H
 #define OHOS_ACELITE_NETWORK_LISTENER_H
 
+#include "lwip_driver_adapter.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 // 网络类型枚举
 typedef enum { 
+    // short reach
     NETWORK_TYPE_WIFI = 0,
-    NETWORK_TYPE_BLUETOOTH,
-    NETWORK_TYPE_BLUETOOTH_LE,
-    NETWORK_TYPE_UNKNOWN
+    NETWORK_TYPE_BLUETOOTH = 1,
+    NETWORK_TYPE_BLUETOOTH_LE = 2,
+    NETWORK_TYPE_BLUETOOTH_PAN = 3,
+    // long reach
+    NETWORK_TYPE_CELL_LTE_CAT1 = 30,
+    NETWORK_TYPE_CELL_4G = 31,
+    // unknown
+    NETWORK_TYPE_UNKNOWN = 100
 } NetworkType;
 
+
 // 连接状态枚举
 typedef enum {
+    // to be connected
     CONNECTION_STATUS_CONNECTING = 0,
-    CONNECTION_STATUS_CONNECTED,
-    CONNECTION_STATUS_DISCONNECTING,
-    CONNECTION_STATUS_DISCONNECTED,
-    CONNECTION_STATUS_UNKNOWN
+    CONNECTION_STATUS_CONNECTED = 1,
+    // to be disconnected
+    CONNECTION_STATUS_DISCONNECTING = 2,
+    CONNECTION_STATUS_DISCONNECTED = 3,
+    CONNECTION_STATUS_UNKNOWN = 100
 } ConnectionState;
 
 void net_connect_status_change(uint8_t type, uint8_t netConnectState);
index 983827a..35306c0 100644 (file)
  * limitations under the License.\r
  */\r
 \r
+#include <unistd.h>\r
+#include <securec.h>\r
 #include "ace_log.h"\r
-#include "js_app_context.h"\r
 #include "js_async_work.h"\r
 #include "product_adapter.h"\r
-#include <securec.h>\r
-#include <unistd.h>\r
-#include "network_module.h"\r
-#ifdef CUSTOM_ZHIHUI\r
-#include "bluetooth/include/BluetoothModel.h"\r
-#else\r
-#include "bluetooth/BluetoothModel.h"\r
-#endif\r
-#include "msg_center_protocol.h"\r
-#include "bts_le_gap.h"\r
+#include "connection_manage.h"\r
 #include "network_listener.h"\r
+#include "network_module.h"\r
+\r
+constexpr uint8_t ARGS_NUM_2 = 2;\r
 \r
 namespace OHOS {\r
 namespace ACELite {\r
 std::map<uint8_t, NetCallBack *> NetWorkModule::callbackSet;\r
 \r
-void NetWorkModule::TriggerCallbackListener(uint8_t type, uint8_t netConnectState)\r
+void NetWorkModule::TriggerCallbackListener(const uint8_t networkType, const uint8_t netConnectState)\r
 {\r
-    auto it = callbackSet.find(type);\r
+    auto it = callbackSet.find(networkType);\r
     if (it != callbackSet.end()) {\r
         NetCallBack *callback = it->second;\r
         callback->netParam.state = netConnectState;\r
-        callback->netParam.net_type = type;\r
+        callback->netParam.net_type = networkType;\r
         if (!JsAsyncWork::DispatchAsyncWork(AsyncExecuteCallback, const_cast<NetCallBack *>(callback))) {\r
             HILOG_ERROR(HILOG_MODULE_ACE, "dispatch async work failed.");\r
         }\r
@@ -51,28 +46,7 @@ static bool ValidJsValue(JSIValue value)
     return (value != nullptr) && (!JSI::ValueIsUndefined(value));\r
 }\r
 \r
-static uint8_t GetNetConnectState(uint8_t net_type)\r
-{\r
-    uint8_t state;\r
-    switch (net_type) {\r
-        case NETWORK_TYPE_WIFI:\r
-            break;\r
-        case NETWORK_TYPE_BLUETOOTH:\r
-            state = OHOS::BluetoothModel::GetInstance()->GetAclConnected() ? CONNECTION_STATUS_CONNECTED\r
-                                                                           : CONNECTION_STATUS_DISCONNECTED;\r
-            break;\r
-        case NETWORK_TYPE_BLUETOOTH_LE:\r
-            state = (msg_center_get_ble_conn_state() == GAP_BLE_STATE_CONNECTED) ? CONNECTION_STATUS_CONNECTED\r
-                                                                                 : CONNECTION_STATUS_DISCONNECTED;\r
-            break;\r
-        default:\r
-            state = CONNECTION_STATUS_UNKNOWN;\r
-            break;\r
-    }\r
-    return state;\r
-}\r
-\r
-const JSIValue GetNetworkStateString(uint8_t type, uint8_t state)\r
+static JSIValue GetNetworkStateString(uint8_t type, uint8_t state)\r
 {\r
     // 网络类型\r
     const char *networkType;\r
@@ -86,6 +60,12 @@ const JSIValue GetNetworkStateString(uint8_t type, uint8_t state)
         case NETWORK_TYPE_BLUETOOTH_LE:\r
             networkType = "Bluetooth LE";\r
             break;\r
+        case NETWORK_TYPE_BLUETOOTH_PAN:\r
+            networkType = "Bluetooth PAN";\r
+            break;\r
+        case NETWORK_TYPE_CELL_LTE_CAT1:\r
+            networkType = "Cell CAT1";\r
+            break;\r
         default:\r
             networkType = "Unknown Network Type";\r
             break;\r
@@ -116,7 +96,7 @@ const JSIValue GetNetworkStateString(uint8_t type, uint8_t state)
         HILOG_ERROR(HILOG_MODULE_ACE, "result buff is too long");\r
     }\r
     JSIValue result = JSI::CreateObject();\r
-    JSI::SetStringProperty(result, "type", networkType);\r
+    JSI::SetNumberProperty(result, "type", type);\r
     JSI::SetNumberProperty(result, "state", state);\r
     JSI::SetStringProperty(result, "description", description);\r
     return result;\r
@@ -140,7 +120,7 @@ JSIValue NetWorkModule::RegisterConnectListener(const JSIValue thisVal, const JS
     if (argsNum == 1) {\r
         type = NETWORK_TYPE_BLUETOOTH;\r
         callbackArg = args[0];\r
-    } else if (argsNum == 2) {\r
+    } else if (argsNum == ARGS_NUM_2) {\r
         if (args == nullptr || JSI::ValueIsUndefined(args[0])) {\r
             HILOG_ERROR(HILOG_MODULE_ACE, "Invalid type argument for registering net connection callback");\r
             return JSI::CreateUndefined();\r
@@ -174,8 +154,7 @@ JSIValue NetWorkModule::RegisterConnectListener(const JSIValue thisVal, const JS
     }\r
     newCallback->netParam.net_type = type;\r
     callbackSet[type] = newCallback;\r
-    uint8_t state = GetNetConnectState(type);\r
-    net_connect_status_change(type, state);\r
+    ::RegisterConnectListener(type, TriggerCallbackListener);\r
     return JSI::CreateUndefined();\r
 }\r
 \r
@@ -201,6 +180,7 @@ JSIValue NetWorkModule::UnregisterConnectListener(const JSIValue thisVal, const
         NetCallBack *callback = it->second;\r
         callbackSet.erase(it);\r
         Clean(callback);\r
+        ::UnregisterConnectListener(type, TriggerCallbackListener);\r
     } else {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "No callback registered for the given type");\r
     }\r
@@ -259,16 +239,3 @@ void InitNetWorkModule(JSIValue exports)
 \r
 }  // namespace ACELite\r
 }  // namespace OHOS\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-void net_connect_status_change(uint8_t type, uint8_t netConnectState)\r
-{\r
-    OHOS::ACELite::NetWorkModule::TriggerCallbackListener(type, netConnectState);\r
-}\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
index fc8061b..ad6ff6d 100644 (file)
@@ -8,15 +8,10 @@
 #ifndef OHOS_ACELITE_NETWORK_MODULE_H\r
 #define OHOS_ACELITE_NETWORK_MODULE_H\r
 \r
-#include <cJSON.h>\r
-#include "acelite_config.h"\r
-#include "jsi.h"\r
 #include <map>\r
-#include "js_async_work.h"\r
 #include "non_copyable.h"\r
-#include "product_adapter.h"\r
-#include "abilityms_slite_client.h"\r
-#include "network_listener.h"\r
+#include "jsi.h"\r
+#include "js_async_work.h"\r
 \r
 namespace OHOS {\r
 namespace ACELite {\r
index a38ac4a..2928a1c 100644 (file)
@@ -37,6 +37,7 @@ extern void InitAppModule(JSIValue exports);
 #ifdef FEATURE_MODULE_AUDIO
 extern void InitAudioModule(JSIValue exports);
 extern void InitAudioCapturerModule(JSIValue exports);
+extern void InitAudioRecorderModule(JSIValue exports);
 extern void InitBaiduMapComponentModule(JSIValue exports);
 #endif // FEATURE_MODULE_AUDIO
 #ifdef FEATURE_ACELITE_DFX_MODULE
@@ -78,12 +79,20 @@ extern void InitBrightnessModule(JSIValue exports);
 extern void InitHttpClientModule(JSIValue exports);
 #endif
 
+#ifdef FEATURE_MODULE_BLE
+extern void InitBleModule(JSIValue exports);
+#endif
+
 #ifdef FEATURE_MODULE_BATTERY
 extern void InitBatteryModule(JSIValue exports);
 #endif
 
+#ifdef FEATURE_MODULE_WATCHFACE
+extern void InitWatchFaceModule(JSIValue exports);
+#endif
+ 
 #ifdef FEATURE_MODULE_WEBSOCKET
-extern void InitWebsocketClientModule(JSIValue exports);
+extern void InitWebSocketClientModule(JSIValue exports);
 #endif
 
 #ifdef FEATURE_MODULE_CONFIGURATION
@@ -93,6 +102,9 @@ extern void InitLocaleModule(JSIValue exports);
 #ifdef FEATURE_MODULE_NFC
 extern void NfcHceInitModule(JSIValue exports);
 #endif
+#ifdef ENABLE_MODULE_CALENDAR
+extern void InitCalendarModule(JSIValue exports);
+#endif
 extern void InitNetWorkModule(JSIValue exports);
 extern void InitKeyInputModule(JSIValue exports);
 // #ifdef FEATURE_ACELITE_SYSTEM_CAPABILITY
@@ -108,6 +120,7 @@ const Module OHOS_MODULES[] = {
 #ifdef FEATURE_MODULE_AUDIO
     {"audio", InitAudioModule},
     {"audiocapturer", InitAudioCapturerModule},
+    {"multimedia.AudioRecorder", InitAudioRecorderModule},
 #endif
 #ifdef FEATURE_MODULE_BAIDU
     {"baidumapcomponent",InitBaiduMapComponentModule},
@@ -152,6 +165,9 @@ const Module OHOS_MODULES[] = {
 #ifdef FEATURE_MODULE_HTTP
     {"net.http", InitHttpClientModule},
 #endif
+#ifdef FEATURE_MODULE_BLE
+    {"bluetooth.ble", InitBleModule},
+#endif
 #ifdef FEATURE_MODULE_BATTERY
     {"battery", InitBatteryModule},
 #endif
@@ -162,13 +178,19 @@ const Module OHOS_MODULES[] = {
 //     {"capability", InitCapabilityModule},
 // #endif
 #ifdef FEATURE_MODULE_WEBSOCKET
-    {"net.webSocket", InitWebsocketClientModule},
+    {"net.webSocket", InitWebSocketClientModule},
 #endif
 #ifdef FEATURE_MODULE_NFC
     {"nfc.cardEmulation", NfcHceInitModule},
+#endif
+#ifdef FEATURE_MODULE_WATCHFACE
+    {"watchface", InitWatchFaceModule},
 #endif
     {"network", InitNetWorkModule},
     {"keyinput", InitKeyInputModule},
+#ifdef ENABLE_MODULE_CALENDAR
+    {"CalendarManager", InitCalendarModule},
+#endif
 };
 } // namespace ACELite
 } // namespace OHOS
index 73f33c2..2a446dc 100644 (file)
 #include "js_app_context.h"
 #include "js_profiler.h"
 #include "jsi/internal/jsi_internal.h"
+#include "NativeAbility.h"
+#include "AppViewIDs.h"
 
 namespace OHOS {
 namespace ACELite {
 void InitRouterModule(JSIValue exports)
 {
     JSI::SetModuleAPI(exports, "replace", RouterModule::Replace);
+    JSI::SetModuleAPI(exports, "replaceToNative", RouterModule::ReplaceToNative);
 }
 
 JSIValue RouterModule::Replace(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)
@@ -50,5 +53,42 @@ JSIValue RouterModule::Replace(const JSIValue thisVal, const JSIValue* args, uin
     jerry_value_t replaceResult = router->Replace(object);
     return AS_JSI_VALUE(replaceResult);
 }
+
+JSIValue RouterModule::ReplaceToNative(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
+{
+    uint16_t sliceId = 0;
+    // router.replaceToNative({sliceId: 1}}
+    JSIValue jsId = JSI::GetNamedProperty(args[0], "sliceId");
+    // router.replaceToNative({sliceName: "APP_LIST"}}
+    JSIValue jsName = JSI::GetNamedProperty(args[0], "sliceName");
+
+    // If sliceId and sliceName are contained, only sliceId is used.
+    if (!JSI::ValueIsUndefined(jsId)) {
+        sliceId = static_cast<uint16_t>(JSI::ValueToNumber(jsId));
+    } else if (!JSI::ValueIsUndefined(jsName)) {
+        char *sliceName = JSI::ValueToString(jsName);
+        if (sliceName == nullptr) {
+            HILOG_ERROR(HILOG_MODULE_ACE, "ReplaceToSlice sliceName is invalid");
+            return JSI::CreateUndefined();
+        }
+
+        if (strcmp(sliceName, "LAUNCHER") == 0) {
+            sliceId = VIEW_MAIN_SAMPLE;
+        } else if (strcmp(sliceName, "APP_LIST") == 0) {
+            sliceId = VIEW_APPLIST;
+        } else {
+            HILOG_ERROR(HILOG_MODULE_ACE, "ReplaceToSlice sliceName mismatch");
+            JSI::ReleaseString(sliceName);
+            return JSI::CreateUndefined();
+        }
+        JSI::ReleaseString(sliceName);
+    } else {
+        HILOG_ERROR(HILOG_MODULE_ACE, "ReplaceToSlice args is nullptr");
+        return JSI::CreateUndefined();
+    }
+
+    OHOS::NativeAbility::GetInstance().ChangeSlice(sliceId);
+    return JSI::CreateUndefined();
+}
 } // namespace ACELite
 } // namespace OHOS
index c4c71f5..003b29f 100644 (file)
@@ -30,6 +30,7 @@ public:
     RouterModule() {}
     ~RouterModule() {}
     static JSIValue Replace(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
+    static JSIValue ReplaceToNative(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
 };
 
 void InitRouterModule(JSIValue exports);
index 2909c8b..9888003 100644 (file)
@@ -20,7 +20,6 @@
 #include "product_adapter.h"\r
 #include <securec.h>\r
 #include "sensor_module.h"\r
-#include "media_log.h"\r
 #include "global.h"\r
 #include "screen.h"\r
 \r
@@ -42,24 +41,38 @@ const uint32_t SensorModule::Z = 80;
 SensorInfo *SensorModule::sensorInfo_ = nullptr;\r
 int32_t SensorModule::sensorCnt_ = 0;\r
 \r
+static void RecordAccelSensorCallback(SensorEvent *event);\r
+static void RecordBarSensorCallback(SensorEvent *event);\r
+static void RecordGyroSensorCallback(SensorEvent *event);\r
+static void RecordHrSensorCallback(SensorEvent *event);\r
+static void RecordObsSensorCallback(SensorEvent *event);\r
+static void RecordScSensorCallback(SensorEvent *event);\r
+\r
+struct SensorDev {\r
+    SensorTypeId sensorTypeId;\r
+    SensorUser user;\r
+    bool subscribed;\r
+    SensorParams sensorParams;\r
+};\r
+\r
 static struct SensorDev g_sensorDev[] = {\r
-    {SENSOR_TYPE_ID_ACCELEROMETER, {"SensorModule", SensorModule::RecordAccelSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
-    {SENSOR_TYPE_ID_BAROMETER, {"SensorModule", SensorModule::RecordBarSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
-    {SENSOR_TYPE_ID_GYROSCOPE, {"SensorModule", SensorModule::RecordCyroSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
-    {SENSOR_TYPE_ID_HEART_RATE, {"SensorModule", SensorModule::RecordHrSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
-    {SENSOR_TYPE_ID_WEAR_DETECTION, {"SensorModule", SensorModule::RecordObsSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
-    {SENSOR_TYPE_ID_PEDOMETER, {"SensorModule", SensorModule::RecordScSensorCallback, nullptr}, SensorModule::UnsubscribeBySensorTypeId, false},\r
+    {SENSOR_TYPE_ID_ACCELEROMETER, {"SensorModule", RecordAccelSensorCallback, nullptr}, false},\r
+    {SENSOR_TYPE_ID_BAROMETER, {"SensorModule", RecordBarSensorCallback, nullptr}, false},\r
+    {SENSOR_TYPE_ID_GYROSCOPE, {"SensorModule", RecordGyroSensorCallback, nullptr}, false},\r
+    {SENSOR_TYPE_ID_HEART_RATE, {"SensorModule", RecordHrSensorCallback, nullptr}, false},\r
+    {SENSOR_TYPE_ID_WEAR_DETECTION, {"SensorModule", RecordObsSensorCallback, nullptr}, false},\r
+    {SENSOR_TYPE_ID_PEDOMETER, {"SensorModule", RecordScSensorCallback, nullptr}, false},\r
 };\r
 \r
-SensorDev *SensorModule::GetSensorIdBySensorDevIndex(SensorTypeId sensorTypeId)\r
+static struct SensorDev *GetSensorIdBySensorDevIndex(SensorTypeId sensorTypeId)\r
 {\r
-    if (sensorCnt_ <= 0 || sensorInfo_ == nullptr) {\r
+    if (SensorModule::sensorCnt_ <= 0 || SensorModule::sensorInfo_ == nullptr) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "must GetAllSensors first");\r
         return nullptr;\r
     }\r
     bool found = false;\r
-    for (int32_t index = 0; index < sensorCnt_; index++) {\r
-        if (sensorInfo_[index].sensorTypeId == sensorTypeId) {\r
+    for (int32_t index = 0; index < SensorModule::sensorCnt_; index++) {\r
+        if (SensorModule::sensorInfo_[index].sensorTypeId == sensorTypeId) {\r
             found = true;\r
             break;\r
         }\r
@@ -116,8 +129,13 @@ void SensorModule::FailCallBack(const JSIValue thisVal, const JSIValue args, int
     JSI::ReleaseValueList(fail, complete, errInfo, errCode, ARGS_END);\r
 }\r
 \r
-void SensorModule::RecordAccelSensorCallback(SensorEvent *event)\r
+void RecordAccelSensorCallbackDispatch(void *arg)\r
 {\r
+    SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
+    if (event == nullptr) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "Sensor event is NULL!");\r
+        return;\r
+    }\r
     if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(AccelData)) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
         return;\r
@@ -126,7 +144,7 @@ void SensorModule::RecordAccelSensorCallback(SensorEvent *event)
         HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not ACCELEROMETER", event->sensorTypeId);\r
         return;\r
     }\r
-    SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
     if (sensorDev == nullptr) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
         return;\r
@@ -137,13 +155,19 @@ void SensorModule::RecordAccelSensorCallback(SensorEvent *event)
     JSI::SetNumberProperty(result, "x", static_cast<double>(accelData->axisX));\r
     JSI::SetNumberProperty(result, "y", static_cast<double>(accelData->axisY));\r
     JSI::SetNumberProperty(result, "z", static_cast<double>(accelData->axisZ));\r
-    SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+    SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
     JSI::ReleaseString(interval);\r
     JSI::ReleaseValueList(result, ARGS_END);\r
 }\r
 \r
-void SensorModule::RecordBarSensorCallback(SensorEvent *event)\r
+void RecordAccelSensorCallback(SensorEvent *event)\r
 {\r
+    JsAsyncWork::DispatchAsyncWork(RecordAccelSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordBarSensorCallbackDispatch(void *arg)\r
+{\r
+    SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
     if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(PressureData)) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
         return;\r
@@ -152,7 +176,7 @@ void SensorModule::RecordBarSensorCallback(SensorEvent *event)
         HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not BAROMETER", event->sensorTypeId);\r
         return;\r
     }\r
-    SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
     if (sensorDev == nullptr) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
         return;\r
@@ -160,12 +184,18 @@ void SensorModule::RecordBarSensorCallback(SensorEvent *event)
     PressureData *pressureData = (PressureData *)event->data;\r
     JSIValue result = JSI::CreateObject();\r
     JSI::SetNumberProperty(result, SensorModule::PRESSURE, static_cast<double>(pressureData->pressure));\r
-    SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+    SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
     JSI::ReleaseValueList(result, ARGS_END);\r
 }\r
 \r
-void SensorModule::RecordCyroSensorCallback(SensorEvent *event)\r
+void RecordBarSensorCallback(SensorEvent *event)\r
 {\r
+    JsAsyncWork::DispatchAsyncWork(RecordBarSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordGyroSensorCallbackDispatch(void *arg)\r
+{\r
+    SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
     if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(GyroData)) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
         return;\r
@@ -174,7 +204,7 @@ void SensorModule::RecordCyroSensorCallback(SensorEvent *event)
         HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not GYROSCOPE", event->sensorTypeId);\r
         return;\r
     }\r
-    SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
     if (sensorDev == nullptr) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
         return;\r
@@ -185,13 +215,19 @@ void SensorModule::RecordCyroSensorCallback(SensorEvent *event)
     JSI::SetNumberProperty(result, "x", static_cast<double>(gyroData->axisX));\r
     JSI::SetNumberProperty(result, "y", static_cast<double>(gyroData->axisY));\r
     JSI::SetNumberProperty(result, "z", static_cast<double>(gyroData->axisZ));\r
-    SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+    SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
     JSI::ReleaseString(interval);\r
     JSI::ReleaseValueList(result, ARGS_END);\r
 }\r
 \r
-void SensorModule::RecordHrSensorCallback(SensorEvent *event)\r
+void RecordGyroSensorCallback(SensorEvent *event)\r
+{\r
+    JsAsyncWork::DispatchAsyncWork(RecordGyroSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordHrSensorCallbackDispatch(void *arg)\r
 {\r
+    SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
     if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(uint32_t)) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
         return;\r
@@ -200,7 +236,7 @@ void SensorModule::RecordHrSensorCallback(SensorEvent *event)
         HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not HEART_RATE", event->sensorTypeId);\r
         return;\r
     }\r
-    SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
     if (sensorDev == nullptr) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
         return;\r
@@ -208,12 +244,18 @@ void SensorModule::RecordHrSensorCallback(SensorEvent *event)
     uint32_t heartRate = *(uint32_t *)event->data;\r
     JSIValue result = JSI::CreateObject();\r
     JSI::SetNumberProperty(result, SensorModule::HEARTRATE, static_cast<double>(heartRate));\r
-    SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+    SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
     JSI::ReleaseValueList(result, ARGS_END);\r
 }\r
 \r
-void SensorModule::RecordObsSensorCallback(SensorEvent *event)\r
+void RecordHrSensorCallback(SensorEvent *event)\r
 {\r
+    JsAsyncWork::DispatchAsyncWork(RecordHrSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordObsSensorCallbackDispatch(void *arg)\r
+{\r
+    SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
     if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(uint8_t)) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
         return;\r
@@ -222,7 +264,7 @@ void SensorModule::RecordObsSensorCallback(SensorEvent *event)
         HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not WEAR_DETECTION", event->sensorTypeId);\r
         return;\r
     }\r
-    SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
     if (sensorDev == nullptr) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
         return;\r
@@ -231,12 +273,22 @@ void SensorModule::RecordObsSensorCallback(SensorEvent *event)
     bool value = isonbody == 0 ? false : true;\r
     JSIValue result = JSI::CreateObject();\r
     JSI::SetNumberProperty(result, SensorModule::ISONBODY, static_cast<double>(value));\r
-    SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+    SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
     JSI::ReleaseValueList(result, ARGS_END);\r
 }\r
 \r
-void SensorModule::RecordScSensorCallback(SensorEvent *event)\r
+void RecordObsSensorCallback(SensorEvent *event)\r
+{\r
+    JsAsyncWork::DispatchAsyncWork(RecordObsSensorCallbackDispatch, event);\r
+}\r
+\r
+void RecordScSensorCallbackDispatch(void *arg)\r
 {\r
+    SensorEvent *event = reinterpret_cast<SensorEvent *>(arg);\r
+    if (event == nullptr) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
+        return;\r
+    }\r
     if (event->data == NULL || event->dataLen == 0 || event->dataLen != sizeof(uint32_t)) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SensorEvent data invalid");\r
         return;\r
@@ -245,7 +297,7 @@ void SensorModule::RecordScSensorCallback(SensorEvent *event)
         HILOG_ERROR(HILOG_MODULE_ACE, "sensorTypeId %d is not PEDOMETER", event->sensorTypeId);\r
         return;\r
     }\r
-    SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex((SensorTypeId)event->sensorTypeId);\r
     if (sensorDev == nullptr) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
         return;\r
@@ -253,14 +305,19 @@ void SensorModule::RecordScSensorCallback(SensorEvent *event)
     uint32_t steps = *(uint32_t *)event->data;\r
     JSIValue result = JSI::CreateObject();\r
     JSI::SetNumberProperty(result, SensorModule::STEPS, static_cast<double>(steps));\r
-    SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
+    SensorModule::SuccessCallBack(sensorDev->sensorParams.thisVal, sensorDev->sensorParams.args, result, false);\r
     JSI::ReleaseValueList(result, ARGS_END);\r
 }\r
 \r
+void RecordScSensorCallback(SensorEvent *event)\r
+{\r
+    JsAsyncWork::DispatchAsyncWork(RecordScSensorCallbackDispatch, event);\r
+}\r
+\r
 void SensorModule::ExecuteGetAllSensors()\r
 {\r
     if (sensorCnt_ != 0 || sensorInfo_ != nullptr) {\r
-        HILOG_INFO(HILOG_MODULE_ACE, "sensorInfo is Got");\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "sensorInfo is Got");\r
         return;\r
     }\r
     int32_t errCode = GetAllSensors(&sensorInfo_, &sensorCnt_);\r
@@ -270,22 +327,33 @@ void SensorModule::ExecuteGetAllSensors()
     }\r
 }\r
 \r
+void SensorModule::ExecuteUnsubscribeAllSensors()\r
+{\r
+    HILOG_INFO(HILOG_MODULE_ACE, "ExecuteUnsubscribeAllSensors");\r
+    for (uint32_t index = 0; index < ARRAY_SIZE(g_sensorDev); index++) {\r
+        if (!g_sensorDev[index].subscribed) {\r
+            continue;\r
+        }\r
+        UnsubscribeBySensorTypeId(g_sensorDev[index].sensorTypeId);\r
+    }\r
+}\r
+\r
 int32_t SensorModule::SubscribeBySensorTypeId(void *data, SensorTypeId sensorTypeId)\r
 {\r
     SensorParams *params = reinterpret_cast<SensorParams *>(data);\r
-    SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);\r
     if (sensorDev == nullptr) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
         return SENSOR_ERROR_UNKNOWN;\r
     }\r
-    int32_t errCode = ActivateSensor(sensorTypeId, &sensorDev->user);\r
+    int32_t errCode = SubscribeSensor(sensorTypeId, &sensorDev->user);\r
     if (errCode != SENSOR_OK) {\r
-        HILOG_ERROR(HILOG_MODULE_ACE, "ActivateSensor failed:%d", errCode);\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
         return SENSOR_ERROR_UNKNOWN;\r
     }\r
-    errCode = SubscribeSensor(sensorTypeId, &sensorDev->user);\r
+    errCode = ActivateSensor(sensorTypeId, &sensorDev->user);\r
     if (errCode != SENSOR_OK) {\r
-        HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "ActivateSensor failed:%d", errCode);\r
         return SENSOR_ERROR_UNKNOWN;\r
     }\r
     sensorDev->sensorParams.args = params->args;\r
@@ -296,9 +364,10 @@ int32_t SensorModule::SubscribeBySensorTypeId(void *data, SensorTypeId sensorTyp
 \r
 int32_t SensorModule::UnsubscribeBySensorTypeId(SensorTypeId sensorTypeId)\r
 {\r
-    SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);\r
-    if (sensorDev == nullptr) {\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex(sensorTypeId);\r
+    if (sensorDev == nullptr || sensorDev->subscribed == false) {\r
         HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
+        return SENSOR_ERROR_UNKNOWN;\r
     }\r
     int32_t errCode = UnsubscribeSensor(sensorTypeId, &sensorDev->user);\r
     if (errCode != SENSOR_OK) {\r
@@ -325,6 +394,8 @@ void SensorModule::ExecuteSubscribeStepCounter(void *data)
     if (errCode != SENSOR_OK) {\r
         FailCallBack(thisVal, args, -1, false);\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+        delete params;\r
+        return;\r
     }\r
     delete params;\r
 }\r
@@ -341,6 +412,8 @@ void SensorModule::ExecuteSubscribeBarometer(void *data)
     if (errCode != SENSOR_OK) {\r
         FailCallBack(thisVal, args, -1, false);\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+        delete params;\r
+        return;\r
     }\r
     delete params;\r
 }\r
@@ -357,6 +430,8 @@ void SensorModule::ExecuteSubscribeHeartRate(void *data)
     if (errCode != SENSOR_OK) {\r
         FailCallBack(thisVal, args, -1, false);\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+        delete params;\r
+        return;\r
     }\r
     delete params;\r
 }\r
@@ -373,6 +448,8 @@ void SensorModule::ExecuteSubscribeOnBodyState(void *data)
     if (errCode != SENSOR_OK) {\r
         FailCallBack(thisVal, args, -1, false);\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+        delete params;\r
+        return;\r
     }\r
     delete params;\r
 }\r
@@ -410,6 +487,8 @@ void SensorModule::ExecuteSubscribeAccelerometer(void *data)
     if (errCode != SENSOR_OK) {\r
         FailCallBack(thisVal, args, -1, false);\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+        delete params;\r
+        return;\r
     }\r
     delete params;\r
 }\r
@@ -426,51 +505,118 @@ void SensorModule::ExecuteSubscribeGyroscope(void *data)
     if (errCode != SENSOR_OK) {\r
         FailCallBack(thisVal, args, -1, false);\r
         HILOG_ERROR(HILOG_MODULE_ACE, "SubscribeSensor failed:%d", errCode);\r
+        delete params;\r
+        return;\r
     }\r
     delete params;\r
 }\r
 \r
-struct SensorParams *SensorModule::GetSensorParamsFromArgs(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)\r
+void SensorModule::ExecuteGetAccelerometerData(void *data)\r
 {\r
-    JSIValue undefValue = JSI::CreateUndefined();\r
-    if ((args == nullptr) || (argsNum == 0) || (JSI::ValueIsUndefined(args[0]))) {\r
-        HILOG_ERROR(HILOG_MODULE_ACE, "Error in obtaining Sensor information parameters");\r
-        return nullptr;\r
+    SensorParams *params = reinterpret_cast<SensorParams *>(data);\r
+    if (params == nullptr) {\r
+        return;\r
+    }\r
+    JSIValue args = params->args;\r
+    JSIValue thisVal = params->thisVal;\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex(SENSOR_TYPE_ID_ACCELEROMETER);\r
+    if (sensorDev == nullptr) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
+        return;\r
+    }\r
+    SensorData *sensorData = new SensorData;\r
+    if (sensorData == nullptr) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "malloc failed!");\r
+        SensorModule::FailCallBack(thisVal, args, SENSOR_ERROR_UNKNOWN, false);\r
+        return;\r
     }\r
+    int32_t ret = GetSensorData(SENSOR_TYPE_ID_ACCELEROMETER, &sensorDev->user, sensorData);\r
+    if (ret != SENSOR_OK) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "Get accelerometer data failed!");\r
+        delete sensorData;\r
+        SensorModule::FailCallBack(thisVal, args, SENSOR_ERROR_UNKNOWN, false);\r
+        return;\r
+    }\r
+    AccelData *accelData = (AccelData *)sensorData->data;\r
+    JSIValue result = JSI::CreateObject();\r
+    for (uint32_t i = 0; i < sensorData->batchCnt; i++) {\r
+        JSI::SetNumberProperty(result, "x", static_cast<double>(accelData[i].axisX));\r
+        JSI::SetNumberProperty(result, "y", static_cast<double>(accelData[i].axisY));\r
+        JSI::SetNumberProperty(result, "z", static_cast<double>(accelData[i].axisZ));\r
+        SensorModule::SuccessCallBack(thisVal, args, result, false);\r
+    }\r
+    JSI::SetNumberProperty(result, "batchCnt", static_cast<double>(sensorData->batchCnt));\r
+    JSI::SetNumberProperty(result, "timestamp", static_cast<double>(sensorData->timestamp));\r
+    SensorModule::SuccessCallBack(thisVal, args, result, false);\r
+    JSI::ReleaseValueList(result, ARGS_END);\r
+    delete sensorData;\r
+}\r
 \r
-    SensorParams *params = new (std::nothrow) SensorParams();\r
+void SensorModule::ExecuteGetGyroscopeData(void *data)\r
+{\r
+    SensorParams *params = reinterpret_cast<SensorParams *>(data);\r
     if (params == nullptr) {\r
-        HILOG_ERROR(HILOG_MODULE_ACE, "Error in new Sensor information parameters");\r
-        return nullptr;\r
+        return;\r
     }\r
-    params->thisVal = JSI::AcquireValue(thisVal);\r
-    if (args != nullptr) {\r
-        params->args = JSI::AcquireValue(args[0]);\r
+    JSIValue args = params->args;\r
+    JSIValue thisVal = params->thisVal;\r
+    struct SensorDev *sensorDev = GetSensorIdBySensorDevIndex(SENSOR_TYPE_ID_GYROSCOPE);\r
+    if (sensorDev == nullptr) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetSensorIdBySensorDevIndex failed");\r
+        return;\r
+    }\r
+    SensorData *sensorData = new SensorData;\r
+    if (sensorData == nullptr) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "malloc failed!");\r
+        SensorModule::FailCallBack(thisVal, args, SENSOR_ERROR_UNKNOWN, false);\r
+        return;\r
+    }\r
+    int32_t ret = GetSensorData(SENSOR_TYPE_ID_GYROSCOPE, &sensorDev->user, sensorData);\r
+    if (ret != 0) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "Get accelerometer data failed!");\r
+        delete sensorData;\r
+        SensorModule::FailCallBack(thisVal, args, SENSOR_ERROR_UNKNOWN, false);\r
+        return;\r
     }\r
-    return params;\r
+    GyroData *gyroData = (GyroData *)sensorData->data;\r
+    JSIValue result = JSI::CreateObject();\r
+    for (uint32_t i = 0; i < sensorData->batchCnt; i++) {\r
+        JSI::SetNumberProperty(result, "x", static_cast<double>(gyroData->axisX));\r
+        JSI::SetNumberProperty(result, "y", static_cast<double>(gyroData->axisY));\r
+        JSI::SetNumberProperty(result, "z", static_cast<double>(gyroData->axisZ));\r
+        SensorModule::SuccessCallBack(thisVal, args, result, false);\r
+    }\r
+    JSI::SetNumberProperty(result, "batchCnt", static_cast<double>(sensorData->batchCnt));\r
+    JSI::SetNumberProperty(result, "timestamp", static_cast<double>(sensorData->timestamp));\r
+    SensorModule::SuccessCallBack(thisVal, args, result, false);\r
+    JSI::ReleaseValueList(result, ARGS_END);\r
+    delete sensorData;\r
 }\r
 \r
-JSIValue SensorModule::ExecuteSyncWork(\r
+JSIValue SensorModule::ExecuteAsyncWork(\r
     const JSIValue thisVal, const JSIValue *args, uint8_t argsNum, AsyncWorkHandler ExecuteFunc)\r
 {\r
     JSIValue undefValue = JSI::CreateUndefined();\r
-    SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
+    if ((args == nullptr) || (argsNum == 0) || (JSI::ValueIsUndefined(args[0]))) {\r
+        HILOG_ERROR(HILOG_MODULE_ACE, "Error in obtaining Sensor information parameters");\r
+        return undefValue;\r
+    }\r
+\r
+    SensorParams *params = new (std::nothrow) SensorParams();\r
     if (params == nullptr) {\r
         return undefValue;\r
     }\r
-    ExecuteFunc(reinterpret_cast<void *>(params));\r
+    params->thisVal = JSI::AcquireValue(thisVal);\r
+    if (args != nullptr) {\r
+        params->args = JSI::AcquireValue(args[0]);\r
+    }\r
+    JsAsyncWork::DispatchAsyncWork(ExecuteFunc, reinterpret_cast<void *>(params));\r
     return undefValue;\r
 }\r
 \r
 JSIValue SensorModule::SubscribeStepCounter(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
 {\r
-    JSIValue undefValue = JSI::CreateUndefined();\r
-    SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
-    if (params == nullptr) {\r
-        return undefValue;\r
-    }\r
-    ExecuteSubscribeStepCounter(reinterpret_cast<void *>(params));\r
-    return undefValue;\r
+    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeStepCounter);\r
 }\r
 \r
 JSIValue SensorModule::UnsubscribeStepCounter(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
@@ -484,13 +630,7 @@ JSIValue SensorModule::UnsubscribeStepCounter(const JSIValue thisVal, const JSIV
 \r
 JSIValue SensorModule::SubscribeBarometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
 {\r
-    JSIValue undefValue = JSI::CreateUndefined();\r
-    SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
-    if (params == nullptr) {\r
-        return undefValue;\r
-    }\r
-    ExecuteSubscribeBarometer(reinterpret_cast<void *>(params));\r
-    return undefValue;\r
+    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeBarometer);\r
 }\r
 \r
 JSIValue SensorModule::UnsubscribeBarometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
@@ -504,13 +644,7 @@ JSIValue SensorModule::UnsubscribeBarometer(const JSIValue thisVal, const JSIVal
 \r
 JSIValue SensorModule::SubscribeHeartRate(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
 {\r
-    JSIValue undefValue = JSI::CreateUndefined();\r
-    SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
-    if (params == nullptr) {\r
-        return undefValue;\r
-    }\r
-    ExecuteSubscribeHeartRate(reinterpret_cast<void *>(params));\r
-    return undefValue;\r
+    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeHeartRate);\r
 }\r
 \r
 JSIValue SensorModule::UnsubscribeHeartRate(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
@@ -524,13 +658,7 @@ JSIValue SensorModule::UnsubscribeHeartRate(const JSIValue thisVal, const JSIVal
 \r
 JSIValue SensorModule::SubscribeOnBodyState(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
 {\r
-    JSIValue undefValue = JSI::CreateUndefined();\r
-    SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
-    if (params == nullptr) {\r
-        return undefValue;\r
-    }\r
-    ExecuteSubscribeOnBodyState(reinterpret_cast<void *>(params));\r
-    return undefValue;\r
+    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeOnBodyState);\r
 }\r
 \r
 JSIValue SensorModule::UnsubscribeOnBodyState(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
@@ -544,18 +672,12 @@ JSIValue SensorModule::UnsubscribeOnBodyState(const JSIValue thisVal, const JSIV
 \r
 JSIValue SensorModule::GetOnBodyState(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
 {\r
-    return ExecuteSyncWork(thisVal, args, argsNum, ExecuteGetOnBodyState);\r
+    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGetOnBodyState);\r
 }\r
 \r
 JSIValue SensorModule::SubscribeAccelerometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
 {\r
-    JSIValue undefValue = JSI::CreateUndefined();\r
-    SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
-    if (params == nullptr) {\r
-        return undefValue;\r
-    }\r
-    ExecuteSubscribeAccelerometer(reinterpret_cast<void *>(params));\r
-    return undefValue;\r
+    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeAccelerometer);\r
 }\r
 \r
 JSIValue SensorModule::UnsubscribeAccelerometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
@@ -569,13 +691,7 @@ JSIValue SensorModule::UnsubscribeAccelerometer(const JSIValue thisVal, const JS
 \r
 JSIValue SensorModule::SubscribeGyroscope(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
 {\r
-    JSIValue undefValue = JSI::CreateUndefined();\r
-    SensorParams *params = GetSensorParamsFromArgs(thisVal, args, argsNum);\r
-    if (params == nullptr) {\r
-        return undefValue;\r
-    }\r
-    ExecuteSubscribeGyroscope(reinterpret_cast<void *>(params));\r
-    return undefValue;\r
+    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteSubscribeGyroscope);\r
 }\r
 \r
 JSIValue SensorModule::UnsubscribeGyroscope(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
@@ -587,18 +703,21 @@ JSIValue SensorModule::UnsubscribeGyroscope(const JSIValue thisVal, const JSIVal
     return JSI::CreateUndefined();\r
 }\r
 \r
-void SensorModule::OnDestroy()\r
+JSIValue SensorModule::GetAccelerometerData(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
 {\r
-    for (uint32_t index = 0; index < ARRAY_SIZE(g_sensorDev); index++) {\r
-        SensorTypeId sensorTypeId = g_sensorDev[index].sensorTypeId;\r
-        if (!g_sensorDev[index].subscribed) {\r
-            continue;\r
-        }\r
-        int32_t errCode = g_sensorDev[index].unSubscribeSensor(sensorTypeId);\r
-        if (errCode != SENSOR_OK) {\r
-            HILOG_INFO(HILOG_MODULE_ACE, "Unsubscribe :%d failed:%d", sensorTypeId, errCode);\r
-        }\r
-    }\r
+    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGetAccelerometerData);\r
+}\r
+\r
+JSIValue SensorModule::GetGyroscopeData(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)\r
+{\r
+    return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteGetGyroscopeData);\r
+}\r
+\r
+void SensorModule::OnTerminate()\r
+{\r
+    ExecuteUnsubscribeAllSensors();\r
+    sensorInfo_ = nullptr;\r
+    sensorCnt_ = 0;\r
 }\r
 \r
 }  // namespace ACELite\r
index 1333e7b..62bc37b 100644 (file)
@@ -35,16 +35,6 @@ struct SensorParams {
     JSIValue thisVal = JSI::CreateUndefined();\r
 };\r
 \r
-typedef int32_t (*UnsubscribeBySensorTypeId)(SensorTypeId sensorTypeId);\r
-\r
-struct SensorDev {\r
-    SensorTypeId sensorTypeId;\r
-    SensorUser user;\r
-    UnsubscribeBySensorTypeId unSubscribeSensor;\r
-    bool subscribed;\r
-    SensorParams sensorParams;\r
-};\r
-\r
 class SensorModule final : public MemoryHeap {\r
 public:\r
     ACE_DISALLOW_COPY_AND_MOVE(SensorModule);\r
@@ -74,27 +64,21 @@ public:
     static JSIValue UnsubscribeAccelerometer(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
     static JSIValue SubscribeGyroscope(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
     static JSIValue UnsubscribeGyroscope(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
+    static JSIValue GetAccelerometerData(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
+    static JSIValue GetGyroscopeData(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);\r
     static void SuccessCallBack(const JSIValue thisVal, const JSIValue args, JSIValue jsiValue, bool flag);\r
-\r
-    static void RecordAccelSensorCallback(SensorEvent *event);\r
-    static void RecordBarSensorCallback(SensorEvent *event);\r
-    static void RecordCyroSensorCallback(SensorEvent *event);\r
-    static void RecordHrSensorCallback(SensorEvent *event);\r
-    static void RecordObsSensorCallback(SensorEvent *event);\r
-    static void RecordScSensorCallback(SensorEvent *event);\r
-\r
     static void ExecuteGetAllSensors();\r
+    static void ExecuteUnsubscribeAllSensors();\r
     static int32_t SubscribeBySensorTypeId(void *data, SensorTypeId sensorTypeId);\r
     static int32_t UnsubscribeBySensorTypeId(SensorTypeId sensorTypeId);\r
+    static void OnTerminate();\r
 \r
-    static void OnDestroy();\r
+    static SensorInfo *sensorInfo_;\r
+    static int32_t sensorCnt_;\r
 \r
 private:\r
-    static JSIValue ExecuteSyncWork(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum, AsyncWorkHandler ExecuteFunc);\r
-    static SensorDev *GetSensorIdBySensorDevIndex(SensorTypeId sensorTypeId);\r
-    static SensorParams *GetSensorParamsFromArgs(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);\r
+    static JSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum, AsyncWorkHandler ExecuteFunc);\r
     static void FailCallBack(const JSIValue thisVal, const JSIValue args, int ret, bool flag);\r
-\r
     static void ExecuteSubscribeStepCounter(void *data);\r
     static void ExecuteSubscribeBarometer(void *data);\r
     static void ExecuteSubscribeHeartRate(void *data);\r
@@ -102,9 +86,8 @@ private:
     static void ExecuteGetOnBodyState(void *data);\r
     static void ExecuteSubscribeGyroscope(void *data);\r
     static void ExecuteSubscribeAccelerometer(void *data);\r
-    static SensorInfo *sensorInfo_;\r
-    static int32_t sensorCnt_;\r
-\r
+    static void ExecuteGetAccelerometerData(void *data);\r
+    static void ExecuteGetGyroscopeData(void *data);\r
 };\r
 \r
 void InitSensorModule(JSIValue exports)\r
@@ -122,7 +105,10 @@ void InitSensorModule(JSIValue exports)
     JSI::SetModuleAPI(exports, "unsubscribeAccelerometer", SensorModule::UnsubscribeAccelerometer);\r
     JSI::SetModuleAPI(exports, "subscribeGyroscope", SensorModule::SubscribeGyroscope);\r
     JSI::SetModuleAPI(exports, "unsubscribeGyroscope", SensorModule::UnsubscribeGyroscope);\r
-    JSI::SetOnDestroy(exports, SensorModule::OnDestroy);\r
+    JSI::SetModuleAPI(exports, "getAccelerometerData", SensorModule::GetAccelerometerData);\r
+    JSI::SetModuleAPI(exports, "getGyroscopeData", SensorModule::GetGyroscopeData);\r
+    JSI::SetOnTerminate(exports, SensorModule::OnTerminate);\r
+    JSI::SetOnDestroy(exports, SensorModule::OnTerminate);\r
     SensorModule::ExecuteGetAllSensors();\r
 }\r
 \r
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/watchface/watchface_module.cpp b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/watchface/watchface_module.cpp
new file mode 100644 (file)
index 0000000..0da6cc1
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: watchface JS intarface
+ * Author: Software Group
+ * Create: 2025-09-5
+ */
+ 
+#include <string>
+#include "jsi.h"
+#include "securec.h"
+#include "ace_log.h"
+#include "js_async_work.h"
+#include "watchface_module.h"
+ 
+namespace OHOS {
+namespace ACELite {
+
+bool WatchfaceModule::isListenerRunning_ = false;
+bool WatchfaceModule::isTerminate_ = false;
+
+constexpr static uint32_t STEP_SIZE = 512;
+constexpr static uint32_t DELAY_TIME = 500;
+
+// 下载状态打桩变量
+static uint32_t totalSize = 16 * 1024;
+static uint32_t receivedSize = 0;
+
+bool WatchfaceModule::GetDialInfo(uint32_t uuid, WatchDialInfo& watch, JSIValue& dialInfo)
+{
+    bool isGet = ::GetWatchFaceInfo(uuid, &watch);
+    if (isGet) {
+        JSI::SetNumberProperty(dialInfo, "uuid", watch.uuid);
+        JSI::SetNumberProperty(dialInfo, "install_state", watch.install_state);
+        JSI::SetNumberProperty(dialInfo, "is_current_watch", watch.is_current_watch);
+        JSI::SetStringProperty(dialInfo, "watch_protocol_version", reinterpret_cast<char*>(watch.watch_protocol_version));
+        JSI::SetStringProperty(dialInfo, "watch_version", reinterpret_cast<char*>(watch.watch_version));
+        return true;
+    } else {
+        return false;
+    }
+}
+ 
+JSIValue WatchfaceModule::SetWatchFace(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
+{
+    if (argsSize != ARGC_TWO) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid parameter!");
+        return JSI::CreateUndefined();
+    }
+
+    WATCHFACE_ERRCODE ret = WATCHFACE_SUCCESS;
+    JSIValue dialInfo = JSI::CreateObject();
+    JSIValue callback = JSI::AcquireValue(args[1]);
+    bool isGet = false;
+
+    uint32_t uuid = JSI::ValueToNumber(args[0]);
+    bool installed = SetCurrentWatchFace(uuid);
+    if (!installed) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "SetCurrentWatchFace failed!");
+        ret = WATCHFACE_INSTALL_ERROR;
+        goto exit;
+    }
+
+    WatchDialInfo watch;
+    memset_s(&watch, sizeof(WatchDialInfo), 0, sizeof(WatchDialInfo));
+    isGet = GetDialInfo(uuid, watch, dialInfo);
+    if (!isGet) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetDialInfo failed!");
+        ret = WATCHFACE_GETINFO_ERROR;
+    }
+
+exit:
+    JSIValue err = JSI::CreateNumber(ret);
+    JSIValue argv[ARGC_TWO] = {err, dialInfo};
+    JSI::CallFunction(callback, thisVal, argv, ARGC_TWO);
+    JSI::ReleaseValueList(err, callback, dialInfo);
+    return JSI::CreateUndefined();
+}
+ 
+JSIValue WatchfaceModule::GetWatchFaceInfo(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
+{
+    if (argsSize != ARGC_TWO) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid parameter!");
+        return JSI::CreateUndefined();
+    }
+
+    WatchDialInfo watch;
+    memset_s(&watch, sizeof(WatchDialInfo), 0, sizeof(WatchDialInfo));
+    WATCHFACE_ERRCODE ret = WATCHFACE_SUCCESS;
+
+    uint32_t uuid = JSI::ValueToNumber(args[0]);
+    JSIValue dialInfo = JSI::CreateObject();
+    bool isGet = GetDialInfo(uuid, watch, dialInfo);
+    if (!isGet) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "GetDialInfo failed!");
+        ret = WATCHFACE_GETINFO_ERROR;
+    }
+
+    JSIValue err = JSI::CreateNumber(ret);
+    JSIValue callback = JSI::AcquireValue(args[1]);
+    JSIValue argv[ARGC_TWO] = {err, dialInfo};
+    JSI::CallFunction(callback, thisVal, argv, ARGC_TWO);
+    JSI::ReleaseValueList(err, callback, dialInfo);
+
+    return JSI::CreateUndefined();
+}
+
+// 下载状态打桩函数
+static int GetDownloadStatus(DownloadStatus& status)
+{
+    status.receivedSize = receivedSize;
+    status.totalSize = totalSize;
+    receivedSize += STEP_SIZE;
+    if (receivedSize > totalSize) {
+        receivedSize = totalSize;
+    }
+    status.uuid = 1;
+    
+    osal_msleep(DELAY_TIME);
+    return 0;
+}
+
+void WatchfaceModule::FailCallback(void *data)
+{
+    if (data == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid null argument in FailCallback");
+        isListenerRunning_ = false;
+        return;
+    }
+
+    WatchfaceParams *params = static_cast<WatchfaceParams *>(data);
+
+    JSIValue installInfo = JSI::CreateObject();
+    JSIValue err = JSI::CreateNumber(WATCHFACE_GETMSG_ERROR);
+    JSIValue callback = params->callback;
+    JSIValue thisVal = params->thisVal;
+
+    JSIValue argv[ARGC_TWO] = {err, installInfo};
+
+    if (!isTerminate_) {
+        JSI::CallFunction(callback, thisVal, argv, ARGC_TWO);
+    }
+    JSI::ReleaseValueList(callback, thisVal);
+    JSI::ReleaseValueList(err, installInfo);
+    delete params;
+    isListenerRunning_ = false;
+    return;
+}
+
+void WatchfaceModule::SuccessCallback(void *data)
+{
+    if (data == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid null argument in SuccessCallback");
+        return;
+    }
+
+    WatchfaceParams *params = static_cast<WatchfaceParams *>(data);
+    JSIValue callback = params->callback;
+    JSIValue thisVal = params->thisVal;
+
+    JSIValue installInfo = JSI::CreateObject();
+    JSIValue err = JSI::CreateNumber(WATCHFACE_SUCCESS);
+    JSI::SetNumberProperty(installInfo, "process", params->process);
+    JSI::SetNumberProperty(installInfo, "install_state", params->installState);
+
+    JSIValue argv[ARGC_TWO] = {err, installInfo};
+
+    if (!isTerminate_) {
+        JSI::CallFunction(callback, thisVal, argv, ARGC_TWO);
+    }
+
+    JSI::ReleaseValueList(err, installInfo);
+    if (params->installState || isTerminate_) {
+        JSI::ReleaseValueList(callback, thisVal);
+        delete params;
+        isListenerRunning_ = false;
+    }
+    return;
+}
+
+static void WatchFaceDownload(void *argument)
+{
+    if (argument == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid null argument in DownloadListener");
+        return;
+    }
+    WatchfaceParams *params = static_cast<WatchfaceParams *>(argument);
+
+    do {
+        DownloadStatus status;
+        int ret = GetDownloadStatus(status);
+        if (ret != 0) {
+            HILOG_ERROR(HILOG_MODULE_ACE, "GetDownloadStatus failed");
+            JsAsyncWork::DispatchAsyncWork(WatchfaceModule::FailCallback, static_cast<void *>(params));
+            break;
+        }
+
+        WatchDialInfo watch;
+        if (status.receivedSize == status.totalSize) {
+            bool isGet = ::GetWatchFaceInfo(status.uuid, &watch);
+            if (!isGet) {
+                HILOG_ERROR(HILOG_MODULE_ACE, "GetWatchFaceInfo failed");
+                JsAsyncWork::DispatchAsyncWork(WatchfaceModule::FailCallback, static_cast<void *>(params));
+                break;
+            }
+            params->installState = watch.install_state;
+        }
+
+        params->process = static_cast<double>(status.receivedSize) / status.totalSize;
+
+        JsAsyncWork::DispatchAsyncWork(WatchfaceModule::SuccessCallback, static_cast<void *>(params));
+    } while(!params->installState && !WatchfaceModule::isTerminate_);
+}
+
+JSIValue WatchfaceModule::SetDownloadListener(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
+{
+    if (argsSize != ARGC_ONE) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Invalid parameter!");
+        return JSI::CreateUndefined();
+    }
+
+    if (isListenerRunning_) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "another DownloadListener is running!");
+        return JSI::CreateUndefined();
+    }
+
+    WatchfaceParams *params = new WatchfaceParams{};
+    if (params == nullptr) {
+        HILOG_ERROR(HILOG_MODULE_ACE, "Failed to allocate memory for params!");
+        return JSI::CreateUndefined();
+    }
+
+    params->thisVal = JSI::AcquireValue(thisVal);
+    params->callback = JSI::AcquireValue(args[0]);
+
+    osThreadId_t id;
+    osThreadAttr_t attr;
+    attr.name = "WatchFaceDownload";
+    attr.attr_bits = osThreadDetached;
+    attr.cb_mem = NULL;
+    attr.cb_size = 0U;
+    attr.stack_mem = NULL;
+    attr.stack_size = 0x1000;
+    attr.priority = osPriorityNormal;
+
+    isTerminate_ = false;
+    isListenerRunning_ = true;
+    receivedSize = 0; // 打桩数据初始化
+    id = osThreadNew((osThreadFunc_t)WatchFaceDownload, (void *)params, &attr);
+
+    return JSI::CreateUndefined();
+}
+
+JSIValue WatchfaceModule::Destroy(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize)
+{
+    isTerminate_ = true;
+    return JSI::CreateUndefined();
+}
+
+void InitWatchFaceModule(JSIValue exports)
+{
+    JSI::SetModuleAPI(exports, "setWatchFace", WatchfaceModule::SetWatchFace);
+    JSI::SetModuleAPI(exports, "getWatchFaceInfo", WatchfaceModule::GetWatchFaceInfo);
+    JSI::SetModuleAPI(exports, "setDownloadListener", WatchfaceModule::SetDownloadListener);
+    JSI::SetModuleAPI(exports, "destroy", WatchfaceModule::Destroy);
+}
+}  // namespace ACELite
+}  // namespace OHOS
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/watchface/watchface_module.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/watchface/watchface_module.h
new file mode 100644 (file)
index 0000000..24bfac3
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: watchface JS intarface
+ * Author: Software Group
+ * Create: 2025-09-5
+ */
+ 
+#ifndef WATCHFACE_MODULE_H
+#define WATCHFACE_MODULE_H
+ 
+#include <stdint.h>
+#include <map>
+#include "jsi.h"
+#include "WatchInterface.h"
+ 
+namespace OHOS {
+namespace ACELite {
+
+typedef enum {
+    WATCHFACE_SUCCESS          =  0,
+    WATCHFACE_PARAM_ERROR      =  401,
+    WATCHFACE_INSTALL_ERROR    =  2400001,
+    WATCHFACE_GETINFO_ERROR    =  2400002,
+    WATCHFACE_GETMSG_ERROR     =  2400003,
+} WATCHFACE_ERRCODE;
+
+typedef watch_dial_info WatchDialInfo;
+
+struct DownloadStatus {
+    uint32_t receivedSize;
+    uint32_t totalSize;
+    uint32_t uuid;
+};
+
+struct WatchfaceParams{
+    JSIValue thisVal;
+    JSIValue callback;
+    double process;
+    uint8_t installState;
+};
+
+class WatchfaceModule final : public MemoryHeap {
+public:
+    WatchfaceModule() = default;
+    ~WatchfaceModule() = default;
+    static JSIValue SetWatchFace(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);
+    static JSIValue GetWatchFaceInfo(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);
+    static JSIValue SetDownloadListener(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);
+    static JSIValue Destroy(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);
+    static void FailCallback(void *data);
+    static void SuccessCallback(void *data);
+    static bool isTerminate_;
+private:
+    static bool GetDialInfo(uint32_t uuid, WatchDialInfo& watch, JSIValue& dialInfo);
+    static bool isListenerRunning_;
+};
+void InitWatchFaceModule(JSIValue exports);
+ 
+}  // namespace ACELite
+}  // namespace OHOS
+ 
+#endif  // WATCHFACE_MODULE_H
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_common.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_common.h
new file mode 100644 (file)
index 0000000..9fd3cdc
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: websocket common definition
+ * Author: Software Group
+ * Create: 2025-11-19
+ */
+
+#ifndef WEBSOCKET_COMMON_H
+#define WEBSOCKET_COMMON_H
+
+
+namespace OHOS {
+namespace ACELite {
+
+#define net_malloc ace_malloc
+#define net_free ace_free
+
+enum WsEventId {
+    WS_EVENT_OPEN = 0,
+    WS_EVENT_MESSAGE = 1,
+    WS_EVENT_CLOSE = 2,
+    WS_EVENT_ERROR = 3,
+    WS_EVENT_MAX = 4
+};
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif
\ No newline at end of file
index a657471..7cb1201 100644 (file)
@@ -12,6 +12,8 @@
 #include "jsi.h"\r
 #include <map>\r
 #include <cstring>\r
+#include "websocket_common.h"\r
+#include "websocket_module_callback.h"\r
 \r
 namespace OHOS {\r
 namespace ACELite {\r
@@ -21,21 +23,27 @@ struct EventCallback {
     JSIValue context;\r
 };\r
 \r
-class WebsocketModule final : public MemoryHeap {\r
+class WebSocketModule final : public MemoryHeap {\r
 public:\r
-    WebsocketModule() = default;\r
-    ~WebsocketModule() = default;\r
-    static JSIValue CreateWebsocket(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    WebSocketModule() = default;\r
+    ~WebSocketModule() = default;\r
+    static JSIValue CreateWebSocket(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
     static JSIValue Connect(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
     static JSIValue Send(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue SendInit(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue SendUpdate(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue SendFinish(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
     static JSIValue Close(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+    static JSIValue Destroy(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
     static JSIValue On(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
     static JSIValue Off(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
     static std::map<std::string, EventCallback *> eventCallbacks;\r
-    static void Destroy();\r
     static void OnTerminate();\r
+private:\r
+    static WsEventId GetEventId(const char *event);\r
+    static char *HeaderJsonToString(char* headerJson);\r
 };\r
-void InitWebsocketModule(JSIValue exports);\r
+void InitWebSocketClientModule(JSIValue exports);\r
 \r
 }  // namespace ACELite\r
 }  // namespace OHOS\r
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_module_callback.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_module_callback.h
new file mode 100644 (file)
index 0000000..7d48719
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: websocket callback interfaces
+ * Author: Software Group
+ * Create: 2025-09-1
+ */
+
+#ifndef WEBSOCKET_MODULE_CALLBACK_H
+#define WEBSOCKET_MODULE_CALLBACK_H
+
+#include "jsi.h"
+#include "net_websocket_type.h"
+#include "http_errcode.h"
+#include "websocket_common.h"
+
+namespace OHOS {
+namespace ACELite {
+
+struct WsResult {
+    int resCode;
+    char* reason;
+    char* data;
+    int length;
+    bool isBinary;
+    int clientId;
+    WsEventId eventId;
+};
+
+class WsCallback final : public MemoryHeap {
+public:
+    WsCallback() = default;
+    ~WsCallback() = default;
+
+    static void DispatchStateInfo(int resCode, const char* reason, WsEventId eventId, int clientId);
+    static void DispatchMessage(const char *data, size_t length, bool isBinary, int clientId);
+
+private:
+    static void SendStateInfo(void *param);
+    static void SendMessage(void *param);
+
+private:
+};
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_module_client.h b/code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/websocket/websocket_module_client.h
new file mode 100644 (file)
index 0000000..4dbbfca
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) CompanyNameMagicTag. 2025-2025. All rights reserved.
+ * Description: websocket client interfaces
+ * Author: Software Group
+ * Create: 2025-10-20
+ */
+
+#ifndef WEBSOCKET_CLIENT_H
+#define WEBSOCKET_CLIENT_H
+
+#include "jsi.h"
+#include "net_websocket.h"
+#include "net_websocket_type.h"
+#include "websocket_common.h"
+
+namespace OHOS {
+namespace ACELite {
+
+enum WsDataType {
+    DATA_TYPE_STRING = 0,
+    DATA_TYPE_OBJECT = 1,
+    DATA_TYPE_ARRAY_BUFFER = 2
+};
+
+struct WsHandler {
+    JSIValue send;
+    JSIValue sendInit;
+    JSIValue sendUpdate;
+    JSIValue sendFinish;
+    JSIValue connect;
+    JSIValue close;
+    JSIValue destroy;
+    JSIValue on;
+    JSIValue off;
+};
+
+class WsModuleClient final : public MemoryHeap {
+public:
+    WsModuleClient();
+    ~WsModuleClient();
+
+    int GetClientId(void) const
+    {
+        return clientId_;
+    }
+
+    int Connect(const char *url, const char *option);
+    int Send(const char *data, size_t length, WsDataType dataType);
+    int SendInit(uint32_t size);
+    int SendUpdate(const char *data, size_t length);
+    int SendFinish(const char *data, size_t length, WsDataType dataType);
+    int Close(void);
+    static int GetErrorCode(int8_t errorCode);
+
+    WsHandler handler_;
+    JSIValue context_;
+    JSIValue WsEvents_[WS_EVENT_MAX];
+private:
+    void ReleaseJSIValue(JSIValue value)
+    {
+        if (!JSI::ValueIsUndefined(value)) {
+            JSI::ReleaseValue(value);
+        }
+    }
+
+    int SendBinary(const char *data, size_t bufferSize);
+
+    static const uint32_t WS_MAX_DATA_LENGTH  = 20 * 1024;
+    static const uint32_t WS_MAX_SEND_LENGTH  = 100 * 1024;
+    int clientId_ = -1;
+    char *msgBuffer_ = nullptr;
+    uint32_t bufferSize_ = 0;
+    uint32_t dataSize_ = 0;
+
+};
+
+}  // namespace ACELite
+}  // namespace OHOS
+
+#endif  // WEBSOCKET_CLIENT_H
\ No newline at end of file
index fa561a6..fcd9e64 100644 (file)
@@ -20,6 +20,8 @@
 
 namespace OHOS {
 namespace ACELite {
+int8_t GetStateMachineInfo();
+
 class Router final : public MemoryHeap {
 public:
     ACE_DISALLOW_COPY_AND_MOVE(Router);
index 0f8144c..0767666 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/appexecfwk/appexecfwk_lite/brandy-auto-ota-cli/libbms.a and b/code/sdk/open_source/openharmony/foundation/appexecfwk/appexecfwk_lite/brandy-auto-ota-cli/libbms.a differ
index 58dcccd..31603c9 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/appexecfwk/appexecfwk_lite/brandy-auto-ota-ser/libbms.a and b/code/sdk/open_source/openharmony/foundation/appexecfwk/appexecfwk_lite/brandy-auto-ota-ser/libbms.a differ
index f262ad8..599f480 100644 (file)
Binary files a/code/sdk/open_source/openharmony/foundation/appexecfwk/appexecfwk_lite/brandy-native-js/libbms.a and b/code/sdk/open_source/openharmony/foundation/appexecfwk/appexecfwk_lite/brandy-native-js/libbms.a differ
index 1389938..f13cf2d 100644 (file)
@@ -46,14 +46,39 @@ public:
     static JSIValue Stop(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
 \r
     /**\r
-     handle exception\r
+     * Start\r
+     * Start XiaoduVoice when args[0] == "XiaoduVoice", no input param\r
+     * Start AudioCaptruer otherwise\r
+     * @inputparam args, include properties buffersize, format, etc\r
      */\r
-    static void ExceptionStop(void);\r
+    static JSIValue start(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+\r
+    /**\r
+     * Stop\r
+     */\r
+    static JSIValue stop(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+\r
+    /**\r
+     * ListenerOn\r
+     * @inputparam args, include properties success, fail\r
+     */\r
+    static JSIValue ListenerOn(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
 \r
     /**\r
      * Cancel\r
      */\r
     static JSIValue Cancel(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+       /**\r
+     * ListenerOff\r
+     */\r
+    static JSIValue ListenerOff(const JSIValue thisVal, const JSIValue *args, uint8_t argsSize);\r
+\r
+    /**\r
+     handle exception\r
+     */\r
+    static void ExceptionStop(void);\r
+    static void OnDestroy(void);\r
+    static void OnTerminate(void);\r
 };\r
 \r
 void InitAudioCapturerModule(JSIValue exports);\r
index 5db2684..cb68767 100644 (file)
@@ -122,8 +122,14 @@ struct PlayerDebugInfo {
 class PlayerCallback {\r
 public:\r
     enum PlayerInfoType : int32_t {\r
-        /** Pushed the first video frame for rendering */\r
-        PLAYER_INFO_RENDER_START = 0,\r
+        PLAYER_INFO_PLAY_START = 0,\r
+        PLAYER_INFO_PLAYING,\r
+        PLAYER_INFO_PLAY_END,\r
+        PLAYER_INFO_SEEK_START,\r
+        PLAYER_INFO_SEEK_END,\r
+        PLAYER_INFO_STOPPED,\r
+        PLAYER_INFO_PAUSED,\r
+        PLAYER_INFO_BUTT,\r
     };\r
 \r
     enum PlayerErrorType : int32_t {\r
@@ -131,13 +137,13 @@ public:
     };\r
 \r
     enum PlayerErrorCode : int32_t {\r
-        PLAYER_ERROR_CODE_VID_PLAY_FAIL = 0x0, /* The video fails to be played. */\r
+        PLAYER_ERROR_CODE_VID_PLAY_FAIL = 0, /* The video fails to be played. */\r
         PLAYER_ERROR_CODE_AUD_PLAY_FAIL,       /* The audio fails to be played. */\r
         PLAYER_ERROR_CODE_DEMUX_FAIL,          /* The file fails to be played. */\r
         PLAYER_ERROR_CODE_TIMEOUT,             /* Operation timeout. For example, reading data timeout. */\r
         PLAYER_ERROR_CODE_NOT_SUPPORT,         /* The file format is not supportted. */\r
-        PLAYER_ERROR_CODE_UNKNOW,              /* Unknown error. */\r
         PLAYER_ERROR_CODE_ILLEGAL_STATEACTION, /* illegal action at cur state. */\r
+        PLAYER_ERROR_CODE_UNKNOWN,              /* Unknown error. */\r
         PLAYER_ERROR_CODE_BUTT,\r
     };\r
 \r
@@ -170,7 +176,7 @@ public:
     * @since 1.0\r
     * @version 1.0\r
     */\r
-    virtual void OnInfo(int type, int extra) = 0;\r
+    virtual void OnInfo(int32_t type, int32_t extra) = 0;\r
 \r
     /**\r
     * @brief Called when the rewind is complete.\r
index 0d64dd1..09f1bd4 100644 (file)
Binary files a/code/sdk/open_source/openharmony/third_party/jerryscript/brandy-auto-ota-cli/libjerryscript.a and b/code/sdk/open_source/openharmony/third_party/jerryscript/brandy-auto-ota-cli/libjerryscript.a differ
index 96543a8..651a82f 100644 (file)
Binary files a/code/sdk/open_source/openharmony/third_party/jerryscript/brandy-auto-ota-ser/libjerryscript.a and b/code/sdk/open_source/openharmony/third_party/jerryscript/brandy-auto-ota-ser/libjerryscript.a differ
index bafd4fc..82e598e 100644 (file)
Binary files a/code/sdk/open_source/openharmony/third_party/jerryscript/brandy-native-js/libjerryscript.a and b/code/sdk/open_source/openharmony/third_party/jerryscript/brandy-native-js/libjerryscript.a differ
index 59ffd4c..2f2a74a 100644 (file)
Binary files a/code/sdk/open_source/openharmony/third_party/jerryscript/brandy-xts/libjerryscript.a and b/code/sdk/open_source/openharmony/third_party/jerryscript/brandy-xts/libjerryscript.a differ
index e083e5e..3a0e8b4 100644 (file)
@@ -5,16 +5,17 @@ cmake_minimum_required(VERSION 3.7)
 # @brief    cmake file
 # Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved.
 #===============================================================================
+if("BRANDY_PRODUCT_EVB4" IN_LIST DEFINES OR "BRANDY_PRODUCT_EVB" IN_LIST DEFINES)
 set(COMPONENT_NAME "lwip")
+else()
+set(COMPONENT_NAME "ohos_lwip")
+endif()
 
 set(CMAKE_LWIP_SOURCE_DIR
     ${CMAKE_CURRENT_SOURCE_DIR}/lwip_v2.1.3)
 set(LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lwip_v2.1.3)
 
-if("liteos_207_1_0" IN_LIST TARGET_COMPONENT)
-    set(CMAKE_LWIP_ADAPTER_DIR
-        ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/liteos)
-elseif("liteos_207_0_0" IN_LIST TARGET_COMPONENT)
+if("__LITEOS__" IN_LIST DEFINES)
     set(CMAKE_LWIP_ADAPTER_DIR
         ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/liteos)
 elseif("freertos" IN_LIST TARGET_COMPONENT)
@@ -22,40 +23,6 @@ elseif("freertos" IN_LIST TARGET_COMPONENT)
         ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/freertos)     
 endif()
 
-# PPP
-set(lwipppp_SRCS
-    ${LWIP_DIR}/src/netif/ppp/auth.c
-    ${LWIP_DIR}/src/netif/ppp/ccp.c
-    ${LWIP_DIR}/src/netif/ppp/chap-md5.c
-    ${LWIP_DIR}/src/netif/ppp/chap_ms.c
-    ${LWIP_DIR}/src/netif/ppp/chap-new.c
-    ${LWIP_DIR}/src/netif/ppp/demand.c
-    ${LWIP_DIR}/src/netif/ppp/eap.c
-    ${LWIP_DIR}/src/netif/ppp/ecp.c
-    ${LWIP_DIR}/src/netif/ppp/eui64.c
-    ${LWIP_DIR}/src/netif/ppp/fsm.c
-    ${LWIP_DIR}/src/netif/ppp/ipcp.c
-    ${LWIP_DIR}/src/netif/ppp/ipv6cp.c
-    ${LWIP_DIR}/src/netif/ppp/lcp.c
-    ${LWIP_DIR}/src/netif/ppp/magic.c
-    ${LWIP_DIR}/src/netif/ppp/mppe.c
-    ${LWIP_DIR}/src/netif/ppp/multilink.c
-    ${LWIP_DIR}/src/netif/ppp/ppp.c
-    ${LWIP_DIR}/src/netif/ppp/pppapi.c
-    ${LWIP_DIR}/src/netif/ppp/pppcrypt.c
-    ${LWIP_DIR}/src/netif/ppp/pppoe.c
-    ${LWIP_DIR}/src/netif/ppp/pppol2tp.c
-    ${LWIP_DIR}/src/netif/ppp/pppos.c
-    ${LWIP_DIR}/src/netif/ppp/upap.c
-    ${LWIP_DIR}/src/netif/ppp/utils.c
-    ${LWIP_DIR}/src/netif/ppp/vj.c
-    ${LWIP_DIR}/src/netif/ppp/polarssl/arc4.c
-    ${LWIP_DIR}/src/netif/ppp/polarssl/des.c
-    ${LWIP_DIR}/src/netif/ppp/polarssl/md4.c
-    ${LWIP_DIR}/src/netif/ppp/polarssl/md5.c
-    ${LWIP_DIR}/src/netif/ppp/polarssl/sha1.c
-)
-
 set(SOURCES
     ${CMAKE_LWIP_SOURCE_DIR}/src/core/tcp_out.c
     ${CMAKE_LWIP_SOURCE_DIR}/src/core/inet_chksum.c
@@ -109,26 +76,15 @@ set(SOURCES
     ${CMAKE_LWIP_SOURCE_DIR}/src/api/api_lib.c
     ${CMAKE_LWIP_ADAPTER_DIR}/src/arch/sys_arch.c
     ${CMAKE_LWIP_ADAPTER_DIR}/src/arch/ethernetif.c
-    ${CMAKE_LWIP_ADAPTER_DIR}/src/arch/sio.c
-    ${CMAKE_LWIP_SOURCE_DIR}/src/netif/slipif.c
-    ${CMAKE_LWIP_ADAPTER_DIR}/src/test/lwip_test.c
-    ${CMAKE_LWIP_ADAPTER_DIR}/src/test/socket_test.c
-    ${CMAKE_LWIP_ADAPTER_DIR}/src/test/slip_test.c
-    ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/lwip_driver_adapter/lwip_driver_adapter.c
-    ${lwipppp_SRCS}
 )
 
 if("__LITEOS__" IN_LIST DEFINES)
     list(APPEND SOURCES
         ${ROOT_DIR}/open_source/mbedtls/mbedtls_v3.6.0/library/net_sockets.c
+        ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/lwip_driver_adapter/lwip_net_manage.c
     )
 endif()
 
-
-
-
-
-
 set(PUBLIC_HEADER
 )
 
@@ -150,13 +106,24 @@ set(PUBLIC_DEFINES
     MBEDTLS_NET_C
 )
 
+if("SUPPORT_BREDR" IN_LIST DEFINES AND "__LITEOS__" IN_LIST DEFINES)
+    list(APPEND SOURCES
+        ${CMAKE_CURRENT_SOURCE_DIR}/lwip_adapter/lwip_driver_adapter/lwip_driver_adapter.c
+    )
+endif()
 
 # use this when you want to add ccflags like -include xxx
 set(COMPONENT_PUBLIC_CCFLAGS
 )
 
+if("BRANDY_PRODUCT_EVB4" IN_LIST DEFINES OR "BRANDY_PRODUCT_EVB" IN_LIST DEFINES)
+set(COMPONENT_CCFLAGS
+)
+else()
 set(COMPONENT_CCFLAGS
+    -Wno-unused-but-set-variable
 )
+endif()
 
 if("__ALIOS__" IN_LIST DEFINES)
     list(APPEND PRIVATE_HEADER
index 2485b79..6f1c02a 100644 (file)
 #define UNUSED(a) ((void)(a))
 #endif
 
+struct sys_arch_thread {
+    void *arg;
+    u8_t *stackMem;
+    u32_t taskId;
+};
+
 #define LWIP_SEM_ID(x) (u32_t)(uintptr_t)((x)->sem)
 
 #define MBOX_EXPAND_MULTIPLE_SIZE   2
@@ -473,35 +479,75 @@ u32_t sys_now(void)
     /* Lwip docs mentioned like wraparound is not a problem in this funtion */
     return (u32_t)((LOS_TickCountGet() * 1000) / LOSCFG_BASE_CORE_TICK_PER_SECOND);
 }
+
+void sys_thread_delete(void *param)
+{
+    if (param == NULL) {
+      return;
+    }
+    struct sys_arch_thread *threadCtl = (struct sys_arch_thread *)param;
+    LOS_TaskJoin(threadCtl->taskId, NULL);
+
+    if (threadCtl->stackMem != NULL) {
+      free(threadCtl->stackMem);
+      threadCtl->stackMem = NULL;
+    }
+    free(threadCtl);
+}
+
 u32_t sys_jiffies(void)
 {
     /*sys_jiffies is the same as sys_now*/
     return (u32_t)((LOS_TickCountGet() * 1000) / LOSCFG_BASE_CORE_TICK_PER_SECOND);
 }
+
 sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
 {
-  TSK_INIT_PARAM_S task;
-  UINT32 taskid, ret;
-  (void)memset_s(&task, sizeof(task), 0, sizeof(task));
-
+  TSK_INIT_PARAM_S task = {0};
+  u32_t taskId, ret;
+#ifdef LOSCFG_TASK_STACK_STATIC_ALLOCATION
+  u8_t *stackMem = NULL;
+#endif
+  if (function == NULL) {
+    return 0;
+  }
+  struct sys_arch_thread *param = calloc(1, sizeof(struct sys_arch_thread));
+  if (param == NULL) {
+    return 0;
+  }
+  param->arg = arg;
   /* Create host Task */
   task.pfnTaskEntry = (TSK_ENTRY_FUNC)function;
   task.uwStackSize  = 3072;     // 修改为3K=3072
   task.pcName = (char *)name;
   task.usTaskPrio = prio;
-  task.uwResved   = LOS_TASK_STATUS_DETACHED;
+  task.uwResved   = LOS_TASK_STATUS_JOINABLE;
 #ifdef BR_HW_LITEOS_VERSION
   LOS_TASK_PARAM_INIT_ARG(task, arg);
 #else
   task.auwArgs[0] = (UINTPTR)arg;
 #endif
-  ret = LOS_TaskCreate(&taskid, &task);
+#ifdef LOSCFG_TASK_STACK_STATIC_ALLOCATION
+  stackMem = memalign(LOSCFG_STACK_POINT_ALIGN_SIZE, task.uwStackSize);
+  if (stackMem == NULL) {
+    LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: memalign fail\r\n"));
+    free(param);
+    return 0;
+  }
+  param->stackMem = stackMem;
+  ret = LOS_TaskCreateStatic(&taskId, &task, stackMem);
+#else
+  ret = LOS_TaskCreate(&taskId, &task);
+#endif
+  param->taskId = taskId;
   if (ret != LOS_OK) {
     LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: LOS_TaskCreate error %u\n", ret));
-    return SYS_ARCH_ERROR;
+    free(stackMem);
+    free(param);
+    return 0;
   }
   (void)stacksize;
-  return taskid;
+  return (uintptr_t)param;
 }
 
 #ifdef LWIP_DEBUG
index ff8b943..c18d3f5 100644 (file)
@@ -95,7 +95,7 @@ struct sys_mbox {
 
 typedef struct sys_mbox *sys_mbox_t;
 
-typedef unsigned int sys_thread_t;
+typedef uintptr_t sys_thread_t;
 
 #define sys_sem_valid(x)        (((*x).sem == NULL) ? 0 : 1)
 #define sys_sem_set_invalid(x)  ((*x).sem = NULL)
index 0bee4e3..516f985 100644 (file)
@@ -776,8 +776,12 @@ extern "C" {
 #define TCP_SND_BUF        (65535 / 3)
 #endif
 
+/**
+ * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
+ * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
+ */
 #ifndef TCP_SND_QUEUELEN
-#define TCP_SND_QUEUELEN       (TCP_SND_BUF / TCP_MSS)
+#define TCP_SND_QUEUELEN                ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
 #endif
 
 #ifndef TCP_WND
@@ -833,11 +837,11 @@ extern "C" {
 #endif
 
 #ifndef MEMP_NUM_NETDB
-#define MEMP_NUM_NETDB                  1
+#define MEMP_NUM_NETDB                  8
 #endif
 
 #ifndef DNS_TABLE_SIZE
-#define DNS_TABLE_SIZE                  2
+#define DNS_TABLE_SIZE                  8
 #endif
 
 #ifndef DNS_MAX_IPADDR
@@ -1026,6 +1030,13 @@ extern "C" {
 #define IP_REASSEMBLY          1
 #endif
 
+#if IP_REASSEMBLY
+/* The IP reassembly timer interval in milliseconds. */
+#ifndef IP_TMR_INTERVAL
+#define IP_TMR_INTERVAL 2000
+#endif
+#endif
+
 #ifndef LWIP_RPL
 #define LWIP_RPL 0
 #endif
@@ -1338,6 +1349,11 @@ extern "C" {
 #define TCP_OOSEQ_MAX_PBUFS     8
 #endif
 
+/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
+ * by your system, set this to 0 and include <sys/time.h> in cc.h */
+#ifndef LWIP_TIMEVAL_PRIVATE
+#define LWIP_TIMEVAL_PRIVATE 0
+#endif
 
 /**
  * NO_SYS==1: Provides very minimal functionality. Otherwise,
@@ -1452,13 +1468,6 @@ a lot of data that needs to be copied, this should be set high. */
  */
 #ifndef LWIP_NUM_SOCKETS
 
-/**
- * DEFAULT_LWIP_NUM_SOCKETS is default number of sockets.
- */
-#ifndef DEFAULT_LWIP_NUM_SOCKETS
-#define DEFAULT_LWIP_NUM_SOCKETS        8
-#endif /* DEFAULT_LWIP_NUM_SOCKETS */
-
 #else /* else LWIP_NUM_SOCKETS*/
 
 #ifndef DEFAULT_LWIP_NUM_SOCKETS
@@ -1683,6 +1692,12 @@ extern unsigned int g_lwip_num_sockets;
 /* @ingroup Config_TCP
 * Defines the TCP TTL value.
 */
+#if LWIP_TCP
+#ifndef TCP_TMR_INTERVAL
+#define TCP_TMR_INTERVAL       2000  /* The TCP timer interval in milliseconds. */
+#endif /* TCP_TMR_INTERVAL */
+#endif
+
 #ifndef TCP_TTL
 #define TCP_TTL                 255
 #endif
@@ -1692,6 +1707,12 @@ extern unsigned int g_lwip_num_sockets;
 #define LWIP_ARP                    1
 #endif
 
+#if LWIP_ARP
+#ifndef ARP_TMR_INTERVAL
+#define ARP_TMR_INTERVAL 2000
+#endif
+#endif
+
 /**
  * Defines the mailbox size for the tcpip thread messages
  * The queue size value itself is platform-dependent, but is passed to
@@ -1798,7 +1819,38 @@ TCP sender buffer space (pbufs). This must be at least = 2 *
 
 /* ---------- IGMP options ---------- */
 #ifndef LWIP_IGMP
-#define LWIP_IGMP                       1
+#define LWIP_IGMP                       0
+#endif
+
+#if LWIP_IPV6
+#ifndef ND6_TMR_INTERVAL
+#define ND6_TMR_INTERVAL 2000
+#endif
+
+#ifndef MLD6_TMR_INTERVAL
+#define MLD6_TMR_INTERVAL              2000 /* Milliseconds */
+#endif
+
+/** The IPv6 reassembly timer interval in milliseconds. */
+#ifndef IP6_REASS_TMR_INTERVAL
+#define IP6_REASS_TMR_INTERVAL        2000
+#endif
+
+#endif
+
+/* IGMP timer */
+#if LWIP_IGMP
+#ifndef IGMP_TMR_INTERVAL
+#define IGMP_TMR_INTERVAL              2000 /* Milliseconds */
+#endif
+
+#ifndef IGMP_V1_DELAYING_MEMBER_TMR
+#define IGMP_V1_DELAYING_MEMBER_TMR   10
+#endif
+
+#ifndef IGMP_JOIN_DELAYING_MEMBER_TMR
+#define IGMP_JOIN_DELAYING_MEMBER_TMR 5
+#endif
 #endif
 
 /* ---------- DHCP options ---------- */
@@ -1809,6 +1861,12 @@ TCP sender buffer space (pbufs). This must be at least = 2 *
 #define LWIP_DHCP               1
 #endif
 
+#if LWIP_DHCP
+/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
+#ifndef DHCP_FINE_TIMER_MSECS
+#define DHCP_FINE_TIMER_MSECS   2000
+#endif
+#endif
 /* ---------- DNS options ---------- */
 /**
  * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS
@@ -1822,6 +1880,10 @@ TCP sender buffer space (pbufs). This must be at least = 2 *
 #ifndef LWIP_DNS_REVERSE
 #define LWIP_DNS_REVERSE 1
 #endif
+/** DNS timer period */
+#ifndef DNS_TMR_INTERVAL
+#define DNS_TMR_INTERVAL          3000
+#endif
 #else
 #undef LWIP_DNS_REVERSE
 #define LWIP_DNS_REVERSE 0
@@ -1829,6 +1891,14 @@ TCP sender buffer space (pbufs). This must be at least = 2 *
 
 #if !defined DNS_MAX_RETRIES && LWIP_SMALL_SIZE
 #define DNS_MAX_RETRIES          2
+
+/** period (in milliseconds) of the application calling dhcp6_tmr() */
+#if LWIP_IPV6_DHCP6
+#ifndef DHCP6_TIMER_MSECS
+#define DHCP6_TIMER_MSECS   2000
+#endif
+#endif
+
 #endif
 
 /* ---------- UDP options ---------- */
@@ -1892,31 +1962,15 @@ TCP sender buffer space (pbufs). This must be at least = 2 *
 
 /* -----------LOOPIF options -----------*/
 #ifndef LWIP_HAVE_LOOPIF
-#define LWIP_HAVE_LOOPIF                1
+#define LWIP_HAVE_LOOPIF                0
 #endif
 
 /* -----------LOOPBACK options -----------*/
 #ifndef LWIP_NETIF_LOOPBACK
-#define LWIP_NETIF_LOOPBACK             1
+#define LWIP_NETIF_LOOPBACK             0
 #endif
 
-/* ---------- Statistics options ---------- */
-/**
- * LWIP_STATS==1: Enables statistics gathering in lwip_stats.
- */
-#ifndef LWIP_STATS
-#define LWIP_STATS 1
-#endif
 
-/* ---------- TFTP options ---------- */
-#ifndef LWIP_TFTP
-#define LWIP_TFTP               1
-#endif
-
-/* ---------- SNTP options ---------- */
-#ifndef LWIP_SNTP
-#define LWIP_SNTP                      1
-#endif
 
 #if LWIP_SNTP
 
@@ -1976,10 +2030,10 @@ TCP sender buffer space (pbufs). This must be at least = 2 *
 
 #if LWIP_LITEOS_COMPAT
 #ifndef TCPIP_THREAD_STACKSIZE
-#define TCPIP_THREAD_STACKSIZE          0x6000
+#define TCPIP_THREAD_STACKSIZE          0x1000
 #endif
 #ifndef TCPIP_THREAD_PRIO
-#define TCPIP_THREAD_PRIO               5
+#define TCPIP_THREAD_PRIO               24
 #endif
 
 #ifndef LWIP_SOCKET_START_NUM
@@ -2170,10 +2224,6 @@ upto 255 interfaces . New versions donot have these restrictions but we stick to
 #endif
 #endif
 
-#ifndef LWIP_IPV6_MLD
-#define LWIP_IPV6_MLD 1
-#endif
-
 #ifndef LWIP_MLD6_ENABLE_MLD_ON_DAD
 #define LWIP_MLD6_ENABLE_MLD_ON_DAD   LWIP_IPV6 && LWIP_IPV6_MLD
 #endif
index bc845a7..352e49a 100644 (file)
@@ -4,20 +4,46 @@
 
 #include "lwip_driver_adapter.h"
 #include "lwip/tcpip.h"
+#include "lwip/etharp.h"
 #include "lwip/netifapi.h"
 #include "lwip/arch.h"
-#ifdef SUPPORT_BREDR
 #include "bts_pan.h"
 #include "bts_br_gap.h"
+
+#define LWIP_ADAPTER_DEBUG
+#ifdef LWIP_ADAPTER_DEBUG
+#define LWIP_DEBUG_LOG(message) LWIP_PLATFORM_DIAG(message)
+#else
+#define LWIP_DEBUG_LOG(message)
 #endif
+#define PAN_LOW_POWER
+
+static struct netif *g_bt_pan_netif = NULL;
+static net_connection_callback g_bt_pan_callback = NULL;
+static uint8_t g_pan_net_state = CONNECTION_UNKNOWN;
 
-#ifdef SUPPORT_BREDR
-static struct netif *bt_pan_netif = NULL;
+#ifndef PAN_LOW_POWER
+typedef struct {
+    uint8_t thread_run;
+    uint8_t end_thread;
+    sys_sem_t pan_sem;
+    void *param;
+} thread_ctl;
+
+static thread_ctl g_pan_thread = {0};
 #endif
+
+#define BTPAN_THREAD_NAME "bt_pan_listen"
+#define BTPAN_THREAD_STACKSIZE 0xc00
+#define BTPAN_THREAD_PRIO 30
+#define BTPAN_MAX_PAIRED_DEVICES 5
+#define DEVICE_MAJOR_CLASS_PHONE 0x200 /* 手机设备COD:Major Device Class = phone */
+
 static err_t lwip_driver_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr);
 
 static err_t lwip_netif_linkout(struct netif *netif, struct pbuf *p)
 {
+    (void)netif;
     if (p == NULL || p->payload == NULL) {
         return ERR_ARG;
     }
@@ -26,19 +52,21 @@ static err_t lwip_netif_linkout(struct netif *netif, struct pbuf *p)
         payload += SIZEOF_ETH_HDR;
         p->len -= SIZEOF_ETH_HDR;
     }
-#ifdef SUPPORT_BREDR
     pan_service_write_data(payload, p->len, PAN_NETWORK_PROTOCOL_ARP, PAN_PACKET_TYPE_DEST_ONLY_UNICAST);
-#endif
     return ERR_OK;
 }
 
 static err_t lwip_driver_init_fn(struct netif *netif_p)
 {
+    if (netif_p == NULL) {
+        return ERR_ARG;
+    }
     netif_p->output = lwip_driver_output;
     netif_p->linkoutput = lwip_netif_linkout;
 
     netifapi_netif_set_up(netif_p);
     netifapi_netif_set_link_up(netif_p);
+    netifapi_netif_set_default(netif_p);
     netif_p->mtu = 1000; /* 1000: mtu */
 
     return ERR_OK;
@@ -50,13 +78,6 @@ static err_t lwip_driver_init_fn(struct netif *netif_p)
 static struct netif *lwip_driver_init_netif(const char *name, const unsigned char *hw_addr)
 {
     struct netif *netif = (struct netif *)malloc(sizeof(struct netif));
-#if LWIP_IPV4
-    ip4_addr_t ipaddr, netmask, gw;
-
-    IP4_ADDR(&gw, 192, 168, 44, 1);       /* 192 168 44 1 : default gw addr */
-    IP4_ADDR(&ipaddr, 192, 168, 44, 66);  /* 192 168 44 66 : default ip addr */
-    IP4_ADDR(&netmask, 255, 255, 255, 0); /* 255 0 : default netmask */
-#endif
 
     if (netif == NULL) {
         return NULL;
@@ -68,16 +89,7 @@ static struct netif *lwip_driver_init_netif(const char *name, const unsigned cha
         return NULL;
     }
     netif->hwaddr_len = NETIF_MAX_HWADDR_LEN;
-    netifapi_netif_add(netif,
-#if LWIP_IPV4
-        &ipaddr,
-        &netmask,
-        &gw,
-#endif
-        NULL,
-        lwip_driver_init_fn,
-        tcpip_input);
-    netif_set_default(netif);
+    netifapi_netif_add(netif, NULL, NULL, NULL, NULL, lwip_driver_init_fn, tcpip_input);
     return netif;
 }
 
@@ -114,24 +126,51 @@ static err_t lwip_driver_output(struct netif *netif, struct pbuf *p, const ip4_a
     if (netif == NULL || p == NULL || ipaddr == NULL) {
         return ERR_ARG;
     }
-#ifdef SUPPORT_BREDR
+
+    uint8_t *payload = NULL;
+    struct pbuf *p_clone = NULL;
+    if (p->tot_len > p->len && p->next != NULL) {
+        p_clone = pbuf_clone(PBUF_RAW, PBUF_RAM, p); /* packet queue copy to one packet */
+        if (p_clone == NULL) {
+            return ERR_MEM;
+        }
+        payload = p_clone->payload;
+    } else {
+        payload = p->payload;
+    }
     if (ip4_addr_isbroadcast(ipaddr, netif)) {
-        pan_service_write_data(p->payload, p->len, PAN_NETWORK_PROTOCOL_IPV4, PAN_PACKET_TYPE_DEST_ONLY_BORADCAST);
+        pan_service_write_data(payload, p->tot_len, PAN_NETWORK_PROTOCOL_IPV4, PAN_PACKET_TYPE_DEST_ONLY_BORADCAST);
     } else {
-        pan_service_write_data(p->payload, p->len, PAN_NETWORK_PROTOCOL_IPV4, PAN_PACKET_TYPE_DEST_ONLY_UNICAST);
+        pan_service_write_data(payload, p->tot_len, PAN_NETWORK_PROTOCOL_IPV4, PAN_PACKET_TYPE_DEST_ONLY_UNICAST);
+    }
+    if (p_clone != NULL) {
+        pbuf_free(p_clone);
     }
-#endif
     return ERR_OK;
 }
 
-#ifdef SUPPORT_BREDR
-static void sample_pan_net_state_callback(uint8_t net_state)
+static void bt_pan_net_state_callback(uint8_t net_state)
 {
-    printf("sample pan net_state=%u\n", net_state);
+    struct netif *netif_p = g_bt_pan_netif;
+    if (netif_p == NULL) {
+        return;
+    }
     if (net_state == 1) {
+        netifapi_netif_set_link_up(netif_p);
+        netifapi_netif_set_up(netif_p);
 #if defined(LWIP_DHCP) && LWIP_DHCP
-        netifapi_dhcp_start(bt_pan_netif);
-        printf("dhcp start\n");
+        netifapi_dhcp_start(netif_p);
+#endif
+    } else {
+        netifapi_netif_set_link_down(netif_p);
+        netifapi_netif_set_down(netif_p);
+#if LWIP_IPV4
+        ip_addr_set_zero_ip4(&netif_p->ip_addr);
+        ip_addr_set_zero_ip4(&netif_p->netmask);
+        ip_addr_set_zero_ip4(&netif_p->gw);
+#endif
+#ifndef PAN_LOW_POWER
+        sys_sem_signal(&g_pan_thread.pan_sem);
 #endif
     }
 }
@@ -157,24 +196,28 @@ static int lwip_input_arp(u8_t *data, u16_t len, struct netif *netif)
 }
 #endif
 
-static void sample_pan_rpt_ethernet(uint8_t *packet, uint16_t packet_length, uint16_t network_protocol)
+static void bt_pan_rpt_ethernet(uint8_t *packet, uint16_t packet_length, uint16_t network_protocol)
 {
     int ret = ERR_OK;
+    struct netif *netif_p = g_bt_pan_netif;
+    if (netif_p == NULL) {
+        return;
+    }
     if (network_protocol == PAN_NETWORK_PROTOCOL_ARP) {
 #if defined(LWIP_IPV4) && LWIP_IPV4 && defined(LWIP_ARP) && LWIP_ARP
-        ret = lwip_input_arp(packet, packet_length, bt_pan_netif);
+        ret = lwip_input_arp(packet, packet_length, netif_p);
 #endif
     } else if (network_protocol == PAN_NETWORK_PROTOCOL_IPV4) {
-        ret = lwip_driver_input(packet, packet_length, bt_pan_netif);
+        ret = lwip_driver_input(packet, packet_length, netif_p);
     } else {
         return;
     }
     if (ret != 0) {
-        printf("pan receive packet fail, ret=0x%x\n", ret);
+        LWIP_DEBUG_LOG(("pan receive packet fail, ret=0x%x\n", ret));
     }
 }
 
-static pan_callbacks_t g_sample_pan_callbacks_t = {sample_pan_net_state_callback, sample_pan_rpt_ethernet};
+static pan_callbacks_t g_bt_pan_callbacks_t = {bt_pan_net_state_callback, bt_pan_rpt_ethernet};
 
 /* mac addr to big-endian */
 static void mac_addr_hton(uint8_t *data)
@@ -194,47 +237,244 @@ static void mac_addr_hton(uint8_t *data)
     data[3] = temp;    /* 3 : byte index */
 }
 
-static void lwip_register_bt_netif(void)
+static void init_register_bt_netif(void)
 {
-    unsigned char local_addr[6];             /* 6: mac addr length */
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+    unsigned char local_addr[6];          /* 6: mac addr length */
     bluetooth_get_local_addr(local_addr, 6); /* 6: mac addr length */
     mac_addr_hton(local_addr);
-    if (bt_pan_netif != NULL) {
+#else
+    bd_addr_t local_addr = {0};
+    bluetooth_get_local_addr(&local_addr);
+    mac_addr_hton(local_addr.addr);
+#endif
+    if (g_bt_pan_netif != NULL) {
         return;
     }
-    bt_pan_netif = lwip_driver_init_netif("bt", local_addr);
-    if (bt_pan_netif == NULL) {
-        printf("sample pan init lwip fail\n");
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+    g_bt_pan_netif = lwip_driver_init_netif("bt", local_addr);
+#else
+    g_bt_pan_netif = lwip_driver_init_netif("bt", local_addr.addr);
+#endif
+    if (g_bt_pan_netif == NULL) {
+        LWIP_DEBUG_LOG(("bt pan init lwip fail\n"));
     }
 }
 
-void bt_pan_open(void)
+static int bt_pan_get_paired_device(bd_addr_t *addr)
 {
-    int result;
-    bool ret;
-    gap_paired_device_info_t dev_info[1] = {0};
-    int number = 1;
-    lwip_register_bt_netif();
-    ret = gap_get_paired_devices_list(dev_info, &number);
-    if (ret) {
-        printf("get bt dev info ok\n");
+    int index = 0;
+    int number = BTPAN_MAX_PAIRED_DEVICES;
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+    gap_paired_device_info_t dev_info[BTPAN_MAX_PAIRED_DEVICES] = {0};
+#else
+    gap_remote_device_info_t dev_info[BTPAN_MAX_PAIRED_DEVICES] = {0};
+#endif
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+    if (!gap_get_paired_devices_list(dev_info, &number)) {
+        LWIP_DEBUG_LOG(("get bt dev info fail\n"));
+        return -1;
+    }
+#else
+    if (gap_br_get_paired_devices_list(dev_info, &number) != ERRCODE_BT_SUCCESS) {
+        LWIP_DEBUG_LOG(("get bt dev info fail\n"));
+        return -1;
+    }
+#endif
+    for (index = 0; index < BTPAN_MAX_PAIRED_DEVICES; index++) {
+#if defined(BRANDY_PRODUCT_EVB4) || defined(BRANDY_PRODUCT_EVB)
+        if ((gap_get_device_class(&dev_info[index].addr) & DEVICE_MAJOR_CLASS_PHONE) != 0) {
+            break;
+        }
+#else
+        if((dev_info[index].device_class & DEVICE_MAJOR_CLASS_PHONE) != 0) {
+            break;
+        }
+#endif
+    }
+    if (index >= BTPAN_MAX_PAIRED_DEVICES) {
+        LWIP_DEBUG_LOG(("Not find paired phone\n"));
+        return -1;
+    }
+    if (memcpy_s(addr, sizeof(bd_addr_t), &dev_info[index].addr, sizeof(bd_addr_t)) != 0) {
+        return -1;
+    }
+    return 0;
+}
+
+#if defined(PAN_LOW_POWER)
+static int bt_pan_open_service(void)
+{
+    bd_addr_t addr;
+    int ret;
+    ret = bt_pan_get_paired_device(&addr);
+    if (ret != 0) {
+        LWIP_DEBUG_LOG(("bt_pan_get_paired_device fail\n"));
+        return ret;
+    }
+    ret = pan_service_open(&addr);
+    if (ret == 0) {
+        LWIP_DEBUG_LOG(("pan_service_open ok\n"));
     } else {
-        printf("get bt dev info fail\n");
+        LWIP_DEBUG_LOG(("pan_service_open fail, ret=0x%x\n", ret));
+    }
+    return ret;
+}
+
+#else
+static void bt_pan_thread(void *arg)
+{
+    bd_addr_t addr;
+    int ret;
+    thread_ctl *thread = (thread_ctl *)arg;
+    if (thread == NULL) {
         return;
     }
-    result = pan_register_callbacks(&g_sample_pan_callbacks_t);
-    if (result == 0) {
-        printf("pan register callbacks ok\n");
-    } else {
-        printf("pan register fail\n");
+    thread->thread_run = 1;
+    sys_sem_new(&thread->pan_sem, 0);
+
+    while (thread->end_thread == 0) {
+        ret = bt_pan_get_paired_device(&addr);
+        if (ret != 0) {
+            LWIP_DEBUG_LOG(("bt_pan_get_paired_device fail\n"));
+            break;
+        }
+        if (pan_service_open(&addr) == 0) {
+            sys_arch_sem_wait(&thread->pan_sem, 0);
+            pan_service_close(&addr);
+        } else {
+            break;
+        }
+        if (thread->end_thread) {
+            break;
+        }
+        sleep(30); /* 30 : sleep 30s */
+    }
+    sys_sem_free(&thread->pan_sem);
+    thread->thread_run = 0;
+    thread->end_thread = 0;
+}
+#endif
+
+void bt_pan_close(void)
+{
+    int ret;
+    bd_addr_t addr;
+    struct netif *netif_p = g_bt_pan_netif;
+    if (netif_p == NULL) {
         return;
     }
+    pan_deregister_callbacks();
+#ifndef PAN_LOW_POWER
+    if (g_pan_thread.thread_run == 1) {
+        g_pan_thread.end_thread = 1;
+        sys_sem_signal(&g_pan_thread.pan_sem);
+    }
 
-    result = pan_service_open(&dev_info[0].addr);
+    if (g_pan_thread.param != NULL) {
+        sys_thread_delete(g_pan_thread.param);
+        g_pan_thread.param = NULL;
+    }
+#endif
+    netifapi_netif_set_link_down(netif_p);
+    netifapi_netif_set_down(netif_p);
+    netifapi_netif_remove(netif_p);
+
+    free(netif_p);
+    g_bt_pan_netif = NULL;
+    g_pan_net_state = CONNECTION_DISCONNECTED;
+
+    ret = bt_pan_get_paired_device(&addr);
+    if (ret != 0) {
+        return;
+    }
+    pan_service_close(&addr);
+}
+
+void bt_pan_open(void)
+{
+    int result;
+
+    init_register_bt_netif();
+
+    result = pan_register_callbacks(&g_bt_pan_callbacks_t);
     if (result == 0) {
-        printf("pan_service_open ok\n");
+        LWIP_DEBUG_LOG(("pan register callbacks ok\n"));
     } else {
-        printf("pan_service_open fail\n");
+        bt_pan_close();
+        LWIP_DEBUG_LOG(("pan register fail\n"));
+        return;
     }
+#ifdef PAN_LOW_POWER
+    result = bt_pan_open_service();
+    if (result != 0) {
+        bt_pan_close();
+    }
+#else
+    if (g_pan_thread.thread_run == 0) {
+        g_pan_thread.end_thread = 0;
+        g_pan_thread.param =
+            (void *)sys_thread_new(BTPAN_THREAD_NAME, bt_pan_thread, &g_pan_thread, BTPAN_THREAD_STACKSIZE, BTPAN_THREAD_PRIO);
+        if (g_pan_thread.param == NULL) {
+            LWIP_DEBUG_LOG(("bt pan thread create fail\n"));
+        }
+    }
+#endif
 }
-#endif /* SUPPORT_BREDR */
\ No newline at end of file
+
+uint8_t pan_get_net_state(void)
+{
+    return g_pan_net_state;
+}
+
+#if LWIP_NETIF_EXT_STATUS_CALLBACK
+static netif_ext_callback_t g_netif_ext_callback;
+
+static void pan_net_callback(struct netif *netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args)
+{
+    if (netif != g_bt_pan_netif) {
+        return;
+    }
+
+    if ((reason & LWIP_NSC_IPV4_ADDRESS_CHANGED || reason & LWIP_NSC_IPV6_SET) &&
+        g_pan_net_state != CONNECTION_CONNECTED) {
+        g_pan_net_state = CONNECTION_CONNECTED;
+        if (g_bt_pan_callback != NULL) {
+            LWIP_DEBUG_LOG(("pan CONNECTION_CONNECTED\n"));
+            g_bt_pan_callback(LWIP_NETIF_BT_PAN, CONNECTION_CONNECTED);
+        }
+    }
+
+    if (reason & LWIP_NSC_STATUS_CHANGED && args->status_changed.state == 0 &&
+        g_pan_net_state != CONNECTION_DISCONNECTED) {
+        g_pan_net_state = CONNECTION_DISCONNECTED;
+        if (g_bt_pan_callback != NULL) {
+            LWIP_DEBUG_LOG(("pan CONNECTION_DISCONNECTED\n"));
+            g_bt_pan_callback(LWIP_NETIF_BT_PAN, CONNECTION_DISCONNECTED);
+        }
+    }
+}
+
+void bt_pan_register_net_callback(net_connection_callback callback)
+{
+    if (g_bt_pan_callback != NULL) {
+        return;
+    }
+    g_bt_pan_callback = callback;
+    netif_add_ext_callback(&g_netif_ext_callback, pan_net_callback);
+}
+
+void bt_pan_unregister_net_callback(void)
+{
+    g_bt_pan_callback = NULL;
+    netif_remove_ext_callback(&g_netif_ext_callback);
+}
+#else
+void bt_pan_register_net_callback(net_connection_callback callback)
+{
+    (void)callback;
+}
+
+void bt_pan_unregister_net_callback(void)
+{}
+#endif
\ No newline at end of file
index 00869f8..8bf42a8 100644 (file)
@@ -1,17 +1,73 @@
 /*
- * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ * Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved.
+ * Description: extend functions
  */
 
-#ifndef LWIP_DRIVER_ADAPTER_H
-#define LWIP_DRIVER_ADAPTER_H
+#ifndef INCLUDE_LWIP_PUBLIC_H
+#define INCLUDE_LWIP_PUBLIC_H
+
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#ifdef SUPPORT_BREDR
-void bt_pan_open(void);
-#endif
+typedef enum {
+    /* 4g Cat1 netif */
+    LWIP_NETIF_VOLTE = 0,
+    /* bluetooth BT PAN netif */
+    LWIP_NETIF_BT_PAN = 1,
+    /* NULL netif */
+    LWIP_NETIF_NONE
+} lwip_netif_type;
+
+typedef enum {
+    CONNECTION_CONNECTING = 0,
+    CONNECTION_CONNECTED = 1,
+
+    CONNECTION_DISCONNECTING = 2,
+    CONNECTION_DISCONNECTED = 3,
+
+    CONNECTION_UNKNOWN = 100
+} lwip_net_connection_state;
+
+/**
+ * @brief Defines the callback function net connection status change.
+ *
+ * @param netif_type net if type, refer to #lwip_netif_type.
+ * @param net_connect_state net connection status, refer to #lwip_net_connection_state.
+ */
+typedef void (*net_connection_callback)(const uint8_t netif_type, const uint8_t net_connect_state);
+
+/**
+ * @brief This function register network connection status listener.
+ * @param[in] conn_listener             net_connection_callback.
+ * @return 0 if success; non-0 otherwise.
+ */
+int lwip_register_connect_listener(net_connection_callback conn_listener);
+
+/**
+ * @brief Defines the callback unregister function for listening net connection status change.
+ */
+void lwip_unregister_connect_listener(net_connection_callback conn_listener);
+
+/**
+ * @brief This function get current network connection status.
+ * @param[in] netif_type             netif type, refer to #lwip_netif_type.
+ * @param[in, out] net_connect_state      network connection statue, refer to #lwip_net_connection_state.
+ * @return 0 if success; non-0 otherwise.
+ */
+int lwip_get_connect_status(uint8_t netif_type, uint8_t *net_connect_state);
+
+/**
+ * @brief init and open bt pan net interface.
+ */
+void lwip_open_bt_pan(void);
+
+/**
+ * @brief close bt pan net interface.
+ */
+void lwip_close_bt_pan(void);
 
 #ifdef __cplusplus
 }
diff --git a/code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter/lwip_net_manage.c b/code/sdk/open_source/openharmony/third_party/lwip/lwip_adapter/lwip_driver_adapter/lwip_net_manage.c
new file mode 100644 (file)
index 0000000..0006027
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
+ */
+
+#include <stddef.h>
+
+#include "lwip_driver_adapter.h"
+
+#if defined(SUPPORT_VOLTE)
+static lwip_netif_type g_netif_state = LWIP_NETIF_VOLTE;
+#elif defined(SUPPORT_BREDR)
+static lwip_netif_type g_netif_state = LWIP_NETIF_BT_PAN;
+#else
+static lwip_netif_type g_netif_state = LWIP_NETIF_NONE;
+#endif
+
+typedef struct net_status_callback_t {
+    net_connection_callback callback_fn;
+    struct net_status_callback_t *next;
+} net_status_callback_t;
+
+static net_status_callback_t g_head_callback = {0};
+static uint8_t g_net_is_register = 0;
+
+static void net_status_litener(const uint8_t netif_type, const uint8_t net_connect_state)
+{}
+
+void lwip_netif_switch_volte(void)
+{
+#if defined(SUPPORT_VOLTE) && defined(SUPPORT_BREDR)
+    if (g_netif_state == LWIP_NETIF_VOLTE) {
+        return;
+    }
+    if (g_net_is_register == 0) {
+        lwip_register_connect_listener(net_status_litener);
+        g_net_is_register = 1;
+    }
+    bt_pan_close();
+    cat1_open_inner();
+    g_netif_state = LWIP_NETIF_VOLTE;
+#endif
+}
+
+void lwip_netif_switch_bt_pan(void)
+{
+#if defined(SUPPORT_VOLTE) && defined(SUPPORT_BREDR)
+    if (g_netif_state == LWIP_NETIF_BT_PAN) {
+        return;
+    }
+    if (g_net_is_register == 0) {
+        lwip_register_connect_listener(net_status_litener);
+        g_net_is_register = 1;
+    }
+    cat1_close_inner();
+    bt_pan_open();
+    g_netif_state = LWIP_NETIF_BT_PAN;
+#endif
+}
+
+void lwip_open_bt_pan(void)
+{
+#if defined(SUPPORT_BREDR)
+    if (g_netif_state != LWIP_NETIF_BT_PAN) {
+        return;
+    }
+    if (g_net_is_register == 0) {
+        lwip_register_connect_listener(net_status_litener);
+        g_net_is_register = 1;
+    }
+    bt_pan_open();
+#endif
+}
+
+void lwip_close_bt_pan(void)
+{
+#if defined(SUPPORT_BREDR)
+    if (g_netif_state != LWIP_NETIF_BT_PAN) {
+        return;
+    }
+    if (g_net_is_register) {
+        lwip_unregister_connect_listener(net_status_litener);
+        g_net_is_register = 0;
+    }
+    bt_pan_close();
+#endif
+}
+
+void lwip_cat1_open(void)
+{
+#if defined(SUPPORT_VOLTE)
+    if (g_netif_state != LWIP_NETIF_VOLTE) {
+        return;
+    }
+    if (g_net_is_register == 0) {
+        lwip_register_connect_listener(net_status_litener);
+        g_net_is_register = 1;
+    }
+    cat1_open_inner();
+#endif
+}
+
+void lwip_cat1_close(void)
+{
+#if defined(SUPPORT_VOLTE)
+    if (g_netif_state != LWIP_NETIF_VOLTE) {
+        return;
+    }
+    if (g_net_is_register) {
+        lwip_unregister_connect_listener(net_status_litener);
+        g_net_is_register = 0;
+    }
+    cat1_close_inner();
+#endif
+}
+
+int lwip_get_connect_status(uint8_t netif_type, uint8_t *net_connect_state)
+{
+    if (g_netif_state != netif_type) {
+        *net_connect_state = CONNECTION_DISCONNECTED;
+        return 0;
+    }
+#if defined(SUPPORT_VOLTE)
+    if (netif_type == LWIP_NETIF_VOLTE) {
+        *net_connect_state = cat1_get_net_state();
+        return 0;
+    }
+#endif
+#if defined(SUPPORT_BREDR)
+    if (netif_type == LWIP_NETIF_BT_PAN) {
+        *net_connect_state = pan_get_net_state();
+        return 0;
+    }
+#endif
+    return -1;
+}
+
+static void lwip_net_conn_callback(const uint8_t netif_type, const uint8_t net_connect_state)
+{
+    net_status_callback_t *iter_node = &g_head_callback;
+    while (iter_node != NULL) {
+        if (iter_node->callback_fn != NULL) {
+            iter_node->callback_fn(netif_type, net_connect_state);
+        }
+        iter_node = iter_node->next;
+    }
+}
+
+int lwip_register_connect_listener(net_connection_callback callback)
+{
+    net_status_callback_t *iter_node = &g_head_callback;
+    if (callback == NULL) {
+        return -1;
+    }
+#if defined(SUPPORT_VOLTE)
+    cat1_register_net_callback(lwip_net_conn_callback);
+#endif
+#if defined(SUPPORT_BREDR)
+    bt_pan_register_net_callback(lwip_net_conn_callback);
+#endif
+    if (g_head_callback.callback_fn == NULL) {
+        g_head_callback.callback_fn = callback;
+        return 0;
+    }
+    net_status_callback_t *ext_call_node = (net_status_callback_t *)malloc(sizeof(net_status_callback_t));
+    if (ext_call_node == NULL) {
+        return -1;
+    }
+    (void)memset_s(ext_call_node, sizeof(net_status_callback_t), 0, sizeof(net_status_callback_t));
+    ext_call_node->callback_fn = callback;
+
+    while (iter_node != NULL) {
+        if (iter_node->callback_fn == callback) {
+            free(ext_call_node);
+            return 0;
+        }
+        if (iter_node->next == NULL) {
+            iter_node->next = ext_call_node;
+            return 0;
+        }
+        iter_node = iter_node->next;
+    }
+    return 0;
+}
+
+void lwip_unregister_connect_listener(net_connection_callback callback)
+{
+    net_status_callback_t *iter_node = &g_head_callback;
+    net_status_callback_t *last = iter_node;
+    if (callback == NULL) {
+        return;
+    }
+
+    if (iter_node->callback_fn == callback) {
+        if (iter_node->next != NULL) {
+            g_head_callback.callback_fn = iter_node->next->callback_fn;
+            g_head_callback.next = iter_node->next->next;
+            free(iter_node->next);
+            return;
+        } else {
+            iter_node->callback_fn = NULL;
+            goto END;
+        }
+    }
+    while (iter_node != NULL) {
+        if (iter_node->callback_fn == callback) {
+            last->next = iter_node->next;
+            free(iter_node);
+            return;
+        }
+        last = iter_node;
+        iter_node = iter_node->next;
+    }
+    return;
+END:
+#if defined(SUPPORT_VOLTE)
+    cat1_unregister_net_callback();
+#endif
+#if defined(SUPPORT_BREDR)
+    bt_pan_unregister_net_callback();
+#endif
+}
\ No newline at end of file
index 8e3a112..5c60238 100644 (file)
@@ -324,16 +324,15 @@ const ip_addr_t dns_mquery_v6group = DNS_MQUERY_IPV6_GROUP_INIT;
 void
 dns_init(void)
 {
-
-  #ifdef DNS_SERVER_ADDRESS
+#ifdef DNS_SERVER_ADDRESS
   /* initialize default DNS server address */
   ip_addr_t dnsserver = {0};
+  u8_t n;
   DNS_SERVER_ADDRESS(&dnsserver);
-  dns_setserver(0, &dnsserver);
-#ifdef DNS_SERVER_ADDRESS_SECONDARY
-  DNS_SERVER_ADDRESS_SECONDARY(&dnsserver);
-  dns_setserver(1, &dnsserver);
-#endif
+  /* DNS servers */
+  for (n = 0; (n < LWIP_DHCP_MAX_DNS_SERVERS); n++) {
+    dns_setserver(n, &dnsserver);
+  }
 #endif /* DNS_SERVER_ADDRESS */
 
   LWIP_ASSERT("sanity check SIZEOF_DNS_QUERY",
index 063a8ca..5e09f0a 100644 (file)
@@ -421,7 +421,7 @@ dhcp_select(struct netif *netif)
   if (dhcp->tries < 255) {
     dhcp->tries++;
   }
-  msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
+  msecs = (u16_t)((dhcp->tries < 6 ? 2 : 60) * 1000); /* 6, 2, 60, 1000 : retry interval */
   dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
   return result;
@@ -1143,7 +1143,7 @@ dhcp_discover(struct netif *netif)
     autoip_start(netif);
   }
 #endif /* LWIP_DHCP_AUTOIP_COOP */
-  msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
+  msecs = (u16_t)((dhcp->tries < 6 ? 2 : 60) * 1000); /* 6, 2, 60, 1000 : retry interval */
   dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
   LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
   return result;
index 088b50e..dd4d82c 100644 (file)
@@ -1808,8 +1808,7 @@ netif_invoke_ext_callback(struct netif *netif, netif_nsc_reason_t reason, const
   netif_ext_callback_t *callback = ext_callback;
 
   LWIP_ASSERT("netif must be != NULL", netif != NULL);
-
-  while (callback != NULL) {
+  while (callback != NULL && callback->callback_fn != NULL) {
     callback->callback_fn(netif, reason, args);
     callback = callback->next;
   }
index 8149d39..a0688fa 100644 (file)
@@ -1327,7 +1327,7 @@ tcp_output(struct tcp_pcb *pcb)
   /* useg should point to last segment on unacked queue */
   useg = pcb->unacked;
   if (useg != NULL) {
-    for (; useg->next != NULL; useg = useg->next);
+    for (; useg != NULL && useg->next != NULL; useg = useg->next);
   }
   /* data available and window allows it to be sent? */
   while (seg != NULL &&
@@ -1387,6 +1387,7 @@ tcp_output(struct tcp_pcb *pcb)
         /* In the case of fast retransmit, the packet should not go to the tail
          * of the unacked queue, but rather somewhere before it. We need to check for
          * this case. -STJ Jul 27, 2004 */
+        if (useg != NULL) {
         if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) {
           /* add segment to before tail of unacked list, keeping the list sorted */
           struct tcp_seg **cur_seg = &(pcb->unacked);
@@ -1401,6 +1402,7 @@ tcp_output(struct tcp_pcb *pcb)
           useg->next = seg;
           useg = useg->next;
         }
+        }
       }
       /* do not queue empty segments on the unacked list */
     } else {
index 040f039..e0ee8d0 100644 (file)
@@ -72,8 +72,11 @@ typedef u32_t dhcp_num_t;
 #define DHCP_COARSE_TIMER_SECS  60
 /** period (in milliseconds) of the application calling dhcp_coarse_tmr() */
 #define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL)
+
 /** period (in milliseconds) of the application calling dhcp_fine_tmr() */
+#ifndef DHCP_FINE_TIMER_MSECS
 #define DHCP_FINE_TIMER_MSECS   500
+#endif
 
 #define DHCP_BOOT_FILE_LEN      128U
 
index 4f994a8..e6753a3 100644 (file)
@@ -52,7 +52,9 @@ extern "C" {
 #endif
 
 /** period (in milliseconds) of the application calling dhcp6_tmr() */
+#ifndef DHCP6_TIMER_MSECS
 #define DHCP6_TIMER_MSECS   500
+#endif
 
 struct dhcp6
 {
index bafd962..2197533 100644 (file)
@@ -51,7 +51,9 @@ extern "C" {
 #endif
 
 /** DNS timer period */
+#ifndef DNS_TMR_INTERVAL
 #define DNS_TMR_INTERVAL          1000
+#endif
 
 /* DNS resolve types: */
 #define LWIP_DNS_ADDRTYPE_IPV4      0
index 7e9f2c7..a1b9021 100644 (file)
@@ -61,7 +61,9 @@ extern "C" {
 #endif
 
 /** 1 seconds period */
+#ifndef ARP_TMR_INTERVAL
 #define ARP_TMR_INTERVAL 1000
+#endif
 
 #if ARP_QUEUEING
 /** struct for queueing outgoing packets for unknown address
index 32451c6..d14391c 100644 (file)
@@ -52,9 +52,17 @@ extern "C" {
 #endif
 
 /* IGMP timer */
+#ifndef IGMP_TMR_INTERVAL
 #define IGMP_TMR_INTERVAL              100 /* Milliseconds */
-#define IGMP_V1_DELAYING_MEMBER_TMR   (1000/IGMP_TMR_INTERVAL)
-#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL)
+#endif
+
+#ifndef IGMP_V1_DELAYING_MEMBER_TMR
+#define IGMP_V1_DELAYING_MEMBER_TMR   10
+#endif
+
+#ifndef IGMP_JOIN_DELAYING_MEMBER_TMR
+#define IGMP_JOIN_DELAYING_MEMBER_TMR 5
+#endif
 
 /* Compatibility defines (don't use for new code) */
 #define IGMP_DEL_MAC_FILTER            NETIF_DEL_MAC_FILTER
index 13744f2..e66242c 100644 (file)
@@ -53,7 +53,9 @@ extern "C" {
 
 #if IP_REASSEMBLY
 /* The IP reassembly timer interval in milliseconds. */
+#ifndef IP_TMR_INTERVAL
 #define IP_TMR_INTERVAL 1000
+#endif
 
 /** IP reassembly helper struct.
  * This is exported because memp needs to know the size.
index b278ddd..95371e1 100644 (file)
@@ -55,7 +55,9 @@ extern "C" {
 #if LWIP_IPV6 && LWIP_IPV6_REASS  /* don't build if not configured for use in lwipopts.h */
 
 /** The IPv6 reassembly timer interval in milliseconds. */
+#ifndef IP6_REASS_TMR_INTERVAL
 #define IP6_REASS_TMR_INTERVAL 1000
+#endif
 
 /** IP6_FRAG_COPYHEADER==1: for platforms where sizeof(void*) > 4, "struct
  * ip6_reass_helper" is too large to be stored in the IPv6 fragment header, and
index 77ec0cb..e7fce06 100644 (file)
@@ -70,7 +70,9 @@ struct mld_group {
   u8_t               use;
 };
 
+#ifndef MLD6_TMR_INTERVAL
 #define MLD6_TMR_INTERVAL              100 /* Milliseconds */
+#endif
 
 err_t  mld6_stop(struct netif *netif);
 void   mld6_report_groups(struct netif *netif);
index e262ff6..6e49954 100644 (file)
@@ -56,7 +56,9 @@ extern "C" {
 #endif
 
 /** 1 second period */
+#ifndef ND6_TMR_INTERVAL
 #define ND6_TMR_INTERVAL 1000
+#endif
 
 /** Router solicitations are sent in 4 second intervals (see RFC 4861, ch. 6.3.7) */
 #ifndef ND6_RTR_SOLICITATION_INTERVAL
index 2a3c2b5..c2176fe 100644 (file)
@@ -25,7 +25,7 @@ class NativeapiFs {
 public:
     NativeapiFs() = default;
     ~NativeapiFs() = default;
-
+    static int GetFullPath(const char* uri, char* fullPath, int len);
     static JSIValue MoveFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
     static JSIValue CopyFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
     static JSIValue DeleteFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
index 44a4b6e..75f51c4 100644 (file)
@@ -21,6 +21,7 @@
 #include "js_async_work.h"\r
 #include "nativeapi_common.h"\r
 #include "nativeapi_fs_impl.h"\r
+#include <climits>\r
 \r
 namespace OHOS {\r
 namespace ACELite {\r
@@ -29,6 +30,7 @@ char g_uriFullPath[FILE_NAME_MAX_LEN + 1] = {0};
 const unsigned int PREFIX_LEN = strlen(FILE_PREFIX);\r
 const char *trustPath = "/user/music";\r
 const int trustPathSize = strlen(trustPath);\r
+const int MAX_READ_FILE_SIZE = 10 * 1024 * 1024;\r
 \r
 bool IsValidPath(const char* path)\r
 {\r
@@ -65,33 +67,6 @@ bool IsValidPath(const char* path)
     return true;\r
 }\r
 \r
-int GetFullPath(const char* uri, char* fullPath, int len)\r
-{\r
-    if (!IsValidPath(uri) || (fullPath == nullptr)) {\r
-        return ERROR_CODE_PARAM;\r
-    }\r
-    const char* dataPath = GetDataPath();\r
-    int size = PREFIX_LEN;\r
-    bool isTrustPath = (strncmp(uri, trustPath, strlen(trustPath)) == 0);\r
-    if (isTrustPath) {\r
-        size = 0;\r
-    }\r
-\r
-    if (dataPath == nullptr) {\r
-        return ERROR_CODE_PARAM;\r
-    }\r
-\r
-    if (memset_s(fullPath, len, 0x0, len) != EOK) {\r
-        return ERROR_CODE_GENERAL;\r
-    }\r
-\r
-    if (sprintf_s(fullPath, len, "%s%s", (isTrustPath ? "" : dataPath), uri + size) < 0) {\r
-        return ERROR_CODE_GENERAL;\r
-    }\r
-\r
-    return NATIVE_SUCCESS;\r
-}\r
-\r
 JSIValue ExecuteAsyncWork(const JSIValue thisVal, const JSIValue* args,\r
     uint8_t argsNum, AsyncWorkHandler ExecuteFunc, bool flag = false)\r
 {\r
@@ -132,7 +107,7 @@ void ExecuteCopyFile(void* data)
     char* dest = JSI::GetStringProperty(args, FILE_DESTINATION_URI);\r
     char* destFullPath = nullptr;\r
     JSIValue result = JSI::CreateUndefined();\r
-    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+    int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
     JSI::ReleaseString(src);\r
     if (ret != NATIVE_SUCCESS) {\r
         NativeapiCommon::FailCallBack(thisVal, args, ret);\r
@@ -143,7 +118,7 @@ void ExecuteCopyFile(void* data)
         NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_GENERAL);\r
         goto EXIT;\r
     }\r
-    ret = GetFullPath(dest, destFullPath, FILE_NAME_MAX_LEN + 1);\r
+    ret = NativeapiFs::GetFullPath(dest, destFullPath, FILE_NAME_MAX_LEN + 1);\r
     if (ret != NATIVE_SUCCESS) {\r
         NativeapiCommon::FailCallBack(thisVal, args, ret);\r
         goto EXIT;\r
@@ -178,7 +153,7 @@ void ExecuteDeleteAccess(void* data)
     JSIValue args = params->args;\r
     JSIValue thisVal = params->thisVal;\r
     char* src = JSI::GetStringProperty(args, FILE_URI);\r
-    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+    int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
     JSI::ReleaseString(src);\r
     if (ret != NATIVE_SUCCESS) {\r
         NativeapiCommon::FailCallBack(thisVal, args, ret);\r
@@ -247,7 +222,7 @@ void ExecuteGetFileList(void* data)
     JSIValue thisVal = params->thisVal;\r
     char* uri = JSI::GetStringProperty(args, FILE_URI);\r
     JSIValue result = JSI::CreateObject();\r
-    int ret = GetFullPath(uri, g_uriFullPath, sizeof(g_uriFullPath));\r
+    int ret = NativeapiFs::GetFullPath(uri, g_uriFullPath, sizeof(g_uriFullPath));\r
     JSI::ReleaseString(uri);\r
     if (ret != NATIVE_SUCCESS) {\r
         NativeapiCommon::FailCallBack(thisVal, args, ret);\r
@@ -280,7 +255,7 @@ void ExecuteGetFileInfo(void* data)
     bool recursive = JSI::GetBooleanProperty(args, RECURSIVE);\r
     struct stat info = {0};\r
     JSIValue result = JSI::CreateObject();\r
-    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+    int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
     if (ret != NATIVE_SUCCESS) {\r
         NativeapiCommon::FailCallBack(thisVal, args, ret);\r
         goto EXIT;\r
@@ -320,7 +295,7 @@ void ExecuteWriteTextFile(void* data)
     char* src = JSI::GetStringProperty(args, FILE_URI);\r
     char* text = JSI::GetStringProperty(args, TEXT);\r
     bool append = JSI::GetBooleanProperty(args, FILE_APPEND);\r
-    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+    int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
     JSI::ReleaseString(src);\r
     if ((text == nullptr) || (ret != NATIVE_SUCCESS)) {\r
         NativeapiCommon::FailCallBack(thisVal, args, ERROR_CODE_PARAM);\r
@@ -346,7 +321,7 @@ int ReadTextInner(const char* src, int position, int length, JSIValue& result)
     if (length == 0) {\r
         length = TEXT_MAX_READ_LEN;\r
     }\r
-    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+    int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
     if (ret != NATIVE_SUCCESS) {\r
         return ret;\r
     }\r
@@ -407,7 +382,7 @@ void ExecuteDirFunc(void* data)
     JSIValue args = params->args;\r
     JSIValue thisVal = params->thisVal;\r
     char* src = JSI::GetStringProperty(args, FILE_URI);\r
-    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+    int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
     JSI::ReleaseString(src);\r
     bool recursive = JSI::GetBooleanProperty(args, RECURSIVE);\r
     if (ret != NATIVE_SUCCESS) {\r
@@ -436,29 +411,56 @@ int ReadArrayFileInner(const char* path, size_t len, unsigned int position, JSIV
     if (ret != NATIVE_SUCCESS) {\r
         return ret;\r
     }\r
-    void* text = malloc(info.st_size + 1);\r
-    if (text == nullptr) {\r
+\r
+    size_t fileSize = (info.st_size < 0) ? 0 : static_cast<size_t>(info.st_size);\r
+    if (fileSize > static_cast<size_t>(MAX_READ_FILE_SIZE)) {\r
+        return ERROR_CODE_GENERAL;\r
+    }\r
+\r
+    size_t pos = static_cast<size_t>(position);\r
+    if (pos > static_cast<size_t>(INT_MAX)) {\r
+        return ERROR_CODE_GENERAL;\r
+    }\r
+\r
+    size_t maxCanRead = (pos < fileSize) ? (fileSize - pos) : 0;\r
+    size_t toRead = (len == 0 || len > maxCanRead) ? maxCanRead : len;\r
+\r
+    if (toRead == 0) {\r
+        uint8_t *p = nullptr;\r
+        JSIValue emptyBuf = JSI::CreateArrayBuffer(0, p);\r
+        JSIValue emptyArr = JSI::CreateTypedArray(TypedArrayType::JSI_UINT8_ARRAY, 0, emptyBuf, 0);\r
+        JSI::SetNamedProperty(result, FILE_BUFFER, emptyArr);\r
+        JSI::ReleaseValueList(emptyArr, emptyBuf, ARGS_END);\r
+        return NATIVE_SUCCESS;\r
+    }\r
+\r
+    void *buf = malloc(toRead);\r
+    if (buf == nullptr) {\r
         return ERROR_CODE_GENERAL;\r
     }\r
+\r
     size_t actualLen = 0;\r
-    ret = ReadFileImpl(path, text, len, static_cast<int>(position), &actualLen);\r
+    ret = ReadFileImpl(path, buf, toRead, static_cast<int>(position), &actualLen);\r
     if (ret != NATIVE_SUCCESS) {\r
-        free(text);\r
+        free(buf);\r
         return ret;\r
     }\r
-    uint8_t* ptr = nullptr;\r
+\r
+    uint8_t *ptr = nullptr;\r
     JSIValue arrayBuffer = JSI::CreateArrayBuffer(actualLen, ptr);\r
     if (ptr == nullptr) {\r
-        free(text);\r
+        free(buf);\r
         JSI::ReleaseValue(arrayBuffer);\r
         return ERROR_CODE_GENERAL;\r
     }\r
-    ret = memcpy_s(ptr, actualLen, text, actualLen);\r
-    free(text);\r
+\r
+    ret = memcpy_s(ptr, actualLen, buf, actualLen);\r
+    free(buf);\r
     if (ret != EOK) {\r
         JSI::ReleaseValue(arrayBuffer);\r
         return ERROR_CODE_GENERAL;\r
     }\r
+\r
     JSIValue typedArray = JSI::CreateTypedArray(TypedArrayType::JSI_UINT8_ARRAY, actualLen, arrayBuffer, 0);\r
     JSI::SetNamedProperty(result, FILE_BUFFER, typedArray);\r
     JSI::ReleaseValueList(typedArray, arrayBuffer, ARGS_END);\r
@@ -483,7 +485,7 @@ void ExecuteReadArrayFile(void* data)
         NativeapiCommon::FailCallBack(thisVal, args, ret);\r
         goto EXIT;\r
     }\r
-    ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+    ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
     JSI::ReleaseString(src);\r
     if (ret != NATIVE_SUCCESS) {\r
         NativeapiCommon::FailCallBack(thisVal, args, ret);\r
@@ -509,7 +511,7 @@ void ExecuteWriteArrayFile(void* data)
     JSIValue args = params->args;\r
     JSIValue thisVal = params->thisVal;\r
     char* src = JSI::GetStringProperty(args, FILE_URI);\r
-    int ret = GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
+    int ret = NativeapiFs::GetFullPath(src, g_uriFullPath, sizeof(g_uriFullPath));\r
     JSI::ReleaseString(src);\r
     if (ret != NATIVE_SUCCESS) {\r
         NativeapiCommon::FailCallBack(thisVal, args, ret);\r
@@ -564,6 +566,33 @@ void InitNativeApiFs(JSIValue exports)
 #endif\r
 }\r
 \r
+int NativeapiFs::GetFullPath(const char* uri, char* fullPath, int len)\r
+{\r
+    if (!IsValidPath(uri) || (fullPath == nullptr)) {\r
+        return ERROR_CODE_PARAM;\r
+    }\r
+    const char* dataPath = GetDataPath();\r
+    int size = PREFIX_LEN;\r
+    bool isTrustPath = (strncmp(uri, trustPath, strlen(trustPath)) == 0);\r
+    if (isTrustPath) {\r
+        size = 0;\r
+    }\r
+\r
+    if (dataPath == nullptr) {\r
+        return ERROR_CODE_PARAM;\r
+    }\r
+\r
+    if (memset_s(fullPath, len, 0x0, len) != EOK) {\r
+        return ERROR_CODE_GENERAL;\r
+    }\r
+\r
+    if (sprintf_s(fullPath, len, "%s%s", (isTrustPath ? "" : dataPath), uri + size) < 0) {\r
+        return ERROR_CODE_GENERAL;\r
+    }\r
+\r
+    return NATIVE_SUCCESS;\r
+}\r
+\r
 JSIValue NativeapiFs::MoveFile(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum)\r
 {\r
     return ExecuteAsyncWork(thisVal, args, argsNum, ExecuteCopyFile, true);\r