已合并
add perception adv #12487
cnhesai创建于 9月1日
add perception adv #12487
已合并
cnhesai创建于 9月1日
从已删除 :perception-adv合入到openharmony/communication_dsoftbusmaster
共 51 个文件变更+3221-54
@@ -34,6 +34,7 @@
34#define LP_DELIVERY_MODE_REPLY 0xF034#define LP_DELIVERY_MODE_REPLY 0xF0
35#define LP_ADV_DURATION_MS 035#define LP_ADV_DURATION_MS 0
36#define LP_BT_UUID_VLINK "43d4a49f-606d-45b5-9302-4ddbbfd538fd"36#define LP_BT_UUID_VLINK "43d4a49f-606d-45b5-9302-4ddbbfd538fd"
37+#define LP_BT_UUID_PERCEPTION "43d4a49f-607d-45b5-9302-4ddbbfd538fd"
37#define MAX_FILTER_SIZE 1638#define MAX_FILTER_SIZE 16
38 39 
39typedef struct {40typedef struct {
@@ -1025,6 +1026,9 @@ static int32_t SetBtUuidByBroadCastType(LpServerType type, BtUuid *btUuid)
1025 case SOFTBUS_VIRTUAL_SCAN_TYPE:1026 case SOFTBUS_VIRTUAL_SCAN_TYPE:
1026 btUuid->uuid = LP_BT_UUID_VLINK;1027 btUuid->uuid = LP_BT_UUID_VLINK;
1027 break;1028 break;
1029+ case SOFTBUS_PERCEPTION_TYPE:
1030+ btUuid->uuid = LP_BT_UUID_PERCEPTION;
1031+ break;
1028 default:1032 default:
1029 DISC_LOGE(DISC_BLE_ADAPTER, "invalid type, type=%{public}d", type);1033 DISC_LOGE(DISC_BLE_ADAPTER, "invalid type, type=%{public}d", type);
1030 return SOFTBUS_INVALID_PARAM;1034 return SOFTBUS_INVALID_PARAM;
@@ -1208,25 +1208,40 @@ int32_t UnRegisterBroadcaster(int32_t bcId)
1208 return SOFTBUS_OK;1208 return SOFTBUS_OK;
1209}1209}
1210 1210 
1211+typedef struct {
1212+ BaseServiceType srvType;
1213+ int32_t channel;
1214+} SrvTypeChannelMap;
1215+ 
1216+static const SrvTypeChannelMap SRV_TYPE_CHANNEL_MAP[] = {
1217+ { SRV_TYPE_LP_BURST, CHANEL_LP },
1218+ { SRV_TYPE_LP_HB, CHANEL_LP },
1219+ { SRV_TYPE_CONN, CHANEL_STEADY },
1220+ { SRV_TYPE_TRANS_MSG, CHANEL_STEADY },
1221+ { SRV_TYPE_AUTH_CONN, CHANEL_STEADY },
1222+ { SRV_TYPE_APPROACH, CHANEL_STEADY },
1223+ { SRV_TYPE_OH_APPROACH, CHANEL_STEADY },
1224+ { SRV_TYPE_FAST_OFFLINE, CHANEL_STEADY },
1225+ { SRV_TYPE_RAW, CHANEL_STEADY },
1226+ { SRV_TYPE_SHARE, CHANEL_SHARE },
1227+ { SRV_TYPE_TOUCH, CHANEL_SHARE },
1228+ { SRV_TYPE_HB, CHANEL_UNSTEADY },
1229+ { SRV_TYPE_DIS, CHANEL_UNSTEADY },
1230+ { SRV_TYPE_OOP, CHANEL_UNSTEADY },
1231+ { SRV_TYPE_SD, CHANEL_UNSTEADY },
1232+ { SRV_TYPE_COLLABORATION, CHANEL_UNSTEADY },
1233+ { SRV_TYPE_PERCEPTION, CHANEL_UNSTEADY },
1234+ { SRV_TYPE_D2D_PAGING, CHANEL_SLE_D2D_PAGING },
1235+ { SRV_TYPE_D2D_GROUP_TALKIE, CHANEL_SLE_D2D_TALKIE },
1236+ { SRV_TYPE_VLINK, CHANEL_VLINK },
1237+};
1238+ 
1211static int32_t GetSrvTypeIndex(BaseServiceType srvType)1239static int32_t GetSrvTypeIndex(BaseServiceType srvType)
1212{1240{
1213- if (srvType == SRV_TYPE_LP_BURST || srvType == SRV_TYPE_LP_HB) {1241+ for (size_t i = 0; i < sizeof(SRV_TYPE_CHANNEL_MAP) / sizeof(SRV_TYPE_CHANNEL_MAP[0]); ++i) {
1214- return CHANEL_LP;1242+ if (SRV_TYPE_CHANNEL_MAP[i].srvType == srvType) {
1215- } else if (srvType == SRV_TYPE_CONN || srvType == SRV_TYPE_TRANS_MSG || srvType == SRV_TYPE_AUTH_CONN ||1243+ return SRV_TYPE_CHANNEL_MAP[i].channel;
1216- srvType == SRV_TYPE_APPROACH || srvType == SRV_TYPE_OH_APPROACH || srvType == SRV_TYPE_FAST_OFFLINE ||1244+ }
1217- srvType == SRV_TYPE_RAW) {
1218- return CHANEL_STEADY;
1219- } else if (srvType == SRV_TYPE_SHARE || srvType == SRV_TYPE_TOUCH) {
1220- return CHANEL_SHARE;
1221- } else if (srvType == SRV_TYPE_HB || srvType == SRV_TYPE_DIS || srvType == SRV_TYPE_OOP ||
1222- srvType == SRV_TYPE_SD || srvType == SRV_TYPE_COLLABORATION) {
1223- return CHANEL_UNSTEADY;
1224- } else if (srvType == SRV_TYPE_D2D_PAGING) {
1225- return CHANEL_SLE_D2D_PAGING;
1226- } else if (srvType == SRV_TYPE_D2D_GROUP_TALKIE) {
1227- return CHANEL_SLE_D2D_TALKIE;
1228- } else if (srvType == SRV_TYPE_VLINK) {
1229- return CHANEL_VLINK;
1230 }1245 }
1231 return CHANEL_UNKNOW;1246 return CHANEL_UNKNOW;
1232}1247}
@@ -21,6 +21,7 @@
21 21 
22#include "ble_range.h"22#include "ble_range.h"
23#include "data_level.h"23#include "data_level.h"
24+#include "lnn_perception.h"
24#include "softbus_agent_communication.h"25#include "softbus_agent_communication.h"
25#include "softbus_bus_center.h"26#include "softbus_bus_center.h"
26 27 
@@ -91,6 +92,13 @@ int32_t LnnIpcPostConversationData(const char *deviceId, const ConversationBusin
91int32_t LnnIpcRegisterConversationListener(const ConversationBusiness *info, int32_t pid);92int32_t LnnIpcRegisterConversationListener(const ConversationBusiness *info, int32_t pid);
92int32_t LnnIpcUnregisterConversationListener(const ConversationBusiness *info, int32_t pid);93int32_t LnnIpcUnregisterConversationListener(const ConversationBusiness *info, int32_t pid);
93int32_t LnnIpcGetTrustedDevices(DeviceNodeInfo **info, int32_t *nums);94int32_t LnnIpcGetTrustedDevices(DeviceNodeInfo **info, int32_t *nums);
95+int32_t LnnIpcStartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
96+int32_t LnnIpcSetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
97+int32_t LnnIpcStopPerceptionAdv(const char *pkgName, PerceptionType type);
98+int32_t LnnIpcStartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle);
99+int32_t LnnIpcStopPerceptionScan(const char *pkgName, PerceptionType type);
100+int32_t LnnIpcGetPerceptionDeviceList(
101+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count);
94 102 
95#ifdef __cplusplus103#ifdef __cplusplus
96}104}
@@ -28,17 +28,18 @@
28#include "lnn_connection_addr_utils.h"28#include "lnn_connection_addr_utils.h"
29#include "lnn_distributed_net_ledger.h"29#include "lnn_distributed_net_ledger.h"
30 30 
31+#include "lnn_conversation_query.h"
31#include "lnn_heartbeat_ctrl.h"32#include "lnn_heartbeat_ctrl.h"
32#include "lnn_log.h"33#include "lnn_log.h"
33#include "lnn_meta_node_ledger.h"34#include "lnn_meta_node_ledger.h"
34-#include "lnn_time_sync_manager.h"
35-#include "softbus_def.h"
36-#include "softbus_ddos.h"
37-#include "softbus_error_code.h"
38-#include "softbus_permission.h"
39-#include "lnn_conversation_query.h"
40#include "lnn_ranging_manager.h"35#include "lnn_ranging_manager.h"
36+#include "lnn_time_sync_manager.h"
37+#include "perception_manager.h"
38+#include "softbus_ddos.h"
39+#include "softbus_def.h"
40+#include "softbus_error_code.h"
41#include "softbus_init_common.h"41#include "softbus_init_common.h"
42+#include "softbus_permission.h"
42 43 
43struct JoinLnnRequestInfo {44struct JoinLnnRequestInfo {
44 char pkgName[PKG_NAME_SIZE_MAX];45 char pkgName[PKG_NAME_SIZE_MAX];
@@ -1339,4 +1340,35 @@ int32_t LnnIpcUnregisterConversationListener(const ConversationBusiness *info, i
1339int32_t LnnIpcGetTrustedDevices(DeviceNodeInfo **info, int32_t *nums)1340int32_t LnnIpcGetTrustedDevices(DeviceNodeInfo **info, int32_t *nums)
1340{1341{
1341 return LnnGetTrustedDevices(info, nums);1342 return LnnGetTrustedDevices(info, nums);
1342-}1343+}
1344+ 
xuhengxiang
xuhengxiangxuhengxiang9月17日

新增的所有 Perception IPC 接口函数均未对传入的 pkgName、param、list、count 等指针参数进行非空校验,也未对 pkgName 字符串进行长度校验。恶意或异常的IPC调用者可传入空指针或超长字符串,导致底层函数发生空指针解引用或缓冲区溢出,引发进程崩溃或安全漏洞。

在所有新增IPC接口函数入口处增加严格的参数校验。例如:if (pkgName == nullptr || strlen(pkgName) >= PKG_NAME_SIZE_MAX || param == nullptr) { return SOFTBUS_INVALID_PARAM; }。对于 LnnIpcGetPerceptionDeviceList 函数,还需额外校验 list 和 count 指针非空。

likedislike
cnhesai
cnhesai
9月19日 评论:
1345+int32_t LnnIpcStartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
1346+{
1347+ return LnnStartPerceptionAdv(pkgName, type, param);
1348+}
1349+ 
1350+int32_t LnnIpcSetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
1351+{
1352+ return LnnSetPerceptionAdvHighFreq(pkgName, type, param);
1353+}
1354+ 
1355+int32_t LnnIpcStopPerceptionAdv(const char *pkgName, PerceptionType type)
1356+{
1357+ return LnnStopPerceptionAdv(pkgName, type);
1358+}
1359+ 
1360+int32_t LnnIpcStartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle)
1361+{
1362+ return LnnStartPerceptionScan(pkgName, type, cycle);
1363+}
1364+ 
1365+int32_t LnnIpcStopPerceptionScan(const char *pkgName, PerceptionType type)
1366+{
1367+ return LnnStopPerceptionScan(pkgName, type);
1368+}
1369+ 
1370+int32_t LnnIpcGetPerceptionDeviceList(
1371+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
1372+{
1373+ return LnnGetPerceptionDeviceList(pkgName, type, list, count);
1374+}
@@ -18,6 +18,7 @@
18#include "lnn_heartbeat_ctrl.h"18#include "lnn_heartbeat_ctrl.h"
19#include "lnn_lane.h"19#include "lnn_lane.h"
20#include "lnn_time_sync_manager.h"20#include "lnn_time_sync_manager.h"
21+#include "perception_manager.h"
21 22 
22#define LNN_DUMP_CONTROL_LANE_GEOUP_INFO "control_lane_group_info"23#define LNN_DUMP_CONTROL_LANE_GEOUP_INFO "control_lane_group_info"
23 24 
@@ -39,6 +40,10 @@ int32_t LnnInitLaneHub(void)
39 LNN_LOGE(LNN_INIT, "init heart beat fail");40 LNN_LOGE(LNN_INIT, "init heart beat fail");
40 return SOFTBUS_NO_INIT;41 return SOFTBUS_NO_INIT;
41 }42 }
43+ if (PerceptionManagerInit() != SOFTBUS_OK) {
xuhengxiangxuhengxiang
xuhengxiangxuhengxiang9月17日

PerceptionManagerInit 初始化失败时未返回错误码继续执行,且若在 LnnInitLaneHub 前序步骤(如 LnnInitHeartbeat)失败提前返回时该函数根本未执行。但在 LnnDeinitLaneHub 中无条件调用了 PerceptionManagerDeinit,这会导致对未初始化资源的访问,引发崩溃或数据损坏。

在 PerceptionManagerInit 失败时应返回错误码,并在 LnnDeinitLaneHub 中调用 PerceptionManagerDeinit 前检查模块是否已成功初始化,或确保 Deinit 函数内部对未初始化状态做了安全处理。

likedislike
cnhesai
cnhesai
9月18日 评论:
xuhengxiangxuhengxiang27 天前

PerceptionManagerInit() 初始化失败后未返回错误,代码继续执行并最终返回 SOFTBUS_OK。调用方会误认为 PerceptionManager 已成功初始化,后续使用该模块功能时可能触发未定义行为或崩溃。

初始化失败时应返回错误码(如 SOFTBUS_NO_INIT),或在失败后设置标志位以阻止后续对该模块的调用,确保不会在未初始化状态下使用 PerceptionManager。

likedislike
xuhengxiangxuhengxiang27 天前

PerceptionManagerInit 初始化失败后,代码仅打印日志并继续执行(fall-through)。这会导致系统在 PerceptionManager 未成功初始化的状态下继续运行,可能引发后续逻辑错误或崩溃。同时,在 LnnDeinitLaneHub 中无条件调用 PerceptionManagerDeinit 可能会对未完全初始化的资源进行操作,引发内存安全问题。

如果 PerceptionManagerInit 是必要依赖,初始化失败时应返回错误码(如 SOFTBUS_NO_INIT)中止初始化流程;如果允许失败,需确保 PerceptionManagerDeinit 能够安全处理未初始化或部分初始化的情况,避免内存访问异常。

likedislike
44+ LNN_LOGE(LNN_INIT, "init perception fail");
45+ // fall-through
46+ }
42 if (LnnInitMcuPacked() != SOFTBUS_OK) {47 if (LnnInitMcuPacked() != SOFTBUS_OK) {
43 LNN_LOGE(LNN_INIT, "init mcu heartbeat fail");48 LNN_LOGE(LNN_INIT, "init mcu heartbeat fail");
44 }49 }
@@ -46,8 +51,8 @@ int32_t LnnInitLaneHub(void)
46 LNN_LOGE(LNN_INIT, "init control plane fail");51 LNN_LOGE(LNN_INIT, "init control plane fail");
47 return SOFTBUS_NO_INIT;52 return SOFTBUS_NO_INIT;
48 }53 }
49- if (SoftBusRegBusCenterVarDump((char*)LNN_DUMP_CONTROL_LANE_GEOUP_INFO,54+ if (SoftBusRegBusCenterVarDump((char *)LNN_DUMP_CONTROL_LANE_GEOUP_INFO, &LnnDumpControlLaneGroupInfoPacked) !=
50- &LnnDumpControlLaneGroupInfoPacked) != SOFTBUS_OK) {55+ SOFTBUS_OK) {
51 LNN_LOGE(LNN_INIT, "SoftBusRegBusCenterVarDump regist fail");56 LNN_LOGE(LNN_INIT, "SoftBusRegBusCenterVarDump regist fail");
52 }57 }
53 return SOFTBUS_OK;58 return SOFTBUS_OK;
@@ -68,5 +73,6 @@ void LnnDeinitLaneHub(void)
68 LnnDeinitQosPacked();73 LnnDeinitQosPacked();
69 DeinitLane();74 DeinitLane();
70 LnnDeinitTimeSync();75 LnnDeinitTimeSync();
76+ PerceptionManagerDeinit();
xuhengxiang
xuhengxiangxuhengxiang27 天前

LnnDeinitLaneHub 中无条件调用 PerceptionManagerDeinit(),但由于初始化失败时仍返回成功状态,反初始化路径可能被触发而 PerceptionManager 从未正确初始化,导致访问未初始化的资源或释放无效指针,引发崩溃。

使用初始化标志位或状态变量记录 PerceptionManagerInit 的结果,在 LnnDeinitLaneHub 中仅当初始化成功时才调用 PerceptionManagerDeinit(),避免对未初始化模块执行反初始化操作。

likedislike
71 LnnDeinitHeartbeat();77 LnnDeinitHeartbeat();
72}78}
@@ -23,8 +23,15 @@ bus_center_hub_inc = [
23 "$core_lane_hub_path/time_sync/include",23 "$core_lane_hub_path/time_sync/include",
24 "$core_lane_hub_path/heartbeat/include",24 "$core_lane_hub_path/heartbeat/include",
25 "$core_lane_hub_path/lane_qos/include",25 "$core_lane_hub_path/lane_qos/include",
26+ "$core_lane_hub_path/perception/include",
26 "$dsoftbus_dfx_path/interface/include",27 "$dsoftbus_dfx_path/interface/include",
28+ "$dsoftbus_root_path/interfaces/kits/adapter",
29+ "$dsoftbus_root_path/interfaces/kits/broadcast/enhance",
30+ "$dsoftbus_root_path/interfaces/inner_kits/lnn",
27 "$dsoftbus_root_path/interfaces/kits/bus_center/enhance",31 "$dsoftbus_root_path/interfaces/kits/bus_center/enhance",
32+ "$dsoftbus_root_path/core/frame/init/include",
33+ "$dsoftbus_root_path/core/broadcast/scheduler/interface",
34+ "$dsoftbus_root_path/adapter/common/net/bluetooth/broadcast/interface",
28]35]
29bus_center_hub_deps = [ "$dsoftbus_dfx_path:softbus_dfx" ]36bus_center_hub_deps = [ "$dsoftbus_dfx_path:softbus_dfx" ]
30bus_center_hub_src = []37bus_center_hub_src = []
@@ -95,7 +102,6 @@ if (dsoftbus_feature_lnn_frame && dsoftbus_feature_lnn_lane_mgr &&
95if (dsoftbus_feature_lnn_frame && dsoftbus_feature_lnn_ble) {102if (dsoftbus_feature_lnn_frame && dsoftbus_feature_lnn_ble) {
96 bus_center_hub_inc += [103 bus_center_hub_inc += [
97 "$dsoftbus_root_path/adapter/common/net/bluetooth/include",104 "$dsoftbus_root_path/adapter/common/net/bluetooth/include",
98- "$dsoftbus_root_path/adapter/common/net/bluetooth/broadcast/interface",
99 "$dsoftbus_core_path/bus_center/lnn/net_ledger/local_ledger/include",105 "$dsoftbus_core_path/bus_center/lnn/net_ledger/local_ledger/include",
100 "$dsoftbus_core_path/core/adapter/bus_center/include",106 "$dsoftbus_core_path/core/adapter/bus_center/include",
101 "$dsoftbus_core_path/core/authentication/interface",107 "$dsoftbus_core_path/core/authentication/interface",
@@ -126,4 +132,17 @@ if (dsoftbus_feature_lnn_frame && dsoftbus_feature_lnn_ble) {
126 ]132 ]
127}133}
128 134 
129-bus_center_hub_src += [ "$core_lane_hub_path/time_sync/src/lnn_time_sync_manager.c" ]135+if (dsoftbus_feature_lnn_frame && dsoftbus_feature_lnn_ble && dsoftbus_feature_conn_ble &&
136+ dsoftbus_feature_inner_disc_broadcast) {
137+ bus_center_hub_src += [
138+ "$core_lane_hub_path/perception/src/perception_manager.c",
139+ "$core_lane_hub_path/perception/src/perception_advertiser.c",
140+ "$core_lane_hub_path/perception/src/perception_scanner.c",
141+ ]
142+} else {
143+ bus_center_hub_src +=
144+ [ "$core_lane_hub_path/perception/src/perception_manager_virtual.c" ]
145+}
146+bus_center_hub_src += [
147+ "$core_lane_hub_path/time_sync/src/lnn_time_sync_manager.c",
148+]
@@ -0,0 +1,39 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+#ifndef PERCEPTION_ADVERTISER_H
16+#define PERCEPTION_ADVERTISER_H
17+ 
18+#include <stdbool.h>
19+ 
20+#include "lnn_perception.h"
21+ 
22+#ifdef __cplusplus
23+extern "C" {
24+#endif
25+ 
26+int32_t PerceptionAdvertiserInit(void);
27+void PerceptionAdvertiserDeinit(void);
28+ 
29+int32_t PerceptionAdvStart(PerceptionType type, const PerceptionAdvParam *param);
30+int32_t PerceptionAdvStop(void);
31+int32_t PerceptionAdvSetHighFreq(PerceptionType type, const PerceptionAdvParam *param);
32+ 
33+void PerceptionAdvOnBtStateChanged(bool isBtOn);
34+ 
35+#ifdef __cplusplus
36+}
37+#endif
38+ 
39+#endif
@@ -0,0 +1,30 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+#ifndef PERCEPTION_CONST_H
16+#define PERCEPTION_CONST_H
17+ 
18+#define PERCEPTION_NORMAL_INTERVAL 432 // 270ms
19+#define PERCEPTION_HIGH_INTERVAL 32 // 20ms
20+#define PERCEPTION_HIGH_DURATION_MS (10 * 1000)
21+#define PERCEPTION_SCAN_POST_START_DELAY_MS 3000
22+ 
23+#define PERCEPTION_INVALID_BC_ID (-1)
24+#define PERCEPTION_INVALID_LISTENER_ID (-1)
25+ 
26+#define PERCEPTION_CYCLE_LOW_SEC 30
27+#define PERCEPTION_CYCLE_MEDIUM_SEC 75
28+#define PERCEPTION_CYCLE_HIGH_SEC 150
29+ 
30+#endif
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+#ifndef PERCEPTION_MANAGER_H
16+#define PERCEPTION_MANAGER_H
17+ 
18+#include <stdint.h>
19+ 
20+#include "lnn_perception.h"
21+ 
22+#ifdef __cplusplus
23+extern "C" {
24+#endif
25+ 
26+int32_t PerceptionManagerInit(void);
27+void PerceptionManagerDeinit(void);
28+ 
29+int32_t LnnStartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
30+int32_t LnnSetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
31+int32_t LnnStopPerceptionAdv(const char *pkgName, PerceptionType type);
32+int32_t LnnStartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle);
33+int32_t LnnStopPerceptionScan(const char *pkgName, PerceptionType type);
34+int32_t LnnGetPerceptionDeviceList(
35+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count);
36+ 
37+#ifdef __cplusplus
38+}
39+#endif
40+ 
41+#endif
42+ 
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+#ifndef PERCEPTION_SCANNER_H
16+#define PERCEPTION_SCANNER_H
17+ 
18+#include <stdbool.h>
19+ 
20+#include "lnn_perception.h"
21+ 
22+#ifdef __cplusplus
23+extern "C" {
24+#endif
25+ 
26+int32_t PerceptionScannerInit(void);
27+void PerceptionScannerDeinit(void);
28+ 
29+int32_t PerceptionScanStart(PerceptionType type, PerceptionCycle cycle);
30+int32_t PerceptionScanStop(void);
31+ 
32+int32_t PerceptionScanGetDeviceList(PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count);
33+ 
34+void PerceptionScanOnBtStateChanged(bool isBtOn);
35+ 
36+void PerceptionScanOnScreenStateChanged(bool isScreenOn);
37+ 
38+#ifdef __cplusplus
39+}
40+#endif
41+ 
42+#endif
@@ -0,0 +1,430 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+#include "perception_advertiser.h"
16+ 
17+#include <stdatomic.h>
18+#include <stdbool.h>
19+ 
20+#include "broadcast_scheduler.h"
21+#include "bus_center_manager.h"
22+#include "g_enhance_lnn_func_pack.h"
23+#include "lnn_log.h"
24+#include "message_handler.h"
25+#include "perception_const.h"
26+#include "securec.h"
27+#include "softbus_adapter_mem.h"
28+#include "softbus_adapter_thread.h"
29+#include "softbus_common.h"
30+#include "softbus_error_code.h"
31+ 
32+typedef enum {
33+ PERCEPTION_ADV_MSG_RECOVER_LOW = 0,
34+} PerceptionAdvMessageType;
35+ 
36+typedef enum {
37+ PERCEPTION_ADV_FREQ_LOW = 0,
38+ PERCEPTION_ADV_FREQ_HIGH,
39+} PerceptionAdvFreqState;
40+ 
41+typedef struct {
42+ SoftBusMutex opLock;
43+ atomic_bool isAdvertising;
44+ int32_t bcId;
45+ PerceptionType currentType;
46+ PerceptionAdvParam currentParam;
47+} PerceptionAdvertiserContext;
48+ 
49+static PerceptionAdvertiserContext g_advCtx;
50+static SoftBusHandler g_advHandler = { NULL, NULL, NULL };
51+static atomic_bool g_advInited = false;
52+ 
53+static void PerceptionOnStartBroadcastingCallback(int32_t bcId, int32_t status)
54+{
55+ if (status != (int32_t)SOFTBUS_BC_STATUS_SUCCESS) {
56+ atomic_store(&g_advCtx.isAdvertising, false);
57+ LNN_LOGE(LNN_STATE, "perception adv start fail, bcId=%{public}d, status=%{public}d", bcId, status);
58+ return;
59+ }
60+ atomic_store(&g_advCtx.isAdvertising, true);
61+ LNN_LOGI(LNN_STATE, "perception adv physically started, bcId=%{public}d", bcId);
62+}
63+ 
64+static void PerceptionOnStopBroadcastingCallback(int32_t bcId, int32_t status)
65+{
66+ atomic_store(&g_advCtx.isAdvertising, false);
67+ LNN_LOGI(LNN_STATE, "perception adv physically stopped, bcId=%{public}d, status=%{public}d", bcId, status);
68+}
69+ 
70+static void PerceptionOnSetBroadcastingCallback(int32_t bcId, int32_t status)
71+{
72+ (void)bcId;
73+ (void)status;
74+}
75+ 
76+static const BroadcastCallback g_advCallback = {
77+ .OnStartBroadcastingCallback = PerceptionOnStartBroadcastingCallback,
78+ .OnStopBroadcastingCallback = PerceptionOnStopBroadcastingCallback,
79+ .OnSetBroadcastingCallback = PerceptionOnSetBroadcastingCallback,
80+};
81+ 
82+static int32_t ValidateAdvParam(const PerceptionAdvParam *param)
83+{
84+ if (param == NULL) {
85+ return SOFTBUS_INVALID_PARAM;
86+ }
87+ if (param->customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
88+ return SOFTBUS_INVALID_PARAM;
89+ }
90+ return SOFTBUS_OK;
91+}
92+ 
93+static bool ValidateAdvType(PerceptionType type)
94+{
95+ return type >= PERCEPTION_TYPE_COLLABORATIVE_WAKE && type < PERCEPTION_TYPE_BUTT;
96+}
97+ 
98+static void FreePacketPayload(BroadcastPacket *packet)
99+{
100+ if (packet == NULL) {
101+ return;
102+ }
103+ SoftBusFree(packet->bcData.payload);
104+ packet->bcData.payload = NULL;
105+ SoftBusFree(packet->rspData.payload);
106+ packet->rspData.payload = NULL;
107+ SoftBusFree(packet->uuidData.payload);
108+ packet->uuidData.payload = NULL;
109+}
110+ 
111+static int32_t BuildAdvPacket(PerceptionType type, const PerceptionAdvParam *param, BroadcastPacket *packet)
112+{
113+ (void)memset_s(packet, sizeof(BroadcastPacket), 0, sizeof(BroadcastPacket));
114+ 
115+ int32_t ret = PerceptionBuildAdvDataPacked(&type, param, 1, packet);
116+ if (ret != SOFTBUS_OK) {
117+ FreePacketPayload(packet);
118+ return ret;
119+ }
120+ return SOFTBUS_OK;
121+}
122+ 
123+static void BuildBcParam(BroadcastParam *bcParam, PerceptionAdvFreqState freq)
124+{
125+ (void)memset_s(bcParam, sizeof(BroadcastParam), 0, sizeof(BroadcastParam));
126+ int32_t interval = (freq == PERCEPTION_ADV_FREQ_HIGH) ? PERCEPTION_HIGH_INTERVAL : PERCEPTION_NORMAL_INTERVAL;
127+ bcParam->minInterval = interval;
128+ bcParam->maxInterval = interval;
129+ bcParam->advType = SOFTBUS_BC_ADV_NONCONN_IND;
130+ bcParam->advFilterPolicy = SOFTBUS_BC_ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY;
131+ bcParam->ownAddrType = SOFTBUS_BC_PUBLIC_DEVICE_ADDRESS;
132+ bcParam->peerAddrType = SOFTBUS_BC_PUBLIC_DEVICE_ADDRESS;
133+ bcParam->txPower = 0;
134+ bcParam->isSupportRpa = false;
135+}
136+ 
137+static void CacheParam(PerceptionType type, const PerceptionAdvParam *param)
138+{
139+ g_advCtx.currentType = type;
140+ (void)memset_s(g_advCtx.currentParam.customData, PERCEPTION_CUSTOM_DATA_MAX_LEN, 0, PERCEPTION_CUSTOM_DATA_MAX_LEN);
141+ if (param->customDataLen > 0) {
142+ (void)memcpy_s(
143+ g_advCtx.currentParam.customData, PERCEPTION_CUSTOM_DATA_MAX_LEN, param->customData, param->customDataLen);
144+ }
145+ g_advCtx.currentParam.customDataLen = param->customDataLen;
146+}
147+ 
148+static int32_t AcquireAdvLock(void)
149+{
150+ if (!atomic_load(&g_advInited)) {
151+ LNN_LOGE(LNN_STATE, "perception adv not inited");
152+ return SOFTBUS_NO_INIT;
153+ }
154+ if (SoftBusMutexLock(&g_advCtx.opLock) != SOFTBUS_OK) {
155+ LNN_LOGE(LNN_STATE, "perception adv opLock fail");
156+ return SOFTBUS_LOCK_ERR;
157+ }
158+ return SOFTBUS_OK;
159+}
160+ 
161+static bool IsAdvHandlerReady(void)
162+{
163+ return g_advHandler.looper != NULL && g_advHandler.looper->PostMessageDelay != NULL &&
164+ g_advHandler.looper->RemoveMessage != NULL;
165+}
166+ 
167+static void RemoveRecoverLowMessage(void)
168+{
169+ if (!IsAdvHandlerReady()) {
170+ return;
171+ }
172+ g_advHandler.looper->RemoveMessage(g_advHandler.looper, &g_advHandler, PERCEPTION_ADV_MSG_RECOVER_LOW);
173+}
174+ 
175+static SoftBusMessage *CreateRecoverLowMessage(void)
176+{
177+ if (!IsAdvHandlerReady()) {
178+ LNN_LOGW(LNN_STATE, "adv handler not ready, skip recover-low message");
179+ return NULL;
180+ }
181+ SoftBusMessage *msg = MallocMessage();
182+ if (msg == NULL) {
183+ LNN_LOGE(LNN_STATE, "malloc recover-low message fail");
184+ return NULL;
185+ }
186+ msg->what = PERCEPTION_ADV_MSG_RECOVER_LOW;
187+ msg->handler = &g_advHandler;
188+ msg->FreeMessage = NULL;
189+ return msg;
190+}
191+ 
192+static void PostPreparedRecoverLowMessage(SoftBusMessage *msg)
193+{
194+ RemoveRecoverLowMessage();
195+ g_advHandler.looper->PostMessageDelay(g_advHandler.looper, msg, PERCEPTION_HIGH_DURATION_MS);
196+}
197+ 
198+static int32_t PostRecoverLowMessage(void)
199+{
200+ SoftBusMessage *msg = CreateRecoverLowMessage();
201+ if (msg == NULL) {
202+ return IsAdvHandlerReady() ? SOFTBUS_MEM_ERR : SOFTBUS_LOOPER_ERR;
203+ }
204+ PostPreparedRecoverLowMessage(msg);
205+ return SOFTBUS_OK;
206+}
207+ 
208+static int32_t SwitchAdvFreq(PerceptionAdvFreqState freq)
209+{
210+ BroadcastParam bcParam;
211+ BuildBcParam(&bcParam, freq);
212+ int32_t ret = SchedulerSetBroadcastParam(g_advCtx.bcId, &bcParam);
213+ return ret;
214+}
215+ 
216+static void ClearAdvState(void)
217+{
218+ atomic_store(&g_advCtx.isAdvertising, false);
219+ g_advCtx.currentType = PERCEPTION_TYPE_BUTT;
220+ (void)memset_s(&g_advCtx.currentParam, sizeof(PerceptionAdvParam), 0, sizeof(PerceptionAdvParam));
221+}
222+ 
223+static int32_t StopAndClearAdv(void)
224+{
225+ int32_t ret = SOFTBUS_OK;
226+ if (g_advCtx.bcId != PERCEPTION_INVALID_BC_ID) {
227+ ret = SchedulerStopBroadcast(g_advCtx.bcId);
228+ }
229+ ClearAdvState();
230+ return ret;
231+}
232+ 
233+static void HandleAdvMessage(SoftBusMessage *msg)
234+{
235+ if (msg == NULL || msg->what != PERCEPTION_ADV_MSG_RECOVER_LOW) {
236+ LNN_LOGW(LNN_STATE, "perception adv handle invalid msg");
237+ return;
238+ }
239+ if (SoftBusMutexLock(&g_advCtx.opLock) != SOFTBUS_OK) {
240+ LNN_LOGE(LNN_STATE, "perception adv handle msg lock fail");
241+ return;
242+ }
243+ if (atomic_load(&g_advCtx.isAdvertising)) {
244+ LNN_LOGI(LNN_STATE, "high frequency window expired, recover to low");
245+ int32_t ret = SwitchAdvFreq(PERCEPTION_ADV_FREQ_LOW);
246+ if (ret != SOFTBUS_OK) {
247+ LNN_LOGE(LNN_STATE, "recover low fail, ret=%{public}d", ret);
248+ }
249+ }
250+ (void)SoftBusMutexUnlock(&g_advCtx.opLock);
251+}
252+ 
253+static int32_t DoStartBroadcast(PerceptionType type, const PerceptionAdvParam *param, PerceptionAdvFreqState freq)
254+{
255+ CacheParam(type, param);
256+ BroadcastPacket packet;
257+ int32_t ret = BuildAdvPacket(type, param, &packet);
258+ if (ret != SOFTBUS_OK) {
259+ LNN_LOGE(LNN_STATE, "build adv packet fail, ret=%{public}d", ret);
260+ return ret;
261+ }
262+ BroadcastParam bcParam;
263+ BuildBcParam(&bcParam, freq);
264+ 
265+ ret = SchedulerStartBroadcast(g_advCtx.bcId, BC_TYPE_PERCEPTION, &bcParam, &packet);
266+ FreePacketPayload(&packet);
267+ if (ret != SOFTBUS_OK) {
268+ LNN_LOGE(LNN_STATE, "start broadcast fail, ret=%{public}d", ret);
269+ return ret;
270+ }
271+ return SOFTBUS_OK;
272+}
273+ 
274+static int32_t UpdateAdvDataLocked(PerceptionType type, const PerceptionAdvParam *param)
275+{
276+ CacheParam(type, param);
277+ BroadcastPacket packet;
278+ int32_t ret = BuildAdvPacket(type, param, &packet);
279+ if (ret != SOFTBUS_OK) {
280+ LNN_LOGE(LNN_STATE, "build adv packet fail, ret=%{public}d", ret);
281+ return ret;
282+ }
283+ ret = SchedulerSetBroadcastData(g_advCtx.bcId, &packet);
284+ FreePacketPayload(&packet);
285+ if (ret != SOFTBUS_OK) {
286+ LNN_LOGE(LNN_STATE, "update broadcast data fail, ret=%{public}d", ret);
287+ }
288+ return ret;
289+}
290+ 
291+int32_t PerceptionAdvStart(PerceptionType type, const PerceptionAdvParam *param)
292+{
293+ int32_t ret = ValidateAdvParam(param);
294+ if (!ValidateAdvType(type) || ret != SOFTBUS_OK) {
295+ LNN_LOGE(LNN_STATE, "start adv invalid param, type=%{public}d ret=%{public}d", (int32_t)type, ret);
296+ return SOFTBUS_INVALID_PARAM;
xuhengxiang
xuhengxiangxuhengxiang27 天前

PerceptionAdvOnBtStateChanged 在释放锁后调用 DoStartBroadcast 和修改 isAdvertising。DoStartBroadcast 内部会调用 CacheParam 修改全局状态 g_advCtx,这会导致与其他线程的并发访问产生数据竞争,引发状态损坏或崩溃。

将对 DoStartBroadcast 的调用以及 isAdvertising 的修改移到持有 opLock 锁的临界区内,确保对全局状态的修改是线程安全的。

likedislike
297+ }
298+ ret = AcquireAdvLock();
299+ if (ret != SOFTBUS_OK) {
300+ return ret;
301+ }
302+ if (atomic_load(&g_advCtx.isAdvertising)) {
303+ ret = UpdateAdvDataLocked(type, param);
304+ } else {
305+ ret = DoStartBroadcast(type, param, PERCEPTION_ADV_FREQ_LOW);
306+ }
307+ (void)SoftBusMutexUnlock(&g_advCtx.opLock);
308+ return ret;
309+}
310+ 
311+int32_t PerceptionAdvSetHighFreq(PerceptionType type, const PerceptionAdvParam *param)
312+{
313+ int32_t ret = ValidateAdvParam(param);
314+ if (!ValidateAdvType(type) || ret != SOFTBUS_OK) {
315+ LNN_LOGE(LNN_STATE, "set high freq invalid param, type=%{public}d ret=%{public}d", (int32_t)type, ret);
316+ return SOFTBUS_INVALID_PARAM;
317+ }
318+ ret = AcquireAdvLock();
319+ if (ret != SOFTBUS_OK) {
320+ return ret;
321+ }
xuhengxiang
xuhengxiangxuhengxiang27 天前

在调用 SchedulerSetBroadcastData 之前没有检查 packet 是否为 NULL,可能导致空指针解引用。

在调用 SchedulerSetBroadcastData 之前,应先检查 packet 是否为 NULL,以避免空指针解引用。

likedislike
322+ if (!atomic_load(&g_advCtx.isAdvertising)) {
xuhengxiang
xuhengxiangxuhengxiang27 天前

PerceptionAdvStop 存在逻辑错误。当蓝牙关闭时,PerceptionAdvOnBtStateChanged 会将 isAdvertising 设为 false 但保留 currentType。此时调用 PerceptionAdvStop 会因 isAdvertising 为 false 而直接返回,不清理 currentType。当蓝牙重新打开时,会错误地恢复本应已停止的广播。

PerceptionAdvStop 不应仅依赖 isAdvertising 判断是否需要清理状态,应无论广播是否正在运行都清理 currentType 等期望状态,或者在蓝牙关闭时不修改 isAdvertising 而是使用单独的标志位记录底层状态。

likedislike
323+ ret = DoStartBroadcast(type, param, PERCEPTION_ADV_FREQ_HIGH);
324+ } else {
325+ ret = UpdateAdvDataLocked(type, param);
326+ if (ret == SOFTBUS_OK) {
327+ ret = SwitchAdvFreq(PERCEPTION_ADV_FREQ_HIGH);
xuhengxiang
xuhengxiangxuhengxiang27 天前

在调用 FreePacketPayload 之前没有检查 packet 是否为 NULL,可能导致空指针解引用。

在调用 FreePacketPayload 之前,应先检查 packet 是否为 NULL,以避免空指针解引用。

likedislike
328+ }
329+ }
330+ if (ret == SOFTBUS_OK) {
331+ (void)PostRecoverLowMessage();
332+ }
333+ (void)SoftBusMutexUnlock(&g_advCtx.opLock);
334+ LNN_LOGI(LNN_STATE, "perception adv set high freq, ret=%{public}d", ret);
335+ return ret;
336+}
337+ 
338+int32_t PerceptionAdvStop(void)
339+{
340+ int32_t ret = AcquireAdvLock();
341+ if (ret != SOFTBUS_OK) {
342+ return ret;
343+ }
344+ if (!atomic_load(&g_advCtx.isAdvertising)) {
345+ LNN_LOGW(LNN_STATE, "perception adv already stopped");
xuhengxiang
xuhengxiangxuhengxiang9月17日

在函数 PerceptionAdvStart 和 PerceptionAdvSetHighFreq 中,未检查 SchedulerSetBroadcastData 返回的错误码,可能导致数据更新失败未被处理。

在调用 SchedulerSetBroadcastData 后,应检查返回的错误码,并相应地处理错误情况,例如重试或记录错误日志。

likedislike
cnhesai
cnhesai
9月18日 评论:
346+ (void)SoftBusMutexUnlock(&g_advCtx.opLock);
347+ return SOFTBUS_OK;
348+ }
349+ RemoveRecoverLowMessage();
350+ ret = StopAndClearAdv();
351+ (void)SoftBusMutexUnlock(&g_advCtx.opLock);
352+ LNN_LOGI(LNN_STATE, "perception adv stop, ret=%{public}d", ret);
353+ return ret;
354+}
355+ 
356+void PerceptionAdvOnBtStateChanged(bool isBtOn)
357+{
xuhengxiangxuhengxiang
xuhengxiangxuhengxiang27 天前

在函数 PerceptionAdvOnBtStateChanged 中,未检查 GetLooper 返回的 looper 是否为 NULL,可能导致程序崩溃。

在调用 GetLooper 后,应检查返回的 looper 是否为 NULL,以避免空指针解引用。

likedislike
xuhengxiangxuhengxiang27 天前

在函数 PerceptionAdvOnBtStateChanged 中,未检查 SoftBusMutexLock 的返回值,可能导致程序崩溃。

在调用 SoftBusMutexLock 后,应检查返回值是否为 SOFTBUS_OK,以避免在锁未成功获取时继续执行。

likedislike
358+ if (!atomic_load(&g_advInited)) {
359+ LNN_LOGW(LNN_STATE, "perception adv bt state change but not inited");
360+ return;
361+ }
362+ if (SoftBusMutexLock(&g_advCtx.opLock) != SOFTBUS_OK) {
363+ LNN_LOGE(LNN_STATE, "perception adv bt state change lock fail");
364+ return;
365+ }
366+ PerceptionType type = g_advCtx.currentType;
367+ PerceptionAdvParam param = g_advCtx.currentParam;
368+ (void)SoftBusMutexUnlock(&g_advCtx.opLock);
369+ if (!isBtOn) {
370+ RemoveRecoverLowMessage();
371+ atomic_store(&g_advCtx.isAdvertising, false);
372+ LNN_LOGI(LNN_STATE, "perception adv bt off, physical stopped, desired state retained");
373+ } else if (type != PERCEPTION_TYPE_BUTT) {
374+ int32_t ret = DoStartBroadcast(type, &param, PERCEPTION_ADV_FREQ_LOW);
375+ LNN_LOGI(LNN_STATE, "perception adv recover on bt on, ret=%{public}d", ret);
376+ }
377+}
378+ 
379+int32_t PerceptionAdvertiserInit(void)
380+{
381+ if (atomic_load(&g_advInited)) {
382+ return SOFTBUS_OK;
383+ }
384+ if (SoftBusMutexInit(&g_advCtx.opLock, NULL) != SOFTBUS_OK) {
385+ LNN_LOGE(LNN_INIT, "perception adv init opLock fail");
386+ return SOFTBUS_LOCK_ERR;
387+ }
388+ ClearAdvState();
389+ g_advCtx.bcId = PERCEPTION_INVALID_BC_ID;
390+ 
391+ SoftBusLooper *looper = GetLooper(LOOP_TYPE_DEFAULT);
392+ if (looper == NULL || looper->PostMessageDelay == NULL || looper->RemoveMessage == NULL) {
393+ LNN_LOGE(LNN_INIT, "default looper unavailable, perception adv init fail");
394+ return SOFTBUS_LOOPER_ERR;
395+ }
396+ g_advHandler.looper = looper;
397+ g_advHandler.HandleMessage = HandleAdvMessage;
398+ 
399+ int32_t bcId = PERCEPTION_INVALID_BC_ID;
400+ int32_t ret = SchedulerRegisterBroadcaster(BROADCAST_PROTOCOL_BLE, SRV_TYPE_PERCEPTION, &bcId, &g_advCallback);
401+ if (ret != SOFTBUS_OK) {
402+ LNN_LOGE(LNN_INIT, "register perception broadcaster fail, ret=%{public}d", ret);
403+ (void)SoftBusMutexDestroy(&g_advCtx.opLock);
404+ return ret;
405+ }
406+ g_advCtx.bcId = bcId;
407+ atomic_store(&g_advInited, true);
408+ LNN_LOGI(LNN_INIT, "perception advertiser init ok, bcId=%{public}d", bcId);
409+ return SOFTBUS_OK;
410+}
xuhengxiang
xuhengxiangxuhengxiang9月17日

在函数 PerceptionAdvSetHighFreq 中,未检查 PostRecoverLowMessage 返回的错误码,可能导致消息发送失败未被处理。

在调用 PostRecoverLowMessage 后,应检查返回的错误码,并相应地处理错误情况,例如重试或记录错误日志。

likedislike
411+ 
412+void PerceptionAdvertiserDeinit(void)
413+{
xuhengxiang
xuhengxiangxuhengxiang27 天前

在函数 PerceptionAdvertiserDeinit 中,未释放 looper 资源,可能导致资源泄漏。

在函数结束前,应释放 looper 资源,以避免资源泄漏。

likedislike
414+ if (!atomic_load(&g_advInited)) {
415+ return;
xuhengxiang
xuhengxiangxuhengxiang27 天前

PerceptionAdvertiserDeinit 在持有 opLock 锁的情况下调用 SchedulerUnregisterBroadcaster。如果该函数是同步的并触发回调,或内部有同步等待逻辑,极易导致死锁。

在持有锁期间仅拷贝 bcId 并清理状态,释放锁后再调用 SchedulerUnregisterBroadcaster 进行反注册。

likedislike
416+ }
417+ if (SoftBusMutexLock(&g_advCtx.opLock) != SOFTBUS_OK) {
xuhengxiang
xuhengxiangxuhengxiang27 天前

在调用 SchedulerStartBroadcast 之前没有检查 packet 是否为 NULL,可能导致空指针解引用。

在调用 SchedulerStartBroadcast 之前,应先检查 packet 是否为 NULL,以避免空指针解引用。

likedislike
418+ LNN_LOGE(LNN_INIT, "perception adv deinit opLock fail, abort (state retained)");
419+ return;
420+ }
421+ atomic_store(&g_advInited, false);
xuhengxiang
xuhengxiangxuhengxiang27 天前

在调用 FreePacketPayload 之前没有检查 packet 是否为 NULL,可能导致空指针解引用。

在调用 FreePacketPayload 之前,应先检查 packet 是否为 NULL,以避免空指针解引用。

likedislike
422+ int32_t bcId = g_advCtx.bcId;
423+ g_advCtx.bcId = PERCEPTION_INVALID_BC_ID;
424+ ClearAdvState();
425+ if (bcId != PERCEPTION_INVALID_BC_ID) {
426+ (void)SchedulerUnregisterBroadcaster(bcId);
427+ }
428+ (void)SoftBusMutexUnlock(&g_advCtx.opLock);
429+ LNN_LOGI(LNN_INIT, "perception advertiser deinit ok (persistent resources retained)");
430+}
@@ -0,0 +1,325 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+#include "perception_manager.h"
16+ 
17+#include <stdatomic.h>
18+#include <stdbool.h>
19+ 
20+#include "bus_center_event.h"
21+#include "bus_center_manager.h"
22+#include "g_enhance_lnn_func_pack.h"
23+#include "lnn_async_callback_utils.h"
24+#include "lnn_heartbeat_utils.h"
25+#include "lnn_local_net_ledger.h"
26+#include "lnn_log.h"
27+#include "lnn_perception.h"
28+#include "message_handler.h"
29+#include "perception_advertiser.h"
30+#include "perception_scanner.h"
31+#include "softbus_adapter_mem.h"
32+#include "softbus_error_code.h"
33+#include "softbus_utils.h"
34+ 
35+static atomic_bool g_mgrInited = false;
36+ 
37+static int32_t ValidatePkgName(const char *pkgName)
38+{
39+ if (pkgName == NULL) {
40+ return SOFTBUS_INVALID_PKGNAME;
41+ }
42+ if (!IsValidStringSafe(pkgName, PKG_NAME_SIZE_MAX)) {
43+ return SOFTBUS_INVALID_PKGNAME;
44+ }
45+ return SOFTBUS_OK;
46+}
47+ 
48+static bool ValidateType(PerceptionType type)
49+{
50+ return type >= PERCEPTION_TYPE_COLLABORATIVE_WAKE && type < PERCEPTION_TYPE_BUTT;
51+}
52+ 
53+static bool ValidateCycle(PerceptionCycle cycle)
54+{
55+ return cycle >= PERCEPTION_CYCLE_LOW && cycle < PERCEPTION_CYCLE_BUTT;
56+}
57+ 
58+static int32_t CheckSessionArgs(const char *pkgName, PerceptionType type)
59+{
60+ int32_t ret = ValidatePkgName(pkgName);
61+ if (ret != SOFTBUS_OK) {
62+ LNN_LOGE(LNN_STATE, "perception session invalid pkgName, ret=%{public}d", ret);
63+ return ret;
64+ }
65+ if (!ValidateType(type)) {
66+ LNN_LOGE(LNN_STATE, "perception session invalid type=%{public}d", (int32_t)type);
67+ return SOFTBUS_INVALID_PARAM;
68+ }
69+ return SOFTBUS_OK;
70+}
71+ 
72+static int32_t CheckLocalScanCapability(void)
73+{
74+ int32_t localDevTypeId = 0;
75+ if (LnnGetLocalNumInfo(NUM_KEY_DEV_TYPE_ID, &localDevTypeId) != SOFTBUS_OK) {
76+ LNN_LOGE(LNN_STATE, "get local device type fail");
77+ return SOFTBUS_FUNC_NOT_SUPPORT;
78+ }
79+ if (localDevTypeId != TYPE_PHONE_ID && localDevTypeId != TYPE_PAD_ID && localDevTypeId != TYPE_PC_ID) {
80+ LNN_LOGE(LNN_STATE, "perception scan not supported on device type=%{public}d", localDevTypeId);
81+ return SOFTBUS_FUNC_NOT_SUPPORT;
82+ }
83+ if (!LnnIsLocalSupportBurstFeature() && !IsSupportLpFeaturePacked()) {
84+ LNN_LOGE(LNN_STATE, "perception scan capability not supported");
85+ return SOFTBUS_FUNC_NOT_SUPPORT;
86+ }
87+ return SOFTBUS_OK;
88+}
89+ 
90+static int32_t CheckMgrInited(void)
91+{
92+ if (!atomic_load(&g_mgrInited)) {
93+ LNN_LOGE(LNN_STATE, "perception not inited");
94+ return SOFTBUS_NO_INIT;
95+ }
96+ return SOFTBUS_OK;
97+}
98+ 
99+static void PerceptionBtStateChangedAsync(void *para)
100+{
101+ bool *isBtOn = (bool *)para;
102+ bool on = (isBtOn != NULL) ? *isBtOn : false;
103+ SoftBusFree(isBtOn);
104+ LNN_LOGI(LNN_STATE, "perception handle bt state change, isBtOn=%{public}d", on);
105+ PerceptionAdvOnBtStateChanged(on);
106+ PerceptionScanOnBtStateChanged(on);
107+}
108+ 
109+static void PerceptionScreenStateChangeAsync(void *para)
110+{
111+ bool *isScreenOn = (bool *)para;
112+ bool on = (isScreenOn != NULL) ? *isScreenOn : false;
113+ SoftBusFree(isScreenOn);
114+ LNN_LOGI(LNN_STATE, "perception handle screen %{public}s, refresh scan params", on ? "on" : "off");
115+ PerceptionScanOnScreenStateChanged(on);
116+}
117+ 
118+static void PostBtStateChange(bool isBtOn)
119+{
120+ bool *para = (bool *)SoftBusCalloc(sizeof(bool));
121+ if (para == NULL) {
122+ LNN_LOGE(LNN_STATE, "post bt state change malloc fail");
123+ return;
124+ }
125+ *para = isBtOn;
126+ int32_t ret = LnnAsyncCallbackHelper(GetLooper(LOOP_TYPE_DEFAULT), PerceptionBtStateChangedAsync, (void *)para);
127+ if (ret != SOFTBUS_OK) {
128+ LNN_LOGE(LNN_STATE, "post bt state change err, ret=%{public}d", ret);
129+ SoftBusFree(para);
130+ }
131+}
132+ 
133+static void PostScreenStateChange(bool isScreenOn)
134+{
135+ bool *para = (bool *)SoftBusCalloc(sizeof(bool));
136+ if (para == NULL) {
137+ LNN_LOGE(LNN_STATE, "post screen state change malloc fail");
138+ return;
139+ }
140+ *para = isScreenOn;
141+ int32_t ret =
142+ LnnAsyncCallbackHelper(GetLooper(LOOP_TYPE_DEFAULT), PerceptionScreenStateChangeAsync, (void *)para);
143+ if (ret != SOFTBUS_OK) {
144+ LNN_LOGE(LNN_STATE, "post screen state change err, ret=%{public}d", ret);
145+ SoftBusFree(para);
146+ }
147+}
148+ 
149+static void PerceptionBtStateChangeEventHandler(const LnnEventBasicInfo *info)
150+{
151+ if (info == NULL || info->event != LNN_EVENT_BT_STATE_CHANGED) {
152+ LNN_LOGE(LNN_STATE, "perception bt state change evt handler get invalid param");
153+ return;
154+ }
155+ const LnnMonitorHbStateChangedEvent *event = (const LnnMonitorHbStateChangedEvent *)info;
156+ SoftBusBtState btState = (SoftBusBtState)event->status;
157+ if (btState == SOFTBUS_BLE_TURN_OFF) {
158+ PostBtStateChange(false);
159+ } else if (btState == SOFTBUS_BLE_TURN_ON) {
160+ PostBtStateChange(true);
161+ }
162+}
163+ 
164+static void PerceptionScreenStateChangeEventHandler(const LnnEventBasicInfo *info)
165+{
166+ if (info == NULL || info->event != LNN_EVENT_SCREEN_STATE_CHANGED) {
167+ LNN_LOGE(LNN_STATE, "perception screen state change evt handler get invalid param");
168+ return;
169+ }
170+ const LnnMonitorScreenStateChangedEvent *event = (const LnnMonitorScreenStateChangedEvent *)info;
171+ SoftBusScreenState state = (SoftBusScreenState)event->status;
172+ if (state == SOFTBUS_SCREEN_ON) {
173+ PostScreenStateChange(true);
174+ } else if (state == SOFTBUS_SCREEN_OFF) {
175+ PostScreenStateChange(false);
176+ }
177+}
178+ 
179+int32_t LnnStartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
180+{
181+ int32_t ret = CheckSessionArgs(pkgName, type);
182+ if (ret != SOFTBUS_OK) {
183+ return ret;
184+ }
185+ if (param == NULL || param->customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
186+ LNN_LOGE(LNN_STATE, "start perception adv invalid param, type=%{public}d", (int32_t)type);
187+ return SOFTBUS_INVALID_PARAM;
188+ }
189+ ret = CheckMgrInited();
190+ if (ret != SOFTBUS_OK) {
191+ return ret;
192+ }
193+ return PerceptionAdvStart(type, param);
194+}
195+ 
196+int32_t LnnSetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
197+{
198+ int32_t ret = CheckSessionArgs(pkgName, type);
199+ if (ret != SOFTBUS_OK) {
200+ return ret;
201+ }
202+ if (param == NULL || param->customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
203+ LNN_LOGE(LNN_STATE, "set perception adv high freq invalid param, type=%{public}d", (int32_t)type);
204+ return SOFTBUS_INVALID_PARAM;
205+ }
206+ ret = CheckMgrInited();
207+ if (ret != SOFTBUS_OK) {
208+ return ret;
209+ }
210+ return PerceptionAdvSetHighFreq(type, param);
211+}
212+ 
213+int32_t LnnStopPerceptionAdv(const char *pkgName, PerceptionType type)
214+{
215+ int32_t ret = CheckSessionArgs(pkgName, type);
216+ if (ret != SOFTBUS_OK) {
217+ return ret;
218+ }
219+ return PerceptionAdvStop();
220+}
221+ 
222+int32_t LnnStartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle)
223+{
224+ int32_t ret = CheckSessionArgs(pkgName, type);
225+ if (ret != SOFTBUS_OK) {
xuhengxiang
xuhengxiangxuhengxiang27 天前

PerceptionManagerDeinit 在设置 g_mgrInited 为 false 后执行清理操作。此时若有其他线程正在执行业务接口(如 LnnStartPerceptionAdv)且已通过状态检查,将会访问正在被释放的资源,导致 Use-After-Free 或崩溃。

引入读写锁或互斥锁,在 Deinit 执行清理时阻塞其他接口的调用,确保操作期间资源不被释放。

likedislike
226+ return ret;
227+ }
228+ if (!ValidateCycle(cycle)) {
229+ LNN_LOGE(LNN_STATE, "perception scan invalid cycle=%{public}d", (int32_t)cycle);
230+ return SOFTBUS_INVALID_PARAM;
231+ }
232+ ret = CheckLocalScanCapability();
233+ if (ret != SOFTBUS_OK) {
234+ return ret;
235+ }
236+ ret = CheckMgrInited();
237+ if (ret != SOFTBUS_OK) {
238+ return ret;
239+ }
240+ return PerceptionScanStart(type, cycle);
241+}
242+ 
243+int32_t LnnStopPerceptionScan(const char *pkgName, PerceptionType type)
244+{
245+ int32_t ret = CheckSessionArgs(pkgName, type);
246+ if (ret != SOFTBUS_OK) {
247+ return ret;
248+ }
249+ return PerceptionScanStop();
250+}
251+ 
252+int32_t LnnGetPerceptionDeviceList(
253+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
254+{
255+ int32_t ret = CheckSessionArgs(pkgName, type);
256+ if (ret != SOFTBUS_OK) {
257+ return ret;
258+ }
259+ if (list == NULL || count == NULL) {
260+ LNN_LOGE(LNN_STATE, "get perception device list invalid param, type=%{public}d", (int32_t)type);
261+ return SOFTBUS_INVALID_PARAM;
262+ }
263+ ret = CheckLocalScanCapability();
264+ if (ret != SOFTBUS_OK) {
265+ return ret;
266+ }
267+ ret = CheckMgrInited();
268+ if (ret != SOFTBUS_OK) {
269+ return ret;
270+ }
271+ return PerceptionScanGetDeviceList(type, list, count);
272+}
273+ 
274+int32_t PerceptionManagerInit(void)
275+{
xuhengxiang
xuhengxiangxuhengxiang27 天前

PerceptionManagerInit 函数使用原子变量 g_mgrInited 检查初始化状态,但在多线程并发调用时,多个线程可能同时通过检查并执行初始化逻辑,导致重复初始化、内存泄漏或状态损坏。

使用互斥锁保护初始化逻辑,或者使用原子比较交换操作(CAS)确保只有一个线程能执行初始化。

likedislike
276+ if (atomic_load(&g_mgrInited)) {
277+ return SOFTBUS_OK;
278+ }
279+ int32_t ret = PerceptionEnhanceInitPacked();
280+ if (ret != SOFTBUS_OK) {
281+ LNN_LOGW(LNN_INIT, "perception mgr packed init not available, ret=%{public}d", ret);
282+ }
283+ ret = PerceptionAdvertiserInit();
284+ if (ret != SOFTBUS_OK) {
285+ LNN_LOGE(LNN_INIT, "perception advertiser init fail, ret=%{public}d", ret);
286+ return ret;
287+ }
288+ ret = PerceptionScannerInit();
289+ if (ret != SOFTBUS_OK) {
290+ LNN_LOGE(LNN_INIT, "perception scanner init fail, ret=%{public}d", ret);
291+ PerceptionAdvertiserDeinit();
292+ return ret;
293+ }
294+ if (LnnRegisterEventHandler(LNN_EVENT_BT_STATE_CHANGED, PerceptionBtStateChangeEventHandler) != SOFTBUS_OK) {
295+ LNN_LOGE(LNN_INIT, "perception regist bt state change evt handler fail");
296+ PerceptionScannerDeinit();
297+ PerceptionAdvertiserDeinit();
298+ return SOFTBUS_NETWORK_REG_EVENT_HANDLER_ERR;
299+ }
300+ if (LnnRegisterEventHandler(LNN_EVENT_SCREEN_STATE_CHANGED, PerceptionScreenStateChangeEventHandler) !=
301+ SOFTBUS_OK) {
302+ LNN_LOGE(LNN_INIT, "perception regist screen state change evt handler fail");
303+ LnnUnregisterEventHandler(LNN_EVENT_BT_STATE_CHANGED, PerceptionBtStateChangeEventHandler);
304+ PerceptionScannerDeinit();
305+ PerceptionAdvertiserDeinit();
306+ return SOFTBUS_NETWORK_REG_EVENT_HANDLER_ERR;
307+ }
308+ atomic_store(&g_mgrInited, true);
309+ LNN_LOGI(LNN_INIT, "perception manager init ok");
310+ return SOFTBUS_OK;
311+}
312+ 
313+void PerceptionManagerDeinit(void)
314+{
315+ if (!atomic_load(&g_mgrInited)) {
316+ return;
317+ }
318+ atomic_store(&g_mgrInited, false);
319+ LnnUnregisterEventHandler(LNN_EVENT_SCREEN_STATE_CHANGED, PerceptionScreenStateChangeEventHandler);
320+ LnnUnregisterEventHandler(LNN_EVENT_BT_STATE_CHANGED, PerceptionBtStateChangeEventHandler);
321+ PerceptionScannerDeinit();
322+ PerceptionAdvertiserDeinit();
323+ PerceptionEnhanceDeinitPacked();
324+ LNN_LOGI(LNN_INIT, "perception manager deinit ok");
325+}
@@ -0,0 +1,78 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+#include "perception_manager.h"
17+ 
18+#include "lnn_log.h"
19+#include "softbus_error_code.h"
20+ 
21+int32_t PerceptionManagerInit(void)
22+{
23+ LNN_LOGI(LNN_INIT, "perception manager stub init");
24+ return SOFTBUS_OK;
25+}
26+ 
27+void PerceptionManagerDeinit(void)
28+{
29+ LNN_LOGI(LNN_INIT, "perception manager stub deinit");
30+}
31+ 
32+int32_t LnnStartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
33+{
34+ (void)pkgName;
35+ (void)type;
36+ (void)param;
37+ return SOFTBUS_NOT_IMPLEMENT;
38+}
39+ 
40+int32_t LnnSetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
41+{
42+ (void)pkgName;
43+ (void)type;
44+ (void)param;
45+ return SOFTBUS_NOT_IMPLEMENT;
46+}
47+ 
48+int32_t LnnStopPerceptionAdv(const char *pkgName, PerceptionType type)
49+{
50+ (void)pkgName;
51+ (void)type;
52+ return SOFTBUS_NOT_IMPLEMENT;
53+}
54+ 
55+int32_t LnnStartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle)
56+{
57+ (void)pkgName;
58+ (void)type;
59+ (void)cycle;
60+ return SOFTBUS_NOT_IMPLEMENT;
61+}
62+ 
63+int32_t LnnStopPerceptionScan(const char *pkgName, PerceptionType type)
64+{
65+ (void)pkgName;
66+ (void)type;
67+ return SOFTBUS_NOT_IMPLEMENT;
68+}
69+ 
70+int32_t LnnGetPerceptionDeviceList(
71+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
72+{
73+ (void)pkgName;
74+ (void)type;
75+ (void)list;
76+ (void)count;
77+ return SOFTBUS_NOT_IMPLEMENT;
78+}
@@ -0,0 +1,375 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+#include "perception_scanner.h"
16+ 
17+#include <stdatomic.h>
18+#include <stdbool.h>
19+#include <stdint.h>
20+#include <string.h>
21+ 
22+#include "broadcast_scheduler.h"
23+#include "g_enhance_lnn_func_pack.h"
24+#include "lnn_async_callback_utils.h"
25+#include "lnn_log.h"
26+#include "lnn_perception.h"
27+#include "message_handler.h"
28+#include "perception_const.h"
29+#include "securec.h"
30+#include "softbus_adapter_mem.h"
31+#include "softbus_adapter_thread.h"
32+#include "softbus_broadcast_manager.h"
33+#include "softbus_error_code.h"
34+#include "softbus_utils.h"
35+ 
36+#define PERCEPTION_SCAN_FILTER_MAX_NUM 2
37+#define PERCEPTION_SCAN_TO_SH_DELAY_MS 3000
38+ 
39+typedef struct {
40+ SoftBusMutex opLock;
41+ atomic_int listenerId;
42+ PerceptionType activeType;
43+ atomic_bool isScanning;
44+} PerceptionScannerContext;
45+ 
46+static PerceptionScannerContext g_scanCtx;
47+static atomic_bool g_scanInited = false;
48+static atomic_bool g_isScreenOn = true;
49+ 
50+static void FreePerceptionScanFilterArray(BcScanFilter *filter, uint8_t filterNum)
51+{
52+ if (filter == NULL) {
53+ return;
54+ }
55+ while (filterNum-- > 0) {
56+ SoftBusFree((filter + filterNum)->address);
57+ SoftBusFree((filter + filterNum)->deviceName);
58+ SoftBusFree((filter + filterNum)->serviceData);
59+ SoftBusFree((filter + filterNum)->serviceDataMask);
60+ SoftBusFree((filter + filterNum)->manufactureData);
61+ SoftBusFree((filter + filterNum)->manufactureDataMask);
62+ SoftBusFree((filter + filterNum)->serviceUuidData);
63+ SoftBusFree((filter + filterNum)->serviceUuidDataMask);
64+ }
65+ SoftBusFree(filter);
66+}
67+ 
68+static void BuildScanParams(BcScanParams *param)
69+{
70+ (void)memset_s(param, sizeof(BcScanParams), 0, sizeof(BcScanParams));
71+ param->scanType = SOFTBUS_BC_SCAN_TYPE_PASSIVE;
72+ param->scanPhy = SOFTBUS_BC_SCAN_PHY_1M;
73+ param->scanFilterPolicy = SOFTBUS_BC_SCAN_FILTER_POLICY_ACCEPT_ALL;
74+ if (atomic_load(&g_isScreenOn)) {
75+ param->scanInterval = SOFTBUS_BC_SCAN_INTERVAL_P10;
76+ param->scanWindow = SOFTBUS_BC_SCAN_WINDOW_P10;
77+ } else {
78+ param->scanInterval = SOFTBUS_BC_SCAN_INTERVAL_P2_FAST;
79+ param->scanWindow = SOFTBUS_BC_SCAN_WINDOW_P2_FAST;
80+ }
81+}
82+ 
83+static void PerceptionSwitchScanToSH(void *para)
84+{
85+ int32_t listenerId = *(int32_t *)para;
86+ SoftBusFree(para);
87+ 
88+ LpBroadcastParam lpAdvParam;
89+ (void)memset_s(&lpAdvParam, sizeof(LpBroadcastParam), 0, sizeof(LpBroadcastParam));
90+ lpAdvParam.bcHandle = -1;
91+ 
92+ LpScanParam lpScanParam;
93+ (void)memset_s(&lpScanParam, sizeof(LpScanParam), 0, sizeof(LpScanParam));
94+ lpScanParam.listenerId = listenerId;
95+ BuildScanParams(&lpScanParam.scanParam);
96+ 
97+ if (!BroadcastSetAdvDeviceParam(SOFTBUS_PERCEPTION_TYPE, &lpAdvParam, &lpScanParam)) {
98+ LNN_LOGE(LNN_STATE, "perception sink scan filter to SH failed, listenerId=%{public}d", listenerId);
99+ return;
100+ }
101+ 
102+ if (BroadcastSetScanReportChannelToLpDevice(listenerId, true) != SOFTBUS_OK) {
103+ LNN_LOGE(LNN_STATE, "perception switch scan report channel to SH failed, listenerId=%{public}d", listenerId);
104+ return;
105+ }
106+ LNN_LOGI(LNN_STATE, "scan sunk to SH, listenerId=%{public}d", listenerId);
107+}
108+ 
109+static void PerceptionOnStartScanCallback(int32_t listenerId, int32_t status)
110+{
111+ if (listenerId != atomic_load(&g_scanCtx.listenerId)) {
112+ LNN_LOGW(LNN_STATE, "perception scan start callback listenerId mismatch");
113+ return;
114+ }
115+ if (status != (int32_t)SOFTBUS_BC_STATUS_SUCCESS) {
116+ atomic_store(&g_scanCtx.isScanning, false);
117+ LNN_LOGE(LNN_STATE, "perception scan start callback fail, status=%{public}d", status);
118+ return;
119+ }
120+ atomic_store(&g_scanCtx.isScanning, true);
121+ int32_t *para = (int32_t *)SoftBusCalloc(sizeof(int32_t));
122+ if (para != NULL) {
123+ *para = listenerId;
124+ SoftBusLooper *looper = GetLooper(LOOP_TYPE_DEFAULT);
125+ int32_t ret =
126+ LnnAsyncCallbackDelayHelper(looper, PerceptionSwitchScanToSH, para, PERCEPTION_SCAN_POST_START_DELAY_MS);
127+ if (ret != SOFTBUS_OK) {
128+ SoftBusFree(para);
129+ }
130+ }
131+ LNN_LOGI(LNN_STATE, "perception scan physically started");
132+}
133+ 
134+static void PerceptionOnStopScanCallback(int32_t listenerId, int32_t status)
135+{
136+ if (listenerId != atomic_load(&g_scanCtx.listenerId)) {
137+ LNN_LOGW(LNN_STATE, "perception scan stop callback listenerId mismatch");
138+ return;
139+ }
140+ atomic_store(&g_scanCtx.isScanning, false);
141+ LNN_LOGI(LNN_STATE, "perception scan physically stopped, status=%{public}d", status);
142+}
143+ 
144+static const ScanCallback g_scanCallback = {
145+ .OnStartScanCallback = PerceptionOnStartScanCallback,
146+ .OnStopScanCallback = PerceptionOnStopScanCallback,
147+ .OnReportScanDataCallback = NULL,
148+};
149+ 
150+static int32_t EnsureScanFilterLocked(void)
151+{
152+ BcScanFilter *filter = NULL;
153+ uint8_t filterNum = 0;
154+ int32_t ret = PerceptionBuildScanFilterPacked(&filter, &filterNum);
155+ if (ret != SOFTBUS_OK) {
156+ LNN_LOGE(LNN_STATE, "build perception scan filter fail, ret=%{public}d", ret);
157+ return ret;
158+ }
159+ if (filter == NULL || filterNum == 0 || filterNum > PERCEPTION_SCAN_FILTER_MAX_NUM) {
160+ FreePerceptionScanFilterArray(filter, filterNum);
161+ LNN_LOGE(LNN_STATE, "perception scan filter invalid, filterNum=%{public}u", (uint32_t)filterNum);
162+ return SOFTBUS_INVALID_PARAM;
163+ }
164+ ret = SchedulerSetScanFilter(atomic_load(&g_scanCtx.listenerId), filter, filterNum);
165+ if (ret != SOFTBUS_OK) {
166+ LNN_LOGE(LNN_STATE, "set perception scan filter fail, ret=%{public}d (filter released)", ret);
167+ FreePerceptionScanFilterArray(filter, filterNum);
168+ return ret;
169+ }
170+ return SOFTBUS_OK;
171+}
172+ 
173+static int32_t AcquireScanLock(void)
174+{
175+ if (!atomic_load(&g_scanInited)) {
176+ LNN_LOGE(LNN_STATE, "perception scan not inited");
177+ return SOFTBUS_NO_INIT;
178+ }
179+ if (SoftBusMutexLock(&g_scanCtx.opLock) != SOFTBUS_OK) {
180+ LNN_LOGE(LNN_STATE, "perception scan opLock fail");
181+ return SOFTBUS_LOCK_ERR;
182+ }
183+ return SOFTBUS_OK;
184+}
185+ 
186+static uint32_t PerceptionCycleToSeconds(PerceptionCycle cycle)
187+{
188+ switch (cycle) {
189+ case PERCEPTION_CYCLE_LOW:
190+ return PERCEPTION_CYCLE_LOW_SEC;
191+ case PERCEPTION_CYCLE_MEDIUM:
192+ return PERCEPTION_CYCLE_MEDIUM_SEC;
193+ case PERCEPTION_CYCLE_HIGH:
194+ return PERCEPTION_CYCLE_HIGH_SEC;
195+ default:
196+ return 0;
197+ }
198+}
199+ 
200+int32_t PerceptionScanStart(PerceptionType type, PerceptionCycle cycle)
201+{
202+ if (type < PERCEPTION_TYPE_COLLABORATIVE_WAKE || type >= PERCEPTION_TYPE_BUTT) {
203+ LNN_LOGE(LNN_STATE, "perception scan start invalid type=%{public}d", (int32_t)type);
204+ return SOFTBUS_INVALID_PARAM;
205+ }
206+ (void)PerceptionSyncCyclePacked(type, PerceptionCycleToSeconds(cycle));
207+ int32_t ret = AcquireScanLock();
208+ if (ret != SOFTBUS_OK) {
209+ return ret;
210+ }
211+ g_scanCtx.activeType = type;
212+ if (atomic_load(&g_scanCtx.isScanning)) {
213+ LNN_LOGW(LNN_STATE, "perception scan already started");
214+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
215+ return SOFTBUS_OK;
216+ }
217+ ret = EnsureScanFilterLocked();
218+ if (ret != SOFTBUS_OK) {
219+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
220+ return ret;
221+ }
222+ BcScanParams param;
223+ BuildScanParams(&param);
224+ ret = SchedulerStartScan(atomic_load(&g_scanCtx.listenerId), &param);
225+ if (ret != SOFTBUS_OK) {
226+ LNN_LOGE(LNN_STATE, "start perception scan fail, ret=%{public}d", ret);
227+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
228+ return ret;
229+ }
230+ LNN_LOGI(LNN_STATE, "perception scan start ok, listenerId=%{public}d", atomic_load(&g_scanCtx.listenerId));
231+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
232+ (void)PerceptionSyncStatePacked(PERCEPTION_STATE_START);
233+ return SOFTBUS_OK;
234+}
235+ 
236+int32_t PerceptionScanStop(void)
237+{
238+ int32_t ret = AcquireScanLock();
239+ if (ret != SOFTBUS_OK) {
240+ return ret;
241+ }
242+ if (!atomic_load(&g_scanCtx.isScanning)) {
xuhengxiang
xuhengxiangxuhengxiang9月17日

在调用SoftBusFree之前没有检查指针是否为NULL,这可能导致野指针解引用。

在调用SoftBusFree之前,应该检查指针是否为NULL,以避免野指针解引用。

likedislike
243+ LNN_LOGW(LNN_STATE, "perception scan already stopped");
244+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
245+ return SOFTBUS_OK;
246+ }
247+ g_scanCtx.activeType = PERCEPTION_TYPE_BUTT;
248+ ret = SchedulerStopScan(atomic_load(&g_scanCtx.listenerId));
249+ atomic_store(&g_scanCtx.isScanning, false);
250+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
251+ LNN_LOGI(LNN_STATE, "perception scan stop, ret=%{public}d", ret);
252+ (void)PerceptionSyncStatePacked(PERCEPTION_STATE_STOP);
253+ return ret;
xuhengxiang
xuhengxiangxuhengxiang9月17日

在调用SoftBusFree之前没有检查指针是否为NULL,这可能导致野指针解引用。

在调用SoftBusFree之前,应该检查指针是否为NULL,以避免野指针解引用。

likedislike
254+}
xuhengxiang
xuhengxiangxuhengxiang9月17日

在调用SoftBusFree之前没有检查指针是否为NULL,这可能导致野指针解引用。

在调用SoftBusFree之前,应该检查指针是否为NULL,以避免野指针解引用。

likedislike
255+ 
xuhengxiang
xuhengxiangxuhengxiang9月17日

在调用SoftBusFree之前没有检查指针是否为NULL,这可能导致野指针解引用。

在调用SoftBusFree之前,应该检查指针是否为NULL,以避免野指针解引用。

likedislike
256+int32_t PerceptionScanGetDeviceList(PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
xuhengxiang
xuhengxiangxuhengxiang9月17日

在调用SoftBusFree之前没有检查指针是否为NULL,这可能导致野指针解引用。

在调用SoftBusFree之前,应该检查指针是否为NULL,以避免野指针解引用。

likedislike
257+{
258+ if (list == NULL || count == NULL) {
259+ LNN_LOGE(LNN_STATE, "perception scan get device list invalid param, type=%{public}d", (int32_t)type);
260+ return SOFTBUS_INVALID_PARAM;
261+ }
262+ if (!atomic_load(&g_scanCtx.isScanning)) {
263+ LNN_LOGE(LNN_STATE, "perception scan not started, type=%{public}d", (int32_t)type);
264+ return SOFTBUS_PERCEPTION_SCAN_NOT_START;
265+ }
266+ return PerceptionGetDeviceInfoListPacked(type, list, count);
267+}
268+ 
269+static int32_t PerceptionScanRecoverOnBtOnLocked(void)
270+{
271+ int32_t ret = EnsureScanFilterLocked();
272+ if (ret != SOFTBUS_OK) {
273+ return ret;
274+ }
275+ BcScanParams param;
276+ BuildScanParams(&param);
277+ ret = SchedulerStartScan(atomic_load(&g_scanCtx.listenerId), &param);
278+ if (ret != SOFTBUS_OK) {
279+ return ret;
280+ }
281+ return SOFTBUS_OK;
282+}
283+ 
284+void PerceptionScanOnScreenStateChanged(bool isScreenOn)
285+{
286+ if (!atomic_load(&g_scanInited)) {
287+ return;
288+ }
289+ atomic_store(&g_isScreenOn, isScreenOn);
290+ if (!atomic_load(&g_scanCtx.isScanning)) {
291+ return;
292+ }
293+ if (SoftBusMutexLock(&g_scanCtx.opLock) != SOFTBUS_OK) {
294+ return;
295+ }
296+ (void)SchedulerStopScan(atomic_load(&g_scanCtx.listenerId));
297+ BcScanParams param;
298+ BuildScanParams(&param);
299+ (void)SchedulerStartScan(atomic_load(&g_scanCtx.listenerId), &param);
300+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
301+ LNN_LOGI(LNN_STATE, "perception scan params updated for screen %{public}s", isScreenOn ? "on" : "off");
302+}
303+ 
304+void PerceptionScanOnBtStateChanged(bool isBtOn)
305+{
306+ if (!atomic_load(&g_scanInited)) {
307+ LNN_LOGW(LNN_STATE, "perception scan bt state change but not inited");
308+ return;
309+ }
310+ if (SoftBusMutexLock(&g_scanCtx.opLock) != SOFTBUS_OK) {
311+ LNN_LOGE(LNN_STATE, "perception scan bt state change lock fail");
312+ return;
313+ }
314+ if (!isBtOn) {
315+ atomic_store(&g_scanCtx.isScanning, false);
316+ LNN_LOGI(LNN_STATE, "perception scan bt off, physical stopped, desired state retained");
317+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
318+ return;
319+ }
320+ if (g_scanCtx.activeType == PERCEPTION_TYPE_BUTT) {
321+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
xuhengxiang
xuhengxiangxuhengxiang27 天前

在调用SoftBusFree之前,没有检查指针是否为NULL,这可能导致野指针解引用。

在调用SoftBusFree之前,应该检查指针是否为NULL,以避免野指针解引用。

likedislike
322+ return;
xuhengxiang
xuhengxiangxuhengxiang27 天前

在释放filter数组时,循环变量filterNum在循环结束后仍然被使用,这可能导致越界访问。

在循环结束后,确保不再使用filterNum变量,或者将其设置为无效值。

likedislike
323+ }
324+ int32_t ret = PerceptionScanRecoverOnBtOnLocked();
325+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
326+ LNN_LOGI(LNN_STATE, "perception scan recover on bt on, ret=%{public}d", ret);
327+}
xuhengxiang
xuhengxiangxuhengxiang27 天前

在调用SoftBusFree之前,没有检查指针是否为NULL,这可能导致野指针解引用。

在调用SoftBusFree之前,应该检查指针是否为NULL,以避免野指针解引用。

likedislike
328+ 
xuhengxiang
xuhengxiangxuhengxiang27 天前

在释放filter数组时,循环变量filterNum在循环结束后仍然被使用,这可能导致越界访问。

在循环结束后,确保不再使用filterNum变量,或者将其设置为无效值。

likedislike
329+int32_t PerceptionScannerInit(void)
330+{
331+ if (atomic_load(&g_scanInited)) {
332+ return SOFTBUS_OK;
333+ }
xuhengxiang
xuhengxiangxuhengxiang27 天前

在调用SoftBusFree之前,没有检查指针是否为NULL,这可能导致野指针解引用。

在调用SoftBusFree之前,应该检查指针是否为NULL,以避免野指针解引用。

likedislike
334+ if (SoftBusMutexInit(&g_scanCtx.opLock, NULL) != SOFTBUS_OK) {
335+ LNN_LOGE(LNN_INIT, "perception scan init opLock fail");
336+ return SOFTBUS_LOCK_ERR;
337+ }
338+ atomic_store(&g_scanCtx.isScanning, false);
339+ g_scanCtx.activeType = PERCEPTION_TYPE_BUTT;
340+ atomic_store(&g_scanCtx.listenerId, PERCEPTION_INVALID_LISTENER_ID);
341+ int32_t listenerId = PERCEPTION_INVALID_LISTENER_ID;
342+ int32_t ret =
343+ SchedulerRegisterScanListener(BROADCAST_PROTOCOL_BLE, SRV_TYPE_PERCEPTION, &listenerId, &g_scanCallback);
344+ if (ret != SOFTBUS_OK) {
345+ LNN_LOGE(LNN_INIT, "register perception scan listener fail, ret=%{public}d", ret);
346+ (void)SoftBusMutexDestroy(&g_scanCtx.opLock);
347+ return ret;
348+ }
349+ atomic_store(&g_scanCtx.listenerId, listenerId);
350+ atomic_store(&g_scanInited, true);
351+ LNN_LOGI(LNN_INIT, "perception scanner init ok, listenerId=%{public}d", listenerId);
352+ return SOFTBUS_OK;
353+}
354+ 
355+void PerceptionScannerDeinit(void)
356+{
357+ if (!atomic_load(&g_scanInited)) {
358+ return;
359+ }
360+ if (SoftBusMutexLock(&g_scanCtx.opLock) != SOFTBUS_OK) {
361+ LNN_LOGE(LNN_INIT, "perception scan deinit opLock fail, abort (state retained)");
362+ return;
363+ }
364+ atomic_store(&g_scanInited, false);
365+ atomic_store(&g_scanCtx.isScanning, false);
366+ g_scanCtx.activeType = PERCEPTION_TYPE_BUTT;
367+ int32_t listenerId = atomic_load(&g_scanCtx.listenerId);
368+ if (listenerId != PERCEPTION_INVALID_LISTENER_ID) {
369+ (void)SchedulerStopScan(listenerId);
370+ (void)SchedulerUnregisterListener(listenerId);
371+ }
372+ atomic_store(&g_scanCtx.listenerId, PERCEPTION_INVALID_LISTENER_ID);
373+ (void)SoftBusMutexUnlock(&g_scanCtx.opLock);
374+ LNN_LOGI(LNN_INIT, "perception scanner deinit ok (persistent resources retained)");
375+}
@@ -115,6 +115,12 @@ enum SoftBusFuncId {
115 SERVER_POST_CONVERSATION_DATA,115 SERVER_POST_CONVERSATION_DATA,
116 SERVER_REGISTER_CONVERSATION_LISTENER,116 SERVER_REGISTER_CONVERSATION_LISTENER,
117 SERVER_UNREGISTER_CONVERSATION_LISTENER,117 SERVER_UNREGISTER_CONVERSATION_LISTENER,
118+ SERVER_START_PERCEPTION_ADV,
119+ SERVER_STOP_PERCEPTION_ADV,
120+ SERVER_START_PERCEPTION_SCAN,
121+ SERVER_STOP_PERCEPTION_SCAN,
122+ SERVER_GET_PERCEPTION_DEVICE_LIST,
123+ SERVER_SET_PERCEPTION_ADV_HIGH_FREQ,
118 124 
119 CLIENT_ON_CHANNEL_OPENED = 256,125 CLIENT_ON_CHANNEL_OPENED = 256,
120 CLIENT_ON_CHANNEL_OPENFAILED,126 CLIENT_ON_CHANNEL_OPENFAILED,
@@ -43,6 +43,7 @@
43#include "lnn_time_sync_impl_struct.h"43#include "lnn_time_sync_impl_struct.h"
44#include "lnn_trans_lane_struct.h"44#include "lnn_trans_lane_struct.h"
45#include "softbus_adapter_crypto.h"45#include "softbus_adapter_crypto.h"
46+#include "lnn_perception.h"
46#include "softbus_broadcast_type_struct.h"47#include "softbus_broadcast_type_struct.h"
47#include "softbus_bus_center.h"48#include "softbus_bus_center.h"
48 49 
@@ -312,6 +313,14 @@ typedef bool (*FarfieldParseModuleTypeFunc)(const uint8_t *data, uint32_t dataLe
312typedef int32_t (*PostLnnCloudEventFunc)(LnnCloudMsgType event, LnnCloudHandler handler,313typedef int32_t (*PostLnnCloudEventFunc)(LnnCloudMsgType event, LnnCloudHandler handler,
313 const void *obj, uint32_t size, uint64_t delayMs);314 const void *obj, uint32_t size, uint64_t delayMs);
314typedef int32_t (*RemoveLnnCloudEventFunc)(LnnCloudMsgType event, LnnCloudRemoveCompareFunc func, void *param);315typedef int32_t (*RemoveLnnCloudEventFunc)(LnnCloudMsgType event, LnnCloudRemoveCompareFunc func, void *param);
316+typedef int32_t (*PerceptionBuildAdvDataFunc)(const PerceptionType *type, const PerceptionAdvParam *params,
317+ uint32_t paramCnt, BroadcastPacket *packet);
318+typedef int32_t (*PerceptionBuildScanFilterFunc)(BcScanFilter **filter, uint8_t *filterNum);
319+typedef int32_t (*PerceptionGetDeviceInfoListFunc)(PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count);
320+typedef int32_t (*PerceptionSyncStateFunc)(PerceptionState state);
321+typedef int32_t (*PerceptionSyncCycleFunc)(PerceptionType type, uint32_t cycle);
322+typedef int32_t (*PerceptionEnhanceInitFunc)(void);
323+typedef void (*PerceptionEnhanceDeinitFunc)(void);
315typedef int32_t (*AuthMetaOpenConnWithOtherOsTypeFunc)(const AuthConnInfo *info, const char *networkId,324typedef int32_t (*AuthMetaOpenConnWithOtherOsTypeFunc)(const AuthConnInfo *info, const char *networkId,
316 uint32_t requestId, const AuthConnCallback *callback);325 uint32_t requestId, const AuthConnCallback *callback);
317 326 
@@ -573,6 +582,13 @@ typedef struct TagLnnEnhanceFuncList {
573 AuthMetaGetIpByMetaNodeIdFunc authMetaGetIpByMetaNodeId;582 AuthMetaGetIpByMetaNodeIdFunc authMetaGetIpByMetaNodeId;
574 AuthMetaGetLocalIpByMetaNodeIdFunc authMetaGetLocalIpByMetaNodeId;583 AuthMetaGetLocalIpByMetaNodeIdFunc authMetaGetLocalIpByMetaNodeId;
575 AuthMetaGetConnectionTypeByMetaNodeIdFunc authMetaGetConnectionTypeByMetaNodeId;584 AuthMetaGetConnectionTypeByMetaNodeIdFunc authMetaGetConnectionTypeByMetaNodeId;
585+ PerceptionBuildAdvDataFunc perceptionBuildAdvData;
586+ PerceptionBuildScanFilterFunc perceptionBuildScanFilter;
587+ PerceptionGetDeviceInfoListFunc perceptionGetDeviceInfoList;
588+ PerceptionSyncStateFunc perceptionSyncState;
589+ PerceptionSyncCycleFunc perceptionSyncCycle;
590+ PerceptionEnhanceInitFunc perceptionEnhanceInit;
591+ PerceptionEnhanceDeinitFunc perceptionEnhanceDeinit;
576} LnnEnhanceFuncList;592} LnnEnhanceFuncList;
577 593 
578LnnEnhanceFuncList *LnnEnhanceFuncListGet(void);594LnnEnhanceFuncList *LnnEnhanceFuncListGet(void);
@@ -582,4 +598,4 @@ int32_t LnnRegisterEnhanceFunc(void *soHandle);
582}598}
583#endif599#endif
584 600 
585-#endif601+#endif
@@ -41,6 +41,8 @@
41#include "lnn_sync_info_manager_struct.h"41#include "lnn_sync_info_manager_struct.h"
42#include "lnn_time_sync_impl_struct.h"42#include "lnn_time_sync_impl_struct.h"
43#include "lnn_trans_lane_struct.h"43#include "lnn_trans_lane_struct.h"
44+#include "lnn_perception.h"
45+#include "softbus_broadcast_type_struct.h"
44#include "softbus_bus_center.h"46#include "softbus_bus_center.h"
45 47 
46#ifdef __cplusplus48#ifdef __cplusplus
@@ -256,9 +258,17 @@ bool FarfieldParseModuleTypePacked(const uint8_t *data, uint32_t dataLen, uint32
256int32_t PostLnnCloudEventPacked(LnnCloudMsgType event, LnnCloudHandler handler,258int32_t PostLnnCloudEventPacked(LnnCloudMsgType event, LnnCloudHandler handler,
257 const void *obj, uint32_t size, uint64_t delayMs);259 const void *obj, uint32_t size, uint64_t delayMs);
258int32_t RemoveLnnCloudEventPacked(LnnCloudMsgType event, LnnCloudRemoveCompareFunc func, void *param);260int32_t RemoveLnnCloudEventPacked(LnnCloudMsgType event, LnnCloudRemoveCompareFunc func, void *param);
261+int32_t PerceptionBuildAdvDataPacked(const PerceptionType *type, const PerceptionAdvParam *params,
262+ uint32_t paramCnt, BroadcastPacket *packet);
263+int32_t PerceptionBuildScanFilterPacked(BcScanFilter **filter, uint8_t *filterNum);
264+int32_t PerceptionGetDeviceInfoListPacked(PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count);
265+int32_t PerceptionSyncStatePacked(PerceptionState state);
266+int32_t PerceptionSyncCyclePacked(PerceptionType type, uint32_t cycle);
267+int32_t PerceptionEnhanceInitPacked(void);
268+void PerceptionEnhanceDeinitPacked(void);
259 269 
260#ifdef __cplusplus270#ifdef __cplusplus
261}271}
262#endif272#endif
263 273 
264-#endif274+#endif
@@ -46,6 +46,7 @@
46#include "lnn_async_callback_utils_struct.h"46#include "lnn_async_callback_utils_struct.h"
47#include "lnn_lane_struct.h"47#include "lnn_lane_struct.h"
48#include "lnn_lane_def_struct.h"48#include "lnn_lane_def_struct.h"
49+#include "lnn_perception.h"
49#include "message_handler.h"50#include "message_handler.h"
50#include "softbus_broadcast_type_struct.h"51#include "softbus_broadcast_type_struct.h"
51#include "softbus_broadcast_manager_struct.h"52#include "softbus_broadcast_manager_struct.h"
@@ -334,4 +334,4 @@ typedef struct TagLnnOpenFuncList {
334}334}
335#endif335#endif
336 336 
337-#endif337+#endif
@@ -290,6 +290,17 @@ void Register5thPartFunc(void *soHandle)
290 g_lnnEnhanceFuncList.authMetaOpenConnWithOtherOsType = dlsym(soHandle, "AuthMetaOpenConnWithOtherOsType");290 g_lnnEnhanceFuncList.authMetaOpenConnWithOtherOsType = dlsym(soHandle, "AuthMetaOpenConnWithOtherOsType");
291}291}
292 292 
293+void Register6thPartFunc(void *soHandle)
294+{
xuhengxiangxuhengxiang
xuhengxiangxuhengxiang9月17日

dlsym 函数的返回值未进行空指针检查,且 Register6thPartFunc 函数无错误返回机制。如果动态库中未找到对应符号,dlsym 将返回 NULL,但 LnnRegisterEnhanceFunc 仍会返回成功,后续直接调用这些 NULL 函数指针会导致空指针解引用,引发程序崩溃。

在调用 dlsym 后检查返回值是否为 NULL。若为 NULL,应记录错误日志并使 Register6thPartFunc 返回错误码,同时让 LnnRegisterEnhanceFunc 处理该错误,避免在未完全初始化的情况下继续运行。

likedislike
xuhengxiangxuhengxiang27 天前

Register6thPartFunc 函数中未对 dlsym 的返回值进行 NULL 检查。如果动态库中不存在对应符号,函数指针将被赋值为 NULL,后续直接调用这些指针会导致空指针解引用,引发程序崩溃。

在调用 dlsym 后检查返回值是否为 NULL,如果为 NULL 则记录错误并返回失败错误码,避免后续调用空指针。

likedislike
295+ g_lnnEnhanceFuncList.perceptionBuildAdvData = dlsym(soHandle, "PerceptionBuildAdvData");
296+ g_lnnEnhanceFuncList.perceptionBuildScanFilter = dlsym(soHandle, "PerceptionBuildScanFilter");
297+ g_lnnEnhanceFuncList.perceptionGetDeviceInfoList = dlsym(soHandle, "PerceptionGetDeviceInfoList");
298+ g_lnnEnhanceFuncList.perceptionSyncState = dlsym(soHandle, "PerceptionSyncState");
299+ g_lnnEnhanceFuncList.perceptionSyncCycle = dlsym(soHandle, "PerceptionSyncCycle");
300+ g_lnnEnhanceFuncList.perceptionEnhanceInit = dlsym(soHandle, "PerceptionEnhanceInit");
301+ g_lnnEnhanceFuncList.perceptionEnhanceDeinit = dlsym(soHandle, "PerceptionEnhanceDeinit");
302+}
303+ 
293int32_t LnnRegisterEnhanceFunc(void *soHandle)304int32_t LnnRegisterEnhanceFunc(void *soHandle)
294{305{
295 (void)Register1stPartFunc(soHandle);306 (void)Register1stPartFunc(soHandle);
@@ -297,5 +308,6 @@ int32_t LnnRegisterEnhanceFunc(void *soHandle)
297 (void)Register3rdPartFunc(soHandle);308 (void)Register3rdPartFunc(soHandle);
298 (void)Register4thPartFunc(soHandle);309 (void)Register4thPartFunc(soHandle);
299 (void)Register5thPartFunc(soHandle);310 (void)Register5thPartFunc(soHandle);
xuhengxiang
xuhengxiangxuhengxiang27 天前

LnnRegisterEnhanceFunc 函数强制忽略了 Register6thPartFunc 等注册函数的返回值,并总是返回 SOFTBUS_OK。这会掩盖动态库符号加载失败的情况,导致调用方误认为注册成功而在后续调用空指针引发崩溃。

移除对注册函数返回值的 (void) 强制转换,检查其返回值。如果任何注册函数失败,应返回相应的错误码而不是 SOFTBUS_OK。

likedislike
311+ (void)Register6thPartFunc(soHandle);
300 return SOFTBUS_OK;312 return SOFTBUS_OK;
301-}313+}
@@ -16,8 +16,8 @@
16 16 
17#include "auth_log.h"17#include "auth_log.h"
18#include "g_enhance_lnn_func.h"18#include "g_enhance_lnn_func.h"
19-#include "lnn_heartbeat_utils_struct.h"
20#include "lnn_heartbeat_medium_mgr.h"19#include "lnn_heartbeat_medium_mgr.h"
20+#include "lnn_heartbeat_utils_struct.h"
21#include "softbus_adapter_mem.h"21#include "softbus_adapter_mem.h"
22#include "softbus_error_code.h"22#include "softbus_error_code.h"
23#include "softbus_init_common.h"23#include "softbus_init_common.h"
@@ -1990,6 +1990,70 @@ int32_t RemoveLnnCloudEventPacked(LnnCloudMsgType event, LnnCloudRemoveCompareFu
1990 return pfnLnnEnhanceFuncList->removeLnnCloudEvent(event, func, param);1990 return pfnLnnEnhanceFuncList->removeLnnCloudEvent(event, func, param);
1991}1991}
1992 1992 
1993+int32_t PerceptionBuildAdvDataPacked(const PerceptionType *type, const PerceptionAdvParam *params,
1994+ uint32_t paramCnt, BroadcastPacket *packet)
1995+{
1996+ LnnEnhanceFuncList *funcList = LnnEnhanceFuncListGet();
1997+ if (funcList == NULL || LnnCheckFuncPointer((void *)funcList->perceptionBuildAdvData) != SOFTBUS_OK) {
1998+ return SOFTBUS_NOT_IMPLEMENT;
1999+ }
2000+ return funcList->perceptionBuildAdvData(type, params, paramCnt, packet);
2001+}
2002+ 
2003+int32_t PerceptionBuildScanFilterPacked(BcScanFilter **filter, uint8_t *filterNum)
2004+{
2005+ LnnEnhanceFuncList *funcList = LnnEnhanceFuncListGet();
2006+ if (funcList == NULL || LnnCheckFuncPointer((void *)funcList->perceptionBuildScanFilter) != SOFTBUS_OK) {
2007+ return SOFTBUS_NOT_IMPLEMENT;
2008+ }
2009+ return funcList->perceptionBuildScanFilter(filter, filterNum);
2010+}
2011+ 
2012+int32_t PerceptionGetDeviceInfoListPacked(PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
2013+{
2014+ LnnEnhanceFuncList *funcList = LnnEnhanceFuncListGet();
2015+ if (funcList == NULL || LnnCheckFuncPointer((void *)funcList->perceptionGetDeviceInfoList) != SOFTBUS_OK) {
2016+ return SOFTBUS_NOT_IMPLEMENT;
2017+ }
2018+ return funcList->perceptionGetDeviceInfoList(type, list, count);
2019+}
2020+ 
2021+int32_t PerceptionSyncStatePacked(PerceptionState state)
2022+{
2023+ LnnEnhanceFuncList *funcList = LnnEnhanceFuncListGet();
2024+ if (funcList == NULL || LnnCheckFuncPointer((void *)funcList->perceptionSyncState) != SOFTBUS_OK) {
2025+ return SOFTBUS_NOT_IMPLEMENT;
2026+ }
2027+ return funcList->perceptionSyncState(state);
2028+}
2029+ 
2030+int32_t PerceptionSyncCyclePacked(PerceptionType type, uint32_t cycle)
2031+{
2032+ LnnEnhanceFuncList *funcList = LnnEnhanceFuncListGet();
2033+ if (funcList == NULL || LnnCheckFuncPointer((void *)funcList->perceptionSyncCycle) != SOFTBUS_OK) {
2034+ return SOFTBUS_NOT_IMPLEMENT;
2035+ }
2036+ return funcList->perceptionSyncCycle(type, cycle);
2037+}
2038+ 
2039+int32_t PerceptionEnhanceInitPacked(void)
2040+{
2041+ LnnEnhanceFuncList *funcList = LnnEnhanceFuncListGet();
2042+ if (funcList == NULL || LnnCheckFuncPointer((void *)funcList->perceptionEnhanceInit) != SOFTBUS_OK) {
2043+ return SOFTBUS_NOT_IMPLEMENT;
2044+ }
2045+ return funcList->perceptionEnhanceInit();
2046+}
2047+ 
2048+void PerceptionEnhanceDeinitPacked(void)
2049+{
2050+ LnnEnhanceFuncList *funcList = LnnEnhanceFuncListGet();
2051+ if (funcList == NULL || LnnCheckFuncPointer((void *)funcList->perceptionEnhanceDeinit) != SOFTBUS_OK) {
2052+ return;
2053+ }
2054+ funcList->perceptionEnhanceDeinit();
2055+}
2056+ 
1993int32_t AuthMetaOpenConnWithOtherOsTypePacked(const AuthConnInfo *info, const char *networkId,2057int32_t AuthMetaOpenConnWithOtherOsTypePacked(const AuthConnInfo *info, const char *networkId,
1994 uint32_t requestId, const AuthConnCallback *callback)2058 uint32_t requestId, const AuthConnCallback *callback)
1995{2059{
@@ -104,7 +104,14 @@ private:
104 int32_t PostConversationDataInner(MessageParcel &data, MessageParcel &reply);104 int32_t PostConversationDataInner(MessageParcel &data, MessageParcel &reply);
105 int32_t RegisterConversationListenerInner(MessageParcel &data, MessageParcel &reply);105 int32_t RegisterConversationListenerInner(MessageParcel &data, MessageParcel &reply);
106 int32_t UnregisterConversationListenerInner(MessageParcel &data, MessageParcel &reply);106 int32_t UnregisterConversationListenerInner(MessageParcel &data, MessageParcel &reply);
107+ int32_t StartPerceptionAdvInner(MessageParcel &data, MessageParcel &reply);
108+ int32_t SetPerceptionAdvHighFreqInner(MessageParcel &data, MessageParcel &reply);
109+ int32_t StopPerceptionAdvInner(MessageParcel &data, MessageParcel &reply);
110+ int32_t StartPerceptionScanInner(MessageParcel &data, MessageParcel &reply);
111+ int32_t StopPerceptionScanInner(MessageParcel &data, MessageParcel &reply);
112+ int32_t GetPerceptionDeviceListInner(MessageParcel &data, MessageParcel &reply);
107 int32_t BasicPermissionVerify(uint32_t code);113 int32_t BasicPermissionVerify(uint32_t code);
114+ int32_t SysHapPermissionVerify(uint32_t code);
108 int32_t PermissionVerify(uint32_t code);115 int32_t PermissionVerify(uint32_t code);
109 int32_t CheckPermission(uint32_t code);116 int32_t CheckPermission(uint32_t code);
110 int32_t CheckAccountConstraint(uint32_t code);117 int32_t CheckAccountConstraint(uint32_t code);
@@ -121,4 +128,4 @@ private:
121};128};
122} // namespace OHOS129} // namespace OHOS
123 130 
124-#endif // SOFTBUS_SERVER_STUB_H_131+#endif // SOFTBUS_SERVER_STUB_H_
@@ -18,12 +18,13 @@
18#include "lnn_ohos_account_adapter.h"18#include "lnn_ohos_account_adapter.h"
19#include "securec.h"19#include "securec.h"
20 20 
21-#include "accesstoken_kit.h"
22#include "access_control.h"21#include "access_control.h"
23#include "access_token.h"22#include "access_token.h"
23+#include "accesstoken_kit.h"
24#include "br_proxy.h"24#include "br_proxy.h"
25#include "ipc_skeleton.h"25#include "ipc_skeleton.h"
26#include "legacy/softbus_hisysevt_transreporter.h"26#include "legacy/softbus_hisysevt_transreporter.h"
27+#include "lnn_bus_center_ipc.h"
27#include "softbus_access_token_adapter.h"28#include "softbus_access_token_adapter.h"
28#include "softbus_adapter_mem.h"29#include "softbus_adapter_mem.h"
29#include "softbus_agent_communication.h"30#include "softbus_agent_communication.h"
@@ -82,14 +83,15 @@ static const std::string CONSTRAINT = "constraint.distributed.transmission.outgo
82 } while (false) \83 } while (false) \
83 84 
84namespace OHOS {85namespace OHOS {
85- namespace {86+ 
86- constexpr int32_t MSG_MAX_SIZE = 1024 * 2;87+namespace {
87- constexpr int32_t DMS_CALLING_UID = 5522;88+constexpr int32_t MSG_MAX_SIZE = 1024 * 2;
88- static const char *DB_PACKAGE_NAME = "distributeddata-default";89+constexpr int32_t DMS_CALLING_UID = 5522;
89- static const char *DM_PACKAGE_NAME = "ohos.distributedhardware.devicemanager";90+static const char *DB_PACKAGE_NAME = "distributeddata-default";
90- static const char *MSDP_PACKAGE_NAME = "ohos.msdp.spatialawareness";91+static const char *DM_PACKAGE_NAME = "ohos.distributedhardware.devicemanager";
91- static const char *SHARE_PACKAGE_NAME = "ohos.InterConnection.iShare";92+static const char *MSDP_PACKAGE_NAME = "ohos.msdp.spatialawareness";
92- }93+static const char *SHARE_PACKAGE_NAME = "ohos.InterConnection.iShare";
94+} // namespace
93 95 
94int32_t SoftBusServerStub::CheckOpenSessionPermission(const SessionParam *param)96int32_t SoftBusServerStub::CheckOpenSessionPermission(const SessionParam *param)
95{97{
@@ -237,6 +239,12 @@ void SoftBusServerStub::InitMemberFuncMap()
237 memberFuncMap_[SERVER_POST_CONVERSATION_DATA] = &SoftBusServerStub::PostConversationDataInner;239 memberFuncMap_[SERVER_POST_CONVERSATION_DATA] = &SoftBusServerStub::PostConversationDataInner;
238 memberFuncMap_[SERVER_REGISTER_CONVERSATION_LISTENER] = &SoftBusServerStub::RegisterConversationListenerInner;240 memberFuncMap_[SERVER_REGISTER_CONVERSATION_LISTENER] = &SoftBusServerStub::RegisterConversationListenerInner;
239 memberFuncMap_[SERVER_UNREGISTER_CONVERSATION_LISTENER] = &SoftBusServerStub::UnregisterConversationListenerInner;241 memberFuncMap_[SERVER_UNREGISTER_CONVERSATION_LISTENER] = &SoftBusServerStub::UnregisterConversationListenerInner;
242+ memberFuncMap_[SERVER_START_PERCEPTION_ADV] = &SoftBusServerStub::StartPerceptionAdvInner;
243+ memberFuncMap_[SERVER_STOP_PERCEPTION_ADV] = &SoftBusServerStub::StopPerceptionAdvInner;
244+ memberFuncMap_[SERVER_START_PERCEPTION_SCAN] = &SoftBusServerStub::StartPerceptionScanInner;
245+ memberFuncMap_[SERVER_STOP_PERCEPTION_SCAN] = &SoftBusServerStub::StopPerceptionScanInner;
246+ memberFuncMap_[SERVER_GET_PERCEPTION_DEVICE_LIST] = &SoftBusServerStub::GetPerceptionDeviceListInner;
247+ memberFuncMap_[SERVER_SET_PERCEPTION_ADV_HIGH_FREQ] = &SoftBusServerStub::SetPerceptionAdvHighFreqInner;
xuhengxiang
xuhengxiangxuhengxiang9月17日

在函数 SetPerceptionAdvHighFreqInner 中,未检查 LnnIpcSetPerceptionAdvHighFreq 的返回值,可能导致未处理的错误。

在调用 LnnIpcSetPerceptionAdvHighFreq 后,应检查其返回值,并在返回值不正常时进行错误处理。

likedislike
240}248}
241 249 
242void SoftBusServerStub::InitMemberPermissionMap()250void SoftBusServerStub::InitMemberPermissionMap()
@@ -302,6 +310,12 @@ void SoftBusServerStub::InitMemberPermissionMap()
302 memberPermissionMap_[SERVER_START_ACCOUNT_AUTH] = OHOS_PERMISSION_DISTRIBUTED_DATASYNC;310 memberPermissionMap_[SERVER_START_ACCOUNT_AUTH] = OHOS_PERMISSION_DISTRIBUTED_DATASYNC;
303 memberPermissionMap_[SERVER_PROCESS_ACCOUNT_AUTH] = OHOS_PERMISSION_DISTRIBUTED_DATASYNC;311 memberPermissionMap_[SERVER_PROCESS_ACCOUNT_AUTH] = OHOS_PERMISSION_DISTRIBUTED_DATASYNC;
304 memberPermissionMap_[SERVER_PROCESS_PUSH_MSG] = OHOS_PERMISSION_DISTRIBUTED_DATASYNC;312 memberPermissionMap_[SERVER_PROCESS_PUSH_MSG] = OHOS_PERMISSION_DISTRIBUTED_DATASYNC;
313+ memberPermissionMap_[SERVER_START_PERCEPTION_ADV] = OHOS_PERMISSION_ACCESS_SOFTBUS_SYS_HAP;
314+ memberPermissionMap_[SERVER_STOP_PERCEPTION_ADV] = OHOS_PERMISSION_ACCESS_SOFTBUS_SYS_HAP;
315+ memberPermissionMap_[SERVER_SET_PERCEPTION_ADV_HIGH_FREQ] = OHOS_PERMISSION_ACCESS_SOFTBUS_SYS_HAP;
316+ memberPermissionMap_[SERVER_START_PERCEPTION_SCAN] = OHOS_PERMISSION_ACCESS_SOFTBUS_SYS_HAP;
317+ memberPermissionMap_[SERVER_STOP_PERCEPTION_SCAN] = OHOS_PERMISSION_ACCESS_SOFTBUS_SYS_HAP;
318+ memberPermissionMap_[SERVER_GET_PERCEPTION_DEVICE_LIST] = OHOS_PERMISSION_ACCESS_SOFTBUS_SYS_HAP;
305}319}
306 320 
307void SoftBusServerStub::InitMemberConstraintSet()321void SoftBusServerStub::InitMemberConstraintSet()
@@ -2906,6 +2920,198 @@ int32_t SoftBusServerStub::UnregisterConversationListenerInner(MessageParcel &da
2906 return SOFTBUS_OK;2920 return SOFTBUS_OK;
2907}2921}
2908 2922 
2923+static int32_t ReadPerceptionRequestHeader(MessageParcel &data, const char **pkgName, PerceptionType *type)
2924+{
2925+ *pkgName = data.ReadCString();
2926+ int32_t rawType = PERCEPTION_TYPE_BUTT;
2927+ if ((*pkgName == nullptr) ||
2928+ (strnlen(*pkgName, PKG_NAME_SIZE_MAX) > (PKG_NAME_SIZE_MAX - 1)) ||
2929+ (!data.ReadInt32(rawType)) ||
2930+ (rawType < PERCEPTION_TYPE_COLLABORATIVE_WAKE) ||
2931+ (rawType >= PERCEPTION_TYPE_BUTT)) {
2932+ COMM_LOGE(COMM_SVC, "read perception request header failed, invalid pkgName or type, rawType=%{public}d",
2933+ rawType);
2934+ return SOFTBUS_INVALID_PARAM;
2935+ }
2936+ *type = (PerceptionType)rawType;
2937+ return SOFTBUS_OK;
2938+}
2939+ 
2940+int32_t SoftBusServerStub::StartPerceptionAdvInner(MessageParcel &data, MessageParcel &reply)
2941+{
2942+ int32_t permRet = SysHapPermissionVerify(SERVER_START_PERCEPTION_ADV);
2943+ if (permRet != SOFTBUS_OK) {
2944+ COMM_LOGE(COMM_SVC, "permission verification failed");
2945+ return permRet;
2946+ }
2947+ const char *pkgName = nullptr;
2948+ PerceptionType type = PERCEPTION_TYPE_BUTT;
2949+ int32_t ret = ReadPerceptionRequestHeader(data, &pkgName, &type);
2950+ if (ret != SOFTBUS_OK) {
2951+ return ret;
2952+ }
2953+ const void *raw = data.ReadRawData(sizeof(PerceptionAdvParam));
2954+ PerceptionAdvParam received {};
2955+ if (raw == nullptr || memcpy_s(&received, sizeof(received), raw, sizeof(received)) != EOK) {
2956+ COMM_LOGE(COMM_SVC, "read perception adv rawData failed or memcpy fail");
2957+ return SOFTBUS_IPC_ERR;
2958+ }
2959+ if (received.customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
2960+ COMM_LOGE(COMM_SVC, "invalid perception customDataLen=%{public}u", received.customDataLen);
2961+ return SOFTBUS_INVALID_PARAM;
2962+ }
2963+ int32_t serverRet = LnnIpcStartPerceptionAdv(pkgName, type, &received);
2964+ if (!reply.WriteInt32(serverRet)) {
2965+ COMM_LOGE(COMM_SVC, "write reply failed!");
2966+ return SOFTBUS_IPC_ERR;
2967+ }
2968+ return SOFTBUS_OK;
2969+}
2970+ 
2971+int32_t SoftBusServerStub::SetPerceptionAdvHighFreqInner(MessageParcel &data, MessageParcel &reply)
2972+{
2973+ int32_t permRet = SysHapPermissionVerify(SERVER_SET_PERCEPTION_ADV_HIGH_FREQ);
2974+ if (permRet != SOFTBUS_OK) {
2975+ COMM_LOGE(COMM_SVC, "permission verification failed");
2976+ return permRet;
2977+ }
2978+ const char *pkgName = nullptr;
2979+ PerceptionType type = PERCEPTION_TYPE_BUTT;
2980+ int32_t ret = ReadPerceptionRequestHeader(data, &pkgName, &type);
2981+ if (ret != SOFTBUS_OK) {
2982+ return ret;
2983+ }
2984+ const void *raw = data.ReadRawData(sizeof(PerceptionAdvParam));
2985+ PerceptionAdvParam received {};
2986+ if (raw == nullptr || memcpy_s(&received, sizeof(received), raw, sizeof(received)) != EOK) {
2987+ COMM_LOGE(COMM_SVC, "read perception adv rawData failed or memcpy fail");
2988+ return SOFTBUS_IPC_ERR;
2989+ }
2990+ if (received.customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
2991+ COMM_LOGE(COMM_SVC, "invalid perception customDataLen=%{public}u", received.customDataLen);
2992+ return SOFTBUS_INVALID_PARAM;
2993+ }
2994+ int32_t serverRet = LnnIpcSetPerceptionAdvHighFreq(pkgName, type, &received);
2995+ if (!reply.WriteInt32(serverRet)) {
2996+ COMM_LOGE(COMM_SVC, "write reply failed!");
2997+ return SOFTBUS_IPC_ERR;
2998+ }
2999+ return SOFTBUS_OK;
3000+}
3001+ 
3002+int32_t SoftBusServerStub::StopPerceptionAdvInner(MessageParcel &data, MessageParcel &reply)
3003+{
3004+ int32_t permRet = SysHapPermissionVerify(SERVER_STOP_PERCEPTION_ADV);
3005+ if (permRet != SOFTBUS_OK) {
3006+ COMM_LOGE(COMM_SVC, "permission verification failed");
3007+ return permRet;
3008+ }
3009+ const char *pkgName = nullptr;
3010+ PerceptionType type = PERCEPTION_TYPE_BUTT;
3011+ int32_t ret = ReadPerceptionRequestHeader(data, &pkgName, &type);
3012+ if (ret != SOFTBUS_OK) {
3013+ return ret;
3014+ }
3015+ int32_t serverRet = LnnIpcStopPerceptionAdv(pkgName, type);
3016+ if (!reply.WriteInt32(serverRet)) {
3017+ COMM_LOGE(COMM_SVC, "write reply failed!");
3018+ return SOFTBUS_IPC_ERR;
3019+ }
3020+ return SOFTBUS_OK;
3021+}
3022+ 
3023+int32_t SoftBusServerStub::StartPerceptionScanInner(MessageParcel &data, MessageParcel &reply)
3024+{
3025+ int32_t permRet = SysHapPermissionVerify(SERVER_START_PERCEPTION_SCAN);
3026+ if (permRet != SOFTBUS_OK) {
3027+ COMM_LOGE(COMM_SVC, "permission verification failed");
3028+ return permRet;
3029+ }
3030+ const char *pkgName = nullptr;
3031+ PerceptionType type = PERCEPTION_TYPE_BUTT;
3032+ int32_t ret = ReadPerceptionRequestHeader(data, &pkgName, &type);
3033+ if (ret != SOFTBUS_OK) {
3034+ return ret;
3035+ }
3036+ int32_t rawCycle = PERCEPTION_CYCLE_LOW;
3037+ if (!data.ReadInt32(rawCycle) || rawCycle < PERCEPTION_CYCLE_LOW || rawCycle >= PERCEPTION_CYCLE_BUTT) {
3038+ COMM_LOGE(COMM_SVC, "read perception cycle failed, rawCycle=%{public}d", rawCycle);
3039+ return SOFTBUS_INVALID_PARAM;
3040+ }
3041+ int32_t serverRet = LnnIpcStartPerceptionScan(pkgName, type, (PerceptionCycle)rawCycle);
3042+ if (!reply.WriteInt32(serverRet)) {
3043+ COMM_LOGE(COMM_SVC, "write reply failed!");
3044+ return SOFTBUS_IPC_ERR;
3045+ }
3046+ return SOFTBUS_OK;
3047+}
3048+ 
3049+int32_t SoftBusServerStub::StopPerceptionScanInner(MessageParcel &data, MessageParcel &reply)
3050+{
3051+ int32_t permRet = SysHapPermissionVerify(SERVER_STOP_PERCEPTION_SCAN);
3052+ if (permRet != SOFTBUS_OK) {
3053+ COMM_LOGE(COMM_SVC, "permission verification failed");
3054+ return permRet;
3055+ }
3056+ const char *pkgName = nullptr;
3057+ PerceptionType type = PERCEPTION_TYPE_BUTT;
3058+ int32_t ret = ReadPerceptionRequestHeader(data, &pkgName, &type);
3059+ if (ret != SOFTBUS_OK) {
3060+ return ret;
3061+ }
3062+ int32_t serverRet = LnnIpcStopPerceptionScan(pkgName, type);
3063+ if (!reply.WriteInt32(serverRet)) {
3064+ COMM_LOGE(COMM_SVC, "write reply failed!");
3065+ return SOFTBUS_IPC_ERR;
3066+ }
3067+ return SOFTBUS_OK;
3068+}
3069+ 
3070+int32_t SoftBusServerStub::GetPerceptionDeviceListInner(MessageParcel &data, MessageParcel &reply)
3071+{
3072+ int32_t permRet = SysHapPermissionVerify(SERVER_GET_PERCEPTION_DEVICE_LIST);
3073+ if (permRet != SOFTBUS_OK) {
3074+ COMM_LOGE(COMM_SVC, "permission verification failed");
3075+ return permRet;
3076+ }
3077+ const char *pkgName = nullptr;
3078+ PerceptionType type = PERCEPTION_TYPE_BUTT;
3079+ int32_t ret = ReadPerceptionRequestHeader(data, &pkgName, &type);
3080+ if (ret != SOFTBUS_OK) {
3081+ return ret;
3082+ }
3083+ PerceptionDeviceInfo *list = nullptr;
3084+ uint32_t count = 0;
3085+ ret = LnnIpcGetPerceptionDeviceList(pkgName, type, &list, &count);
3086+ if (ret == SOFTBUS_OK && count > PERCEPTION_MAX_DEVICE_NUM) {
3087+ COMM_LOGE(COMM_SVC, "perception device count invalid, count=%{public}u", count);
3088+ ret = SOFTBUS_IPC_ERR;
3089+ count = 0;
3090+ }
3091+ if (ret == SOFTBUS_OK) {
3092+ for (uint32_t i = 0; i < count; ++i) {
3093+ if (list[i].customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
3094+ COMM_LOGE(COMM_SVC, "perception device customDataLen invalid, index=%{public}u", i);
3095+ ret = SOFTBUS_INVALID_PARAM;
3096+ count = 0;
3097+ break;
3098+ }
3099+ }
3100+ }
3101+ if (!reply.WriteInt32(ret) || !reply.WriteUint32(count)) {
3102+ COMM_LOGE(COMM_SVC, "write reply failed!");
3103+ SoftBusFree(list);
3104+ return SOFTBUS_IPC_ERR;
3105+ }
3106+ if (ret == SOFTBUS_OK && count > 0 && !reply.WriteRawData(list, count * sizeof(PerceptionDeviceInfo))) {
3107+ COMM_LOGE(COMM_SVC, "write reply rawData failed!");
3108+ SoftBusFree(list);
3109+ return SOFTBUS_IPC_ERR;
3110+ }
3111+ SoftBusFree(list);
3112+ return SOFTBUS_OK;
3113+}
3114+ 
2909static std::map<uint32_t, std::string> tagNameMap = {3115static std::map<uint32_t, std::string> tagNameMap = {
2910 { SERVER_JOIN_LNN, SERVER_JOIN_LNN_NAME },3116 { SERVER_JOIN_LNN, SERVER_JOIN_LNN_NAME },
2911 { SERVER_LEAVE_LNN, SERVER_LEAVE_LNN_NAME },3117 { SERVER_LEAVE_LNN, SERVER_LEAVE_LNN_NAME },
@@ -2988,4 +3194,17 @@ int32_t SoftBusServerStub::BasicPermissionVerify(uint32_t code)
2988 }3194 }
2989 return SOFTBUS_OK;3195 return SOFTBUS_OK;
2990}3196}
3197+ 
3198+int32_t SoftBusServerStub::SysHapPermissionVerify(uint32_t code)
3199+{
3200+ (void)code;
3201+ uint64_t callingFullTokenId = IPCSkeleton::GetCallingFullTokenID();
3202+ bool support = OHOS::system::GetBoolParameter("persist.sys.softbus.check.system.app", true);
3203+ if (support && !OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callingFullTokenId)) {
3204+ COMM_LOGE(COMM_SVC, "permission denied, is not system app, check=%{public}s",
3205+ support ? "true" : "false");
3206+ return SOFTBUS_PERMISSION_DENIED;
3207+ }
3208+ return SOFTBUS_OK;
3209+}
2991} // namespace OHOS3210} // namespace OHOS
@@ -0,0 +1,75 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+#ifndef LNN_PERCEPTION_H
17+#define LNN_PERCEPTION_H
18+ 
19+#include <stdint.h>
20+ 
21+#include "softbus_broadcast_type_struct.h"
22+ 
23+#ifdef __cplusplus
24+extern "C" {
25+#endif
26+ 
27+#define PERCEPTION_MAX_DEVICE_NUM 30
28+ 
29+/** @brief Defines the supported perception service types. */
30+typedef enum {
31+ PERCEPTION_TYPE_COLLABORATIVE_WAKE = 0,
32+ PERCEPTION_TYPE_BUTT,
33+} PerceptionType;
34+ 
35+/** @brief Defines the custom payload used to start or update perception advertising. */
36+typedef struct {
37+ uint8_t customData[PERCEPTION_CUSTOM_DATA_MAX_LEN];
38+ uint32_t customDataLen;
39+} PerceptionAdvParam;
40+ 
41+/** @brief Defines the perception scan keepalive cycle. */
42+typedef enum {
43+ PERCEPTION_CYCLE_LOW = 0, /**< Low cycle, keepalive 30s. */
44+ PERCEPTION_CYCLE_MEDIUM, /**< Medium cycle, keepalive 75s. */
45+ PERCEPTION_CYCLE_HIGH, /**< High cycle, keepalive 150s. */
46+ PERCEPTION_CYCLE_BUTT,
47+} PerceptionCycle;
48+ 
49+/** @brief Starts perception advertising or updates its custom payload for the current owner. */
50+int32_t StartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
51+ 
52+/** @brief Switches an active perception advertiser to high frequency for ten seconds and updates its custom payload. */
53+int32_t SetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
54+ 
55+/** @brief Stops perception advertising for the current owner. */
56+int32_t StopPerceptionAdv(const char *pkgName, PerceptionType type);
57+ 
58+/** @brief Starts perception scanning for the current owner with specified keepalive cycle. */
59+int32_t StartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle);
60+ 
61+/** @brief Stops perception scanning and clears its device list. */
62+int32_t StopPerceptionScan(const char *pkgName, PerceptionType type);
63+ 
64+/** @brief Returns a snapshot of devices discovered by perception scanning. The list is dynamically
65+ * allocated by softbus and must be released by FreePerceptionDeviceList. */
66+int32_t GetPerceptionDeviceList(
67+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count);
68+ 
69+/** @brief Releases the device list returned by GetPerceptionDeviceList. */
70+void FreePerceptionDeviceList(PerceptionDeviceInfo *list);
71+ 
72+#ifdef __cplusplus
73+}
74+#endif
75+#endif // LNN_PERCEPTION_H
@@ -85,6 +85,11 @@ extern "C"{
85 */85 */
86#define BC_LOCAL_NAME_LEN_MAX 3086#define BC_LOCAL_NAME_LEN_MAX 30
87 87 
88+/** Maximum length of custom data carried by a perception broadcast. */
89+#define PERCEPTION_CUSTOM_DATA_MAX_LEN 5
90+/** Fixed length of a perception device identifier. */
91+#define PERCEPTION_DEVICE_ID_LEN 6
92+ 
88/**93/**
89 * @brief Defines the broadcast protocol.94 * @brief Defines the broadcast protocol.
90 *95 *
@@ -123,9 +128,30 @@ typedef enum {
123 SRV_TYPE_SD, // The service type is service discovery.128 SRV_TYPE_SD, // The service type is service discovery.
124 SRV_TYPE_COLLABORATION, // The service type is pc collaboration.129 SRV_TYPE_COLLABORATION, // The service type is pc collaboration.
125 SRV_TYPE_RAW,130 SRV_TYPE_RAW,
xuhengxiang
xuhengxiangxuhengxiang9月17日

数组 deviceId 的长度为 6,但未指定如何处理超出 6 个字节的输入。

检查并确保 deviceId 数组不会接收超过 6 个字节的输入,或者对输入进行适当的截断或错误处理。

likedislike
131+ SRV_TYPE_PERCEPTION,
126 SRV_TYPE_BUTT,132 SRV_TYPE_BUTT,
127} BaseServiceType;133} BaseServiceType;
128 134 
135+/** @brief Defines the perception scan state synced to the closed-source implementation. */
xuhengxiang
xuhengxiangxuhengxiang9月17日

未初始化的枚举值 PERCEPTION_SCAN_STATE_BUTT 可能导致未定义行为。

确保所有枚举值在定义时都有对应的初始化值,或者使用枚举值定义的默认值。

likedislike
136+typedef enum {
137+ PERCEPTION_STATE_START = 1,
138+ PERCEPTION_STATE_STOP,
139+ PERCEPTION_STATE_BUTT,
140+} PerceptionState;
xuhengxiang
xuhengxiangxuhengxiang9月17日
已过期

结构体 PerceptionDeviceInfo 中的 customDataLen 字段未指定如何处理超出 customData 长度的数据。

确保 customDataLen 字段不会超出 customData 的实际长度,或者对数据进行适当的截断或错误处理。

likedislike
141+ 
142+/**
143+ * @brief Defines device information parsed from a perception scan result.
144+ *
145+ * @since 6.0
146+ * @version 1.0
147+ */
148+typedef struct {
149+ uint16_t deviceType;
150+ uint8_t deviceId[PERCEPTION_DEVICE_ID_LEN];
151+ uint8_t customData[PERCEPTION_CUSTOM_DATA_MAX_LEN];
152+ uint32_t customDataLen;
153+} PerceptionDeviceInfo;
154+ 
129/**155/**
130 * @brief Defines the mapping between supported service types and their names.156 * @brief Defines the mapping between supported service types and their names.
131 *157 *
@@ -166,6 +192,8 @@ static const SrvTypeMap g_srvTypeMap[] = {
166 {SRV_TYPE_D2D_GROUP_TALKIE, (char *)"d2dG"},192 {SRV_TYPE_D2D_GROUP_TALKIE, (char *)"d2dG"},
167 {SRV_TYPE_SD, (char *)"serviceDisc"},193 {SRV_TYPE_SD, (char *)"serviceDisc"},
168 {SRV_TYPE_COLLABORATION, (char *)"pcCollab"},194 {SRV_TYPE_COLLABORATION, (char *)"pcCollab"},
195+ {SRV_TYPE_RAW, (char *)"raw"},
196+ {SRV_TYPE_PERCEPTION, (char *)"perception"},
169};197};
170 198 
171/**199/**
@@ -178,6 +206,7 @@ typedef enum {
178 SOFTBUS_HEARTBEAT_TYPE = 0,206 SOFTBUS_HEARTBEAT_TYPE = 0,
179 SOFTBUS_BURST_TYPE,207 SOFTBUS_BURST_TYPE,
180 SOFTBUS_VIRTUAL_SCAN_TYPE,208 SOFTBUS_VIRTUAL_SCAN_TYPE,
209+ SOFTBUS_PERCEPTION_TYPE,
181 SOFTBUS_UNKNOW_TYPE,210 SOFTBUS_UNKNOW_TYPE,
182} LpServerType;211} LpServerType;
183 212 
@@ -50,6 +50,7 @@ typedef enum {
50 BC_TYPE_SD,50 BC_TYPE_SD,
51 BC_TYPE_PC_COLLABORATION,51 BC_TYPE_PC_COLLABORATION,
52 BC_TYPE_RAW_BLE_DIRECT,52 BC_TYPE_RAW_BLE_DIRECT,
53+ BC_TYPE_PERCEPTION,
53 BC_TYPE_SCHEDULER_BUTT,54 BC_TYPE_SCHEDULER_BUTT,
54} BroadcastContentType;55} BroadcastContentType;
55 56 
@@ -65,6 +65,7 @@ extern "C" {
65#define OHOS_PERMISSION_SEC_ACCESS_UDID "ohos.permission.sec.ACCESS_UDID"65#define OHOS_PERMISSION_SEC_ACCESS_UDID "ohos.permission.sec.ACCESS_UDID"
66#define OHOS_PERMISSION_ACCESS_SERVICE_DM "ohos.permission.ACCESS_SERVICE_DM"66#define OHOS_PERMISSION_ACCESS_SERVICE_DM "ohos.permission.ACCESS_SERVICE_DM"
67#define OHOS_PERMISSION_SOFTBUS_MANAGER_RESOURCE "ohos.permission.SOFTBUS_MANAGER_RESOURCE"67#define OHOS_PERMISSION_SOFTBUS_MANAGER_RESOURCE "ohos.permission.SOFTBUS_MANAGER_RESOURCE"
68+#define OHOS_PERMISSION_ACCESS_SOFTBUS_SYS_HAP "ohos.permission.ACCESS_SOFTBUS_SYS_HAP"
68 69 
69/**70/**
70 * @brief Indicates the length of the Bluetooth device MAC address in string format,71 * @brief Indicates the length of the Bluetooth device MAC address in string format,
@@ -991,6 +991,7 @@ enum SoftBusErrNo {
991 SOFTBUS_SLE_RANGING_NOT_SUPPORT_ERROR,991 SOFTBUS_SLE_RANGING_NOT_SUPPORT_ERROR,
992 SOFTBUS_SLE_RANGING_CONNECT_ERROR,992 SOFTBUS_SLE_RANGING_CONNECT_ERROR,
993 SOFTBUS_SLE_RANGING_TRANS_ERROR,993 SOFTBUS_SLE_RANGING_TRANS_ERROR,
994+ SOFTBUS_PERCEPTION_SCAN_NOT_START,
994 SOFTBUS_NETWORK_USB_GETMAC_FAILED,995 SOFTBUS_NETWORK_USB_GETMAC_FAILED,
995 SOFTBUS_NETWORK_USB_MODE_INVALID,996 SOFTBUS_NETWORK_USB_MODE_INVALID,
996 SOFTBUS_NETWORK_CONFIG_NETLINK_IPV6_FAILED,997 SOFTBUS_NETWORK_CONFIG_NETLINK_IPV6_FAILED,
@@ -63,6 +63,7 @@ config("dsoftbus_sdk_interface") {
63 "$dsoftbus_dfx_path/interface/include",63 "$dsoftbus_dfx_path/interface/include",
64 "$dsoftbus_root_path/interfaces/kits",64 "$dsoftbus_root_path/interfaces/kits",
65 "$dsoftbus_root_path/interfaces/inner_kits/lnn",65 "$dsoftbus_root_path/interfaces/inner_kits/lnn",
66+ "$dsoftbus_root_path/interfaces/kits/adapter",
66 "$dsoftbus_root_path/interfaces/kits/bus_center",67 "$dsoftbus_root_path/interfaces/kits/bus_center",
67 "$dsoftbus_root_path/interfaces/kits/common",68 "$dsoftbus_root_path/interfaces/kits/common",
68 "$dsoftbus_root_path/interfaces/kits/discovery",69 "$dsoftbus_root_path/interfaces/kits/discovery",
@@ -24,13 +24,17 @@ if (!defined(ohos_lite)) {
24}24}
25bus_center_service_sdk_inc = [25bus_center_service_sdk_inc = [
26 "$dsoftbus_root_path/sdk/bus_center/service/include",26 "$dsoftbus_root_path/sdk/bus_center/service/include",
27+ "$dsoftbus_root_path/interfaces/inner_kits/lnn",
27 "$dsoftbus_dfx_path/interface/include",28 "$dsoftbus_dfx_path/interface/include",
28 "$dsoftbus_root_path/core/frame/common/include",29 "$dsoftbus_root_path/core/frame/common/include",
29]30]
30 31 
31bus_center_manager_sdk_src = []32bus_center_manager_sdk_src = []
32-bus_center_manager_sdk_inc =33+bus_center_manager_sdk_inc = [
33- [ "$dsoftbus_root_path/sdk/bus_center/manager/include" ]34+ "$dsoftbus_root_path/sdk/bus_center/manager/include",
35+ "$dsoftbus_root_path/interfaces/inner_kits/lnn",
36+ "$dsoftbus_root_path/interfaces/kits/adapter",
37+]
34bus_center_manager_sdk_deps = []38bus_center_manager_sdk_deps = []
35if (defined(ohos_lite)) {39if (defined(ohos_lite)) {
36 if (ohos_kernel_type == "liteos_m") {40 if (ohos_kernel_type == "liteos_m") {
@@ -20,6 +20,7 @@
20 20 
21#include "ble_range.h"21#include "ble_range.h"
22#include "data_level.h"22#include "data_level.h"
23+#include "lnn_perception.h"
23#include "softbus_agent_communication.h"24#include "softbus_agent_communication.h"
24#include "softbus_bus_center.h"25#include "softbus_bus_center.h"
25 26 
@@ -71,6 +72,13 @@ int32_t ServerIpcPostConversationData(const char *deviceId, const ConversationBu
71int32_t ServerIpcRegisterConversationListener(const ConversationBusiness *info);72int32_t ServerIpcRegisterConversationListener(const ConversationBusiness *info);
72int32_t ServerIpcUnregisterConversationListener(const ConversationBusiness *info);73int32_t ServerIpcUnregisterConversationListener(const ConversationBusiness *info);
73int32_t ServerIpcGetTrustedDevices(DeviceNodeInfo **info, int32_t *nums);74int32_t ServerIpcGetTrustedDevices(DeviceNodeInfo **info, int32_t *nums);
75+int32_t ServerIpcStartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
76+int32_t ServerIpcSetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
77+int32_t ServerIpcStopPerceptionAdv(const char *pkgName, PerceptionType type);
78+int32_t ServerIpcStartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle);
79+int32_t ServerIpcStopPerceptionScan(const char *pkgName, PerceptionType type);
80+int32_t ServerIpcGetPerceptionDeviceList(
81+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count);
74 82 
75#ifdef __cplusplus83#ifdef __cplusplus
76#if __cplusplus84#if __cplusplus
@@ -248,4 +248,54 @@ int32_t ServerIpcGetTrustedDevices(DeviceNodeInfo **info, int32_t *nums)
248 (void)info;248 (void)info;
249 (void)nums;249 (void)nums;
250 return SOFTBUS_FUNC_NOT_SUPPORT;250 return SOFTBUS_FUNC_NOT_SUPPORT;
251-}251+}
252+ 
253+int32_t ServerIpcStartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
254+{
255+ (void)pkgName;
256+ (void)type;
257+ (void)param;
258+ return SOFTBUS_FUNC_NOT_SUPPORT;
259+}
260+ 
261+int32_t ServerIpcSetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
262+{
263+ (void)pkgName;
264+ (void)type;
265+ (void)param;
266+ return SOFTBUS_FUNC_NOT_SUPPORT;
267+}
268+ 
269+int32_t ServerIpcStopPerceptionAdv(const char *pkgName, PerceptionType type)
270+{
271+ (void)pkgName;
272+ (void)type;
273+ return SOFTBUS_FUNC_NOT_SUPPORT;
274+}
275+ 
276+int32_t ServerIpcStartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle)
277+{
278+ (void)pkgName;
279+ (void)type;
280+ (void)cycle;
281+ return SOFTBUS_FUNC_NOT_SUPPORT;
282+}
283+ 
284+int32_t ServerIpcStopPerceptionScan(const char *pkgName, PerceptionType type)
285+{
286+ (void)pkgName;
287+ (void)type;
288+ return SOFTBUS_FUNC_NOT_SUPPORT;
289+}
290+ 
291+int32_t ServerIpcGetPerceptionDeviceList(
292+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
293+{
294+ (void)pkgName;
295+ (void)type;
296+ (void)list;
297+ if (count != NULL) {
298+ *count = 0;
299+ }
300+ return SOFTBUS_FUNC_NOT_SUPPORT;
301+}
@@ -974,4 +974,54 @@ int32_t ServerIpcGetTrustedDevices(DeviceNodeInfo **info, int32_t *nums)
974 (void)info;974 (void)info;
975 (void)nums;975 (void)nums;
976 return SOFTBUS_FUNC_NOT_SUPPORT;976 return SOFTBUS_FUNC_NOT_SUPPORT;
977-}977+}
978+ 
979+int32_t ServerIpcStartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
980+{
981+ (void)pkgName;
982+ (void)type;
983+ (void)param;
984+ return SOFTBUS_FUNC_NOT_SUPPORT;
985+}
986+ 
987+int32_t ServerIpcSetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
988+{
989+ (void)pkgName;
990+ (void)type;
991+ (void)param;
992+ return SOFTBUS_FUNC_NOT_SUPPORT;
993+}
994+ 
995+int32_t ServerIpcStopPerceptionAdv(const char *pkgName, PerceptionType type)
996+{
997+ (void)pkgName;
998+ (void)type;
999+ return SOFTBUS_FUNC_NOT_SUPPORT;
1000+}
1001+ 
1002+int32_t ServerIpcStartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle)
1003+{
1004+ (void)pkgName;
1005+ (void)type;
1006+ (void)cycle;
1007+ return SOFTBUS_FUNC_NOT_SUPPORT;
1008+}
1009+ 
1010+int32_t ServerIpcStopPerceptionScan(const char *pkgName, PerceptionType type)
1011+{
1012+ (void)pkgName;
1013+ (void)type;
1014+ return SOFTBUS_FUNC_NOT_SUPPORT;
1015+}
1016+ 
1017+int32_t ServerIpcGetPerceptionDeviceList(
1018+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
1019+{
1020+ (void)pkgName;
1021+ (void)type;
1022+ (void)list;
1023+ if (count != NULL) {
1024+ *count = 0;
1025+ }
1026+ return SOFTBUS_FUNC_NOT_SUPPORT;
1027+}
@@ -18,6 +18,7 @@
18#define INTERFACES_INNERKITS_BUS_CENTER_SERVER_PROXY_STANDARD_H_18#define INTERFACES_INNERKITS_BUS_CENTER_SERVER_PROXY_STANDARD_H_
19 19 
20#include "if_softbus_server.h"20#include "if_softbus_server.h"
21+#include "lnn_perception.h"
21 22 
22namespace OHOS {23namespace OHOS {
23class BusCenterServerProxy : public IRemoteProxy<ISoftBusServer> {24class BusCenterServerProxy : public IRemoteProxy<ISoftBusServer> {
@@ -92,10 +93,17 @@ public:
92 int32_t RegisterConversationListener(const ConversationBusiness *info) override;93 int32_t RegisterConversationListener(const ConversationBusiness *info) override;
93 int32_t UnregisterConversationListener(const ConversationBusiness *info) override;94 int32_t UnregisterConversationListener(const ConversationBusiness *info) override;
94 int32_t GetTrustedDevices(DeviceNodeInfo **info, int32_t *nums) override;95 int32_t GetTrustedDevices(DeviceNodeInfo **info, int32_t *nums) override;
96+ int32_t StartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
97+ int32_t SetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
98+ int32_t StopPerceptionAdv(const char *pkgName, PerceptionType type);
99+ int32_t StartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle);
100+ int32_t StopPerceptionScan(const char *pkgName, PerceptionType type);
101+ int32_t GetPerceptionDeviceList(
102+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count);
95 103 
96private:104private:
97 static inline BrokerDelegator<BusCenterServerProxy> delegator_;105 static inline BrokerDelegator<BusCenterServerProxy> delegator_;
98};106};
99} // namespace OHOS107} // namespace OHOS
100 108 
101-#endif // !defined(INTERFACES_INNERKITS_BUS_CENTER_SERVER_PROXY_STANDARD_H_)109+#endif // !defined(INTERFACES_INNERKITS_BUS_CENTER_SERVER_PROXY_STANDARD_H_)
@@ -16,14 +16,13 @@
16#include "bus_center_server_proxy.h"16#include "bus_center_server_proxy.h"
17#include "bus_center_server_proxy_standard.h"17#include "bus_center_server_proxy_standard.h"
18 18 
19-#include <mutex>
20#include "comm_log.h"19#include "comm_log.h"
21#include "g_enhance_sdk_func.h"20#include "g_enhance_sdk_func.h"
22#include "ipc_skeleton.h"21#include "ipc_skeleton.h"
23#include "lnn_log.h"22#include "lnn_log.h"
24#include "softbus_error_code.h"23#include "softbus_error_code.h"
25#include "softbus_server_ipc_interface_code.h"24#include "softbus_server_ipc_interface_code.h"
26-#include "g_enhance_sdk_func.h"25+#include <mutex>
27 26 
28using namespace OHOS;27using namespace OHOS;
29 28 
@@ -453,4 +452,47 @@ int32_t ServerIpcGetTrustedDevices(DeviceNodeInfo **info, int32_t *nums)
453 LNN_EVENT, "server not init");452 LNN_EVENT, "server not init");
454 int32_t ret = g_serverProxy->GetTrustedDevices(info, nums);453 int32_t ret = g_serverProxy->GetTrustedDevices(info, nums);
455 return ret;454 return ret;
456-}455+}
456+ 
457+int32_t ServerIpcStartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
458+{
459+ LNN_CHECK_AND_RETURN_RET_LOGE(
460+ CheckAndInitBusCenterServerProxyInit() == SOFTBUS_OK, SOFTBUS_SERVER_NOT_INIT, LNN_EVENT, "server not init");
461+ return g_serverProxy->StartPerceptionAdv(pkgName, type, param);
462+}
463+ 
464+int32_t ServerIpcSetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
465+{
466+ LNN_CHECK_AND_RETURN_RET_LOGE(
467+ CheckAndInitBusCenterServerProxyInit() == SOFTBUS_OK, SOFTBUS_SERVER_NOT_INIT, LNN_EVENT, "server not init");
468+ return g_serverProxy->SetPerceptionAdvHighFreq(pkgName, type, param);
469+}
470+ 
471+int32_t ServerIpcStopPerceptionAdv(const char *pkgName, PerceptionType type)
472+{
473+ LNN_CHECK_AND_RETURN_RET_LOGE(
474+ CheckAndInitBusCenterServerProxyInit() == SOFTBUS_OK, SOFTBUS_SERVER_NOT_INIT, LNN_EVENT, "server not init");
475+ return g_serverProxy->StopPerceptionAdv(pkgName, type);
476+}
477+ 
478+int32_t ServerIpcStartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle)
479+{
480+ LNN_CHECK_AND_RETURN_RET_LOGE(
481+ CheckAndInitBusCenterServerProxyInit() == SOFTBUS_OK, SOFTBUS_SERVER_NOT_INIT, LNN_EVENT, "server not init");
482+ return g_serverProxy->StartPerceptionScan(pkgName, type, cycle);
483+}
484+ 
485+int32_t ServerIpcStopPerceptionScan(const char *pkgName, PerceptionType type)
486+{
487+ LNN_CHECK_AND_RETURN_RET_LOGE(
488+ CheckAndInitBusCenterServerProxyInit() == SOFTBUS_OK, SOFTBUS_SERVER_NOT_INIT, LNN_EVENT, "server not init");
489+ return g_serverProxy->StopPerceptionScan(pkgName, type);
490+}
491+ 
492+int32_t ServerIpcGetPerceptionDeviceList(
493+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
494+{
495+ LNN_CHECK_AND_RETURN_RET_LOGE(
496+ CheckAndInitBusCenterServerProxyInit() == SOFTBUS_OK, SOFTBUS_SERVER_NOT_INIT, LNN_EVENT, "server not init");
497+ return g_serverProxy->GetPerceptionDeviceList(pkgName, type, list, count);
498+}
@@ -17,6 +17,7 @@
17 17 
18#include "ipc_skeleton.h"18#include "ipc_skeleton.h"
19#include "lnn_log.h"19#include "lnn_log.h"
20+#include "securec.h"
20#include "softbus_adapter_mem.h"21#include "softbus_adapter_mem.h"
21#include "softbus_agent_communication.h"22#include "softbus_agent_communication.h"
22#include "softbus_error_code.h"23#include "softbus_error_code.h"
@@ -26,6 +27,7 @@
26#define MAX_TRUST_INFO_NUM 2027#define MAX_TRUST_INFO_NUM 20
27 28 
28namespace OHOS {29namespace OHOS {
30+ 
29sptr<IRemoteObject> g_remoteProxy = nullptr;31sptr<IRemoteObject> g_remoteProxy = nullptr;
30sptr<IRemoteObject> g_oldRemoteProxy = nullptr;32sptr<IRemoteObject> g_oldRemoteProxy = nullptr;
31static sptr<BusCenterServerProxy> g_serverProxy = nullptr;33static sptr<BusCenterServerProxy> g_serverProxy = nullptr;
@@ -1788,4 +1790,259 @@ int32_t BusCenterServerProxy::UnregisterConversationListener(const ConversationB
1788 }1790 }
1789 return serverRet;1791 return serverRet;
1790}1792}
1791-} // namespace OHOS1793+ 
1794+static bool WritePerceptionRequestHeader(
1795+ MessageParcel &data, const std::u16string &descriptor, const char *pkgName, PerceptionType type)
xuhengxiang
xuhengxiangxuhengxiang9月17日

在函数SetPerceptionAdvHighFreq中,如果customDataLen大于0,但没有正确检查memcpy_s的返回值,可能导致内存损坏。

在memcpy_s之后检查返回值,确保没有发生错误,并在发生错误时释放已分配的内存并返回错误代码。

likedislike
1796+{
1797+ if (!data.WriteInterfaceToken(descriptor)) {
1798+ LNN_LOGE(LNN_EVENT, "write interface token failed");
1799+ return false;
1800+ }
1801+ if (!data.WriteCString(pkgName)) {
1802+ LNN_LOGE(LNN_EVENT, "write pkgName failed");
1803+ return false;
1804+ }
1805+ if (!data.WriteInt32((int32_t)type)) {
1806+ LNN_LOGE(LNN_EVENT, "write type failed");
1807+ return false;
1808+ }
1809+ return true;
1810+}
1811+ 
1812+static int32_t ReadPerceptionReply(MessageParcel &reply)
1813+{
1814+ int32_t serverRet = SOFTBUS_IPC_ERR;
1815+ if (!reply.ReadInt32(serverRet)) {
1816+ LNN_LOGE(LNN_EVENT, "read serverRet failed");
1817+ return SOFTBUS_NETWORK_READINT32_FAILED;
1818+ }
1819+ return serverRet;
1820+}
1821+ 
1822+int32_t BusCenterServerProxy::StartPerceptionAdv(
1823+ const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
1824+{
1825+ if (pkgName == nullptr || param == nullptr || param->customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
1826+ LNN_LOGE(LNN_EVENT, "StartPerceptionAdv invalid param, customDataLen=%{public}u",
1827+ (param != nullptr) ? param->customDataLen : 0);
1828+ return SOFTBUS_INVALID_PARAM;
1829+ }
1830+ sptr<IRemoteObject> remote = Remote();
1831+ if (remote == nullptr) {
1832+ LNN_LOGE(LNN_EVENT, "StartPerceptionAdv remote is nullptr");
1833+ return SOFTBUS_NETWORK_REMOTE_NULL;
1834+ }
1835+ PerceptionAdvParam normalized {};
1836+ normalized.customDataLen = param->customDataLen;
1837+ if (param->customDataLen > 0 &&
1838+ memcpy_s(normalized.customData, sizeof(normalized.customData), param->customData,
1839+ param->customDataLen) != EOK) {
1840+ LNN_LOGE(LNN_EVENT, "StartPerceptionAdv copy customData failed");
1841+ return SOFTBUS_MEM_ERR;
1842+ }
1843+ MessageParcel data;
1844+ if (!WritePerceptionRequestHeader(data, GetDescriptor(), pkgName, type) ||
1845+ !data.WriteRawData(&normalized, sizeof(normalized))) {
1846+ LNN_LOGE(LNN_EVENT, "StartPerceptionAdv write request parcel failed");
1847+ return SOFTBUS_IPC_ERR;
1848+ }
1849+ MessageParcel reply;
1850+ MessageOption option;
1851+ int32_t ret = remote->SendRequest(SERVER_START_PERCEPTION_ADV, data, reply, option);
1852+ if (ret != SOFTBUS_OK) {
1853+ LNN_LOGE(LNN_EVENT, "StartPerceptionAdv send request failed, ret=%{public}d", ret);
1854+ return ret;
1855+ }
1856+ return ReadPerceptionReply(reply);
1857+}
1858+ 
1859+int32_t BusCenterServerProxy::SetPerceptionAdvHighFreq(
1860+ const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
1861+{
1862+ if (pkgName == nullptr || param == nullptr || param->customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
1863+ LNN_LOGE(LNN_EVENT, "SetPerceptionAdvHighFreq invalid param, customDataLen=%{public}u",
1864+ (param != nullptr) ? param->customDataLen : 0);
1865+ return SOFTBUS_INVALID_PARAM;
1866+ }
1867+ sptr<IRemoteObject> remote = Remote();
1868+ if (remote == nullptr) {
1869+ LNN_LOGE(LNN_EVENT, "SetPerceptionAdvHighFreq remote is nullptr");
1870+ return SOFTBUS_NETWORK_REMOTE_NULL;
1871+ }
1872+ PerceptionAdvParam normalized {};
1873+ normalized.customDataLen = param->customDataLen;
1874+ if (param->customDataLen > 0) {
1875+ int32_t copyRet =
1876+ memcpy_s(normalized.customData, sizeof(normalized.customData), param->customData, param->customDataLen);
1877+ if (copyRet != EOK) {
1878+ LNN_LOGE(LNN_EVENT, "SetPerceptionAdvHighFreq copy customData failed, copyRet=%{public}d", copyRet);
1879+ return SOFTBUS_MEM_ERR;
1880+ }
1881+ }
1882+ MessageParcel data;
1883+ if (!WritePerceptionRequestHeader(data, GetDescriptor(), pkgName, type) ||
1884+ !data.WriteRawData(&normalized, sizeof(normalized))) {
1885+ LNN_LOGE(LNN_EVENT, "SetPerceptionAdvHighFreq write request parcel failed");
1886+ return SOFTBUS_IPC_ERR;
1887+ }
1888+ MessageParcel reply;
1889+ MessageOption option;
1890+ int32_t ret = remote->SendRequest(SERVER_SET_PERCEPTION_ADV_HIGH_FREQ, data, reply, option);
1891+ if (ret != SOFTBUS_OK) {
1892+ LNN_LOGE(LNN_EVENT, "SetPerceptionAdvHighFreq send request failed, ret=%{public}d", ret);
1893+ return ret;
1894+ }
1895+ return ReadPerceptionReply(reply);
1896+}
1897+ 
1898+int32_t BusCenterServerProxy::StopPerceptionAdv(const char *pkgName, PerceptionType type)
1899+{
1900+ if (pkgName == nullptr) {
1901+ LNN_LOGE(LNN_EVENT, "StopPerceptionAdv invalid param");
1902+ return SOFTBUS_INVALID_PARAM;
1903+ }
1904+ sptr<IRemoteObject> remote = Remote();
1905+ if (remote == nullptr) {
1906+ LNN_LOGE(LNN_EVENT, "StopPerceptionAdv remote is nullptr");
1907+ return SOFTBUS_NETWORK_REMOTE_NULL;
1908+ }
1909+ MessageParcel data;
1910+ if (!WritePerceptionRequestHeader(data, GetDescriptor(), pkgName, type)) {
1911+ LNN_LOGE(LNN_EVENT, "StopPerceptionAdv write request parcel failed");
1912+ return SOFTBUS_IPC_ERR;
1913+ }
1914+ MessageParcel reply;
1915+ MessageOption option;
xuhengxiang
xuhengxiangxuhengxiang9月17日

在函数GetPerceptionDeviceList中,如果读取设备列表时发生错误,没有释放已分配的内存,可能导致内存泄漏。

在读取设备列表失败时,使用SoftBusFree释放已分配的内存,以避免内存泄漏。

likedislike
1916+ int32_t ret = remote->SendRequest(SERVER_STOP_PERCEPTION_ADV, data, reply, option);
1917+ if (ret != SOFTBUS_OK) {
1918+ LNN_LOGE(LNN_EVENT, "StopPerceptionAdv send request failed, ret=%{public}d", ret);
1919+ return ret;
1920+ }
1921+ return ReadPerceptionReply(reply);
1922+}
1923+ 
1924+int32_t BusCenterServerProxy::StartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle)
1925+{
1926+ if (pkgName == nullptr) {
1927+ LNN_LOGE(LNN_EVENT, "StartPerceptionScan invalid param");
1928+ return SOFTBUS_INVALID_PARAM;
1929+ }
1930+ sptr<IRemoteObject> remote = Remote();
xuhengxiang
xuhengxiangxuhengxiang9月17日

在函数GetPerceptionDeviceList中,如果读取设备列表时发生错误,没有释放已分配的内存,可能导致内存泄漏。

在读取设备列表失败时,使用SoftBusFree释放已分配的内存,以避免内存泄漏。

likedislike
1931+ if (remote == nullptr) {
1932+ LNN_LOGE(LNN_EVENT, "StartPerceptionScan remote is nullptr");
1933+ return SOFTBUS_NETWORK_REMOTE_NULL;
1934+ }
1935+ MessageParcel data;
1936+ if (!WritePerceptionRequestHeader(data, GetDescriptor(), pkgName, type) ||
1937+ !data.WriteInt32((int32_t)cycle)) {
1938+ LNN_LOGE(LNN_EVENT, "StartPerceptionScan write request parcel failed");
1939+ return SOFTBUS_IPC_ERR;
1940+ }
1941+ MessageParcel reply;
1942+ MessageOption option;
1943+ int32_t ret = remote->SendRequest(SERVER_START_PERCEPTION_SCAN, data, reply, option);
1944+ if (ret != SOFTBUS_OK) {
1945+ LNN_LOGE(LNN_EVENT, "StartPerceptionScan send request failed, ret=%{public}d", ret);
xuhengxiang
xuhengxiangxuhengxiang9月17日

在函数GetPerceptionDeviceList中,如果读取设备列表时发生错误,没有释放已分配的内存,可能导致内存泄漏。

在读取设备列表失败时,使用SoftBusFree释放已分配的内存,以避免内存泄漏。

likedislike
1946+ return ret;
1947+ }
1948+ return ReadPerceptionReply(reply);
1949+}
1950+ 
1951+int32_t BusCenterServerProxy::StopPerceptionScan(const char *pkgName, PerceptionType type)
1952+{
1953+ if (pkgName == nullptr) {
1954+ LNN_LOGE(LNN_EVENT, "StopPerceptionScan invalid param");
1955+ return SOFTBUS_INVALID_PARAM;
1956+ }
1957+ sptr<IRemoteObject> remote = Remote();
1958+ if (remote == nullptr) {
1959+ LNN_LOGE(LNN_EVENT, "StopPerceptionScan remote is nullptr");
1960+ return SOFTBUS_NETWORK_REMOTE_NULL;
1961+ }
1962+ MessageParcel data;
1963+ if (!WritePerceptionRequestHeader(data, GetDescriptor(), pkgName, type)) {
1964+ LNN_LOGE(LNN_EVENT, "StopPerceptionScan write request parcel failed");
1965+ return SOFTBUS_IPC_ERR;
1966+ }
1967+ MessageParcel reply;
1968+ MessageOption option;
1969+ int32_t ret = remote->SendRequest(SERVER_STOP_PERCEPTION_SCAN, data, reply, option);
1970+ if (ret != SOFTBUS_OK) {
1971+ LNN_LOGE(LNN_EVENT, "StopPerceptionScan send request failed, ret=%{public}d", ret);
1972+ return ret;
1973+ }
1974+ return ReadPerceptionReply(reply);
1975+}
1976+ 
1977+static int32_t ReadPerceptionDeviceList(MessageParcel &reply, PerceptionDeviceInfo **list, uint32_t *count)
1978+{
1979+ *list = nullptr;
1980+ *count = 0;
1981+ uint32_t required = 0;
1982+ if (!reply.ReadUint32(required)) {
1983+ LNN_LOGE(LNN_EVENT, "read perception device count failed");
1984+ return SOFTBUS_NETWORK_READINT32_FAILED;
1985+ }
1986+ if (required == 0) {
1987+ return SOFTBUS_OK;
1988+ }
1989+ if (required > PERCEPTION_MAX_DEVICE_NUM) {
1990+ LNN_LOGE(LNN_EVENT, "perception device count invalid, required=%{public}u", required);
1991+ return SOFTBUS_INVALID_PARAM;
1992+ }
1993+ size_t listSize = required * sizeof(PerceptionDeviceInfo);
1994+ const void *raw = reply.ReadRawData(listSize);
1995+ if (raw == nullptr) {
1996+ LNN_LOGE(LNN_EVENT, "read perception device list failed, required=%{public}u", required);
1997+ return SOFTBUS_IPC_ERR;
1998+ }
1999+ *list = static_cast<PerceptionDeviceInfo *>(SoftBusCalloc(listSize));
2000+ if (*list == nullptr) {
2001+ LNN_LOGE(LNN_EVENT, "malloc perception device list failed, listSize=%{public}zu", listSize);
2002+ return SOFTBUS_MALLOC_ERR;
2003+ }
2004+ if (memcpy_s(*list, listSize, raw, listSize) != EOK) {
2005+ LNN_LOGE(LNN_EVENT, "copy perception device list failed");
2006+ SoftBusFree(*list);
2007+ *list = nullptr;
2008+ return SOFTBUS_MEM_ERR;
2009+ }
2010+ *count = required;
2011+ return SOFTBUS_OK;
2012+}
2013+ 
2014+int32_t BusCenterServerProxy::GetPerceptionDeviceList(
2015+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
2016+{
2017+ if (pkgName == nullptr || list == nullptr || count == nullptr) {
2018+ LNN_LOGE(LNN_EVENT, "GetPerceptionDeviceList invalid param");
2019+ return SOFTBUS_INVALID_PARAM;
2020+ }
2021+ sptr<IRemoteObject> remote = Remote();
2022+ if (remote == nullptr) {
2023+ LNN_LOGE(LNN_EVENT, "GetPerceptionDeviceList remote is nullptr");
2024+ return SOFTBUS_NETWORK_REMOTE_NULL;
2025+ }
2026+ MessageParcel data;
2027+ if (!WritePerceptionRequestHeader(data, GetDescriptor(), pkgName, type)) {
2028+ LNN_LOGE(LNN_EVENT, "GetPerceptionDeviceList write request parcel failed");
2029+ return SOFTBUS_IPC_ERR;
2030+ }
2031+ MessageParcel reply;
2032+ MessageOption option;
2033+ int32_t ret = remote->SendRequest(SERVER_GET_PERCEPTION_DEVICE_LIST, data, reply, option);
2034+ if (ret != SOFTBUS_OK) {
2035+ LNN_LOGE(LNN_EVENT, "GetPerceptionDeviceList send request failed, ret=%{public}d", ret);
2036+ return ret;
2037+ }
2038+ int32_t serverRet = SOFTBUS_IPC_ERR;
2039+ if (!reply.ReadInt32(serverRet)) {
2040+ LNN_LOGE(LNN_EVENT, "read serverRet failed");
2041+ return SOFTBUS_NETWORK_READINT32_FAILED;
2042+ }
2043+ if (serverRet != SOFTBUS_OK) {
2044+ return serverRet;
2045+ }
2046+ return ReadPerceptionDeviceList(reply, list, count);
2047+}
2048+} // namespace OHOS
@@ -22,6 +22,7 @@
22#include "ble_range.h"22#include "ble_range.h"
23#include "data_level.h"23#include "data_level.h"
24#include "data_level_inner.h"24#include "data_level_inner.h"
25+#include "lnn_perception.h"
25#include "softbus_agent_communication.h"26#include "softbus_agent_communication.h"
26#include "softbus_bus_center.h"27#include "softbus_bus_center.h"
27 28 
@@ -119,12 +120,21 @@ void LnnOnErrorAuthResult(const char *pkgName, int64_t requestId, int32_t operat
119 120 
120int32_t DiscRecoveryPublish(void);121int32_t DiscRecoveryPublish(void);
121int32_t DiscRecoverySubscribe(void);122int32_t DiscRecoverySubscribe(void);
123+int32_t PerceptionRecoveryAdv(void);
124+int32_t PerceptionRecoveryScan(void);
122 125 
123int32_t PostConversationDataInner(const char *networkId, const ConversationBusiness *info,126int32_t PostConversationDataInner(const char *networkId, const ConversationBusiness *info,
124 const char *data, uint32_t len);127 const char *data, uint32_t len);
125int32_t RegisterConversationListenerInner(const ConversationBusiness *info, const ConversationListener *listener);128int32_t RegisterConversationListenerInner(const ConversationBusiness *info, const ConversationListener *listener);
126int32_t UnregisterConversationListenerInner(const ConversationBusiness *info);129int32_t UnregisterConversationListenerInner(const ConversationBusiness *info);
127int32_t GetTrustedDevicesInner(DeviceNodeInfo **info, int32_t *nums);130int32_t GetTrustedDevicesInner(DeviceNodeInfo **info, int32_t *nums);
131+int32_t StartPerceptionAdvInner(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
132+int32_t SetPerceptionAdvHighFreqInner(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param);
133+int32_t StopPerceptionAdvInner(const char *pkgName, PerceptionType type);
134+int32_t StartPerceptionScanInner(const char *pkgName, PerceptionType type, PerceptionCycle cycle);
135+int32_t StopPerceptionScanInner(const char *pkgName, PerceptionType type);
136+int32_t GetPerceptionDeviceListInner(
137+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count);
128int32_t LnnConversationRecvMsg(const ConversationBusiness *info, const char *udid, const char *data, uint32_t length);138int32_t LnnConversationRecvMsg(const ConversationBusiness *info, const char *udid, const char *data, uint32_t length);
129void RestartRegisterConversationListener(void);139void RestartRegisterConversationListener(void);
130 140 
@@ -103,6 +103,24 @@ typedef struct {
103 ListNode node;103 ListNode node;
xuhengxiang
xuhengxiangxuhengxiang9月17日

未初始化的静态变量可能导致未定义行为。

确保在所有使用静态变量的地方都进行了适当的初始化。

likedislike
104} DiscSubscribeMsg;104} DiscSubscribeMsg;
105 105 
106+typedef struct {
107+ char pkgName[PKG_NAME_SIZE_MAX];
108+ PerceptionType type;
109+ PerceptionAdvParam param;
110+ bool active;
111+} PerceptionAdvRecord;
112+ 
113+typedef struct {
114+ char pkgName[PKG_NAME_SIZE_MAX];
115+ PerceptionType type;
116+ PerceptionCycle cycle;
117+ bool active;
118+} PerceptionScanRecord;
119+ 
120+static SoftBusMutex g_perceptionRecLock;
121+static PerceptionAdvRecord g_perceptionAdvRecord;
122+static PerceptionScanRecord g_perceptionScanRecord;
123+ 
106typedef struct {124typedef struct {
107 ConversationBusiness info;125 ConversationBusiness info;
108 ConversationListener listener;126 ConversationListener listener;
@@ -688,6 +706,17 @@ static int32_t DiscoveryMsgListInit()
688 (void)SoftBusMutexUnlock(&g_isInitedLock);706 (void)SoftBusMutexUnlock(&g_isInitedLock);
xuhengxiang
xuhengxiangxuhengxiang9月17日

在销毁列表后,未释放互斥锁。

在销毁列表之前,应先释放互斥锁。

likedislike
689 return SOFTBUS_MALLOC_ERR;707 return SOFTBUS_MALLOC_ERR;
690 }708 }
709+ if (SoftBusMutexInit(&g_perceptionRecLock, NULL) != SOFTBUS_OK) {
710+ LNN_LOGE(LNN_STATE, "init perception rec lock failed");
711+ DestroySoftBusList(g_publishMsgList);
712+ DestroySoftBusList(g_discoveryMsgList);
713+ g_publishMsgList = NULL;
714+ g_discoveryMsgList = NULL;
715+ (void)SoftBusMutexUnlock(&g_isInitedLock);
716+ return SOFTBUS_LOCK_ERR;
717+ }
718+ g_perceptionAdvRecord.active = false;
719+ g_perceptionScanRecord.active = false;
691 g_isInited = true;720 g_isInited = true;
692 (void)SoftBusMutexUnlock(&g_isInitedLock);721 (void)SoftBusMutexUnlock(&g_isInitedLock);
693 static uint32_t callCount = 0;722 static uint32_t callCount = 0;
@@ -706,6 +735,9 @@ static int32_t DiscoveryMsgListDeInit()
706 DestroySoftBusList(g_discoveryMsgList);735 DestroySoftBusList(g_discoveryMsgList);
707 g_publishMsgList = NULL;736 g_publishMsgList = NULL;
708 g_discoveryMsgList = NULL;737 g_discoveryMsgList = NULL;
738+ g_perceptionAdvRecord.active = false;
739+ g_perceptionScanRecord.active = false;
740+ (void)SoftBusMutexDestroy(&g_perceptionRecLock);
709 g_isInited = false;741 g_isInited = false;
710 742 
711 LNN_LOGI(LNN_STATE, "disc list deinit success");743 LNN_LOGI(LNN_STATE, "disc list deinit success");
@@ -2073,6 +2105,54 @@ int32_t DiscRecoverySubscribe()
2073 return ret;2105 return ret;
2074}2106}
2075 2107 
2108+int32_t PerceptionRecoveryAdv(void)
2109+{
2110+ if (!g_isInited) {
2111+ LNN_LOGI(LNN_STATE, "no need recovery perception adv");
2112+ return SOFTBUS_OK;
2113+ }
2114+ LNN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_perceptionRecLock) == SOFTBUS_OK,
2115+ SOFTBUS_LOCK_ERR, LNN_STATE, "lock failed");
2116+ int32_t ret = SOFTBUS_OK;
2117+ if (g_perceptionAdvRecord.active) {
2118+ ret = ServerIpcStartPerceptionAdv(g_perceptionAdvRecord.pkgName,
2119+ g_perceptionAdvRecord.type, &g_perceptionAdvRecord.param);
2120+ if (ret != SOFTBUS_OK) {
2121+ LNN_LOGE(LNN_STATE, "recovery perception adv error, pkgName=%{public}s, ret=%{public}d",
2122+ g_perceptionAdvRecord.pkgName, ret);
2123+ } else {
2124+ LNN_LOGI(LNN_STATE, "recovery perception adv success, pkgName=%{public}s",
2125+ g_perceptionAdvRecord.pkgName);
2126+ }
2127+ }
2128+ (void)SoftBusMutexUnlock(&g_perceptionRecLock);
2129+ return ret;
2130+}
2131+ 
2132+int32_t PerceptionRecoveryScan(void)
2133+{
2134+ if (!g_isInited) {
2135+ LNN_LOGI(LNN_STATE, "no need recovery perception scan");
2136+ return SOFTBUS_OK;
2137+ }
2138+ LNN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_perceptionRecLock) == SOFTBUS_OK,
2139+ SOFTBUS_LOCK_ERR, LNN_STATE, "lock failed");
2140+ int32_t ret = SOFTBUS_OK;
2141+ if (g_perceptionScanRecord.active) {
2142+ ret = ServerIpcStartPerceptionScan(g_perceptionScanRecord.pkgName,
2143+ g_perceptionScanRecord.type, g_perceptionScanRecord.cycle);
2144+ if (ret != SOFTBUS_OK) {
2145+ LNN_LOGE(LNN_STATE, "recovery perception scan error, pkgName=%{public}s, ret=%{public}d",
2146+ g_perceptionScanRecord.pkgName, ret);
2147+ } else {
2148+ LNN_LOGI(LNN_STATE, "recovery perception scan success, pkgName=%{public}s",
2149+ g_perceptionScanRecord.pkgName);
2150+ }
2151+ }
2152+ (void)SoftBusMutexUnlock(&g_perceptionRecLock);
2153+ return ret;
2154+}
2155+ 
2076int32_t LnnConversationRecvMsg(const ConversationBusiness *info, const char *networkId,2156int32_t LnnConversationRecvMsg(const ConversationBusiness *info, const char *networkId,
2077 const char *data, uint32_t length)2157 const char *data, uint32_t length)
2078{2158{
@@ -2270,4 +2350,99 @@ void RestartRegisterConversationListener(void)
2270 AnonymizeFree(anonyAbilityName);2350 AnonymizeFree(anonyAbilityName);
2271 }2351 }
2272 (void)SoftBusMutexUnlock(&g_busCenterClient.lock);2352 (void)SoftBusMutexUnlock(&g_busCenterClient.lock);
2273-}2353+}
2354+ 
2355+int32_t StartPerceptionAdvInner(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
2356+{
2357+ int32_t ret = ServerIpcStartPerceptionAdv(pkgName, type, param);
2358+ if (ret != SOFTBUS_OK) {
2359+ return ret;
2360+ }
2361+ if (SoftBusMutexLock(&g_perceptionRecLock) != SOFTBUS_OK) {
2362+ LNN_LOGE(LNN_STATE, "perception adv rec lock failed");
2363+ return SOFTBUS_OK;
2364+ }
2365+ if (strcpy_s(g_perceptionAdvRecord.pkgName, PKG_NAME_SIZE_MAX, pkgName) != EOK) {
2366+ LNN_LOGE(LNN_STATE, "perception adv rec copy pkgName failed");
2367+ }
2368+ g_perceptionAdvRecord.type = type;
2369+ if (param != NULL) {
2370+ g_perceptionAdvRecord.param = *param;
2371+ }
2372+ g_perceptionAdvRecord.active = true;
2373+ (void)SoftBusMutexUnlock(&g_perceptionRecLock);
2374+ return SOFTBUS_OK;
2375+}
2376+ 
2377+int32_t SetPerceptionAdvHighFreqInner(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
2378+{
2379+ int32_t ret = ServerIpcSetPerceptionAdvHighFreq(pkgName, type, param);
2380+ if (ret != SOFTBUS_OK) {
2381+ return ret;
2382+ }
2383+ if (SoftBusMutexLock(&g_perceptionRecLock) != SOFTBUS_OK) {
2384+ LNN_LOGE(LNN_STATE, "perception adv rec lock failed");
2385+ return SOFTBUS_OK;
2386+ }
2387+ if (g_perceptionAdvRecord.active && param != NULL) {
2388+ g_perceptionAdvRecord.param = *param;
2389+ }
2390+ (void)SoftBusMutexUnlock(&g_perceptionRecLock);
2391+ return SOFTBUS_OK;
2392+}
2393+ 
2394+int32_t StopPerceptionAdvInner(const char *pkgName, PerceptionType type)
2395+{
2396+ int32_t ret = ServerIpcStopPerceptionAdv(pkgName, type);
2397+ if (ret != SOFTBUS_OK) {
2398+ return ret;
2399+ }
2400+ if (SoftBusMutexLock(&g_perceptionRecLock) != SOFTBUS_OK) {
2401+ LNN_LOGE(LNN_STATE, "perception adv rec lock failed");
2402+ return SOFTBUS_OK;
2403+ }
2404+ g_perceptionAdvRecord.active = false;
2405+ (void)SoftBusMutexUnlock(&g_perceptionRecLock);
2406+ return SOFTBUS_OK;
2407+}
2408+ 
2409+int32_t StartPerceptionScanInner(const char *pkgName, PerceptionType type, PerceptionCycle cycle)
2410+{
2411+ int32_t ret = ServerIpcStartPerceptionScan(pkgName, type, cycle);
2412+ if (ret != SOFTBUS_OK) {
2413+ return ret;
2414+ }
2415+ if (SoftBusMutexLock(&g_perceptionRecLock) != SOFTBUS_OK) {
2416+ LNN_LOGE(LNN_STATE, "perception scan rec lock failed");
2417+ return SOFTBUS_OK;
2418+ }
2419+ if (strcpy_s(g_perceptionScanRecord.pkgName, PKG_NAME_SIZE_MAX, pkgName) != EOK) {
2420+ LNN_LOGE(LNN_STATE, "perception scan rec copy pkgName failed");
2421+ }
2422+ g_perceptionScanRecord.type = type;
2423+ g_perceptionScanRecord.cycle = cycle;
2424+ g_perceptionScanRecord.active = true;
2425+ (void)SoftBusMutexUnlock(&g_perceptionRecLock);
2426+ return SOFTBUS_OK;
2427+}
2428+ 
2429+int32_t StopPerceptionScanInner(const char *pkgName, PerceptionType type)
2430+{
2431+ int32_t ret = ServerIpcStopPerceptionScan(pkgName, type);
2432+ if (ret != SOFTBUS_OK) {
2433+ return ret;
2434+ }
2435+ if (SoftBusMutexLock(&g_perceptionRecLock) != SOFTBUS_OK) {
2436+ LNN_LOGE(LNN_STATE, "perception scan rec lock failed");
2437+ return SOFTBUS_OK;
2438+ }
2439+ g_perceptionScanRecord.active = false;
2440+ (void)SoftBusMutexUnlock(&g_perceptionRecLock);
2441+ return SOFTBUS_OK;
2442+}
2443+ 
2444+int32_t GetPerceptionDeviceListInner(
2445+ const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
2446+{
2447+ return ServerIpcGetPerceptionDeviceList(pkgName, type, list, count);
2448+}
@@ -24,6 +24,7 @@
24#include "data_level.h"24#include "data_level.h"
25#include "lnn_event.h"25#include "lnn_event.h"
26#include "lnn_log.h"26#include "lnn_log.h"
27+#include "lnn_perception.h"
27#include "softbus_adapter_mem.h"28#include "softbus_adapter_mem.h"
28#include "softbus_client_frame_manager.h"29#include "softbus_client_frame_manager.h"
29#include "softbus_def.h"30#include "softbus_def.h"
@@ -783,4 +784,78 @@ int32_t ProcessAccountAuth(const char *pkgName, int64_t requestId, const uint8_t
783 return ret;784 return ret;
xuhengxiang
xuhengxiangxuhengxiang9月17日

在调用 StartPerceptionAdvInner、SetPerceptionAdvHighFreqInner、StopPerceptionAdvInner、StartPerceptionScanInner、StopPerceptionScanInner 和 GetPerceptionDeviceListInner 之前没有检查返回值,可能导致未处理的错误。

在每个调用 StartPerceptionAdvInner、SetPerceptionAdvHighFreqInner、StopPerceptionAdvInner、StartPerceptionScanInner、StopPerceptionScanInner 和 GetPerceptionDeviceListInner 后,检查返回值并处理可能的错误。

likedislike
784 }785 }
785 return ProcessAccountAuthInner(pkgName, requestId, data, dataLen, cb);786 return ProcessAccountAuthInner(pkgName, requestId, data, dataLen, cb);
786-}787+}
788+ 
789+static int32_t InitPerceptionClient(const char *pkgName, PerceptionType type)
790+{
791+ if (pkgName == NULL || type < PERCEPTION_TYPE_COLLABORATIVE_WAKE || type >= PERCEPTION_TYPE_BUTT) {
792+ LNN_LOGE(LNN_EVENT, "invalid params");
793+ return SOFTBUS_INVALID_PARAM;
794+ }
795+ return CommonInit(pkgName);
796+}
797+ 
798+int32_t StartPerceptionAdv(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
799+{
800+ int32_t ret = InitPerceptionClient(pkgName, type);
801+ if (ret != SOFTBUS_OK) {
802+ return ret;
803+ }
804+ if (param == NULL || param->customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
805+ LNN_LOGE(LNN_EVENT, "invalid params");
806+ return SOFTBUS_INVALID_PARAM;
807+ }
808+ return StartPerceptionAdvInner(pkgName, type, param);
809+}
810+ 
811+int32_t SetPerceptionAdvHighFreq(const char *pkgName, PerceptionType type, const PerceptionAdvParam *param)
812+{
813+ int32_t ret = InitPerceptionClient(pkgName, type);
xuhengxiangxuhengxiang
xuhengxiangxuhengxiang9月17日

在调用 SoftBusFree 释放 PerceptionDeviceInfo 指针之前没有检查指针是否为 NULL,可能导致野指针解引用。

在调用 SoftBusFree 之前,检查 PerceptionDeviceInfo 指针是否为 NULL,以避免野指针解引用。

likedislike
xuhengxiangxuhengxiang9月17日

FreePerceptionDeviceList 函数中,SoftBusFree 释放了 PerceptionDeviceInfo 指针,但没有释放 PerceptionDeviceInfo 结构体内部的资源,可能导致资源泄漏。

在 FreePerceptionDeviceList 函数中,除了释放 PerceptionDeviceInfo 指针外,还需要递归释放 PerceptionDeviceInfo 结构体内部的资源。

likedislike
xuhengxiangxuhengxiang9月17日

在释放 PerceptionDeviceInfo 指针后没有将指针设置为 NULL,可能导致悬垂指针。

在释放 PerceptionDeviceInfo 指针后,将指针设置为 NULL,以避免悬垂指针。

likedislike
xuhengxiangxuhengxiang9月17日

FreePerceptionDeviceList 函数中,没有检查传入的 list 是否为 NULL,可能导致对 NULL 指针的解引用。

在 FreePerceptionDeviceList 函数中,检查传入的 list 是否为 NULL,以避免对 NULL 指针的解引用。

likedislike
814+ if (ret != SOFTBUS_OK) {
815+ return ret;
816+ }
817+ if (param == NULL || param->customDataLen > PERCEPTION_CUSTOM_DATA_MAX_LEN) {
818+ LNN_LOGE(LNN_EVENT, "invalid params");
819+ return SOFTBUS_INVALID_PARAM;
820+ }
821+ return SetPerceptionAdvHighFreqInner(pkgName, type, param);
822+}
823+ 
824+int32_t StopPerceptionAdv(const char *pkgName, PerceptionType type)
825+{
826+ int32_t ret = InitPerceptionClient(pkgName, type);
827+ return (ret == SOFTBUS_OK) ? StopPerceptionAdvInner(pkgName, type) : ret;
828+}
829+ 
830+int32_t StartPerceptionScan(const char *pkgName, PerceptionType type, PerceptionCycle cycle)
831+{
832+ int32_t ret = InitPerceptionClient(pkgName, type);
833+ return (ret == SOFTBUS_OK) ? StartPerceptionScanInner(pkgName, type, cycle) : ret;
834+}
835+ 
836+int32_t StopPerceptionScan(const char *pkgName, PerceptionType type)
837+{
838+ int32_t ret = InitPerceptionClient(pkgName, type);
839+ return (ret == SOFTBUS_OK) ? StopPerceptionScanInner(pkgName, type) : ret;
840+}
841+ 
842+int32_t GetPerceptionDeviceList(const char *pkgName, PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
843+{
844+ int32_t ret = InitPerceptionClient(pkgName, type);
845+ if (ret != SOFTBUS_OK) {
846+ return ret;
847+ }
848+ if (list == NULL || count == NULL) {
849+ LNN_LOGE(LNN_EVENT, "invalid params");
850+ return SOFTBUS_INVALID_PARAM;
851+ }
852+ return GetPerceptionDeviceListInner(pkgName, type, list, count);
853+}
854+ 
855+void FreePerceptionDeviceList(PerceptionDeviceInfo *list)
856+{
857+ if (list == NULL) {
858+ return;
859+ }
860+ SoftBusFree(list);
861+}
@@ -210,6 +210,8 @@ void ClientDeathProcTask(void)
210 DiscRecoveryPublish();210 DiscRecoveryPublish();
211 DiscRecoverySubscribe();211 DiscRecoverySubscribe();
212 DiscRecoveryPolicyPacked();212 DiscRecoveryPolicyPacked();
213+ PerceptionRecoveryAdv();
214+ PerceptionRecoveryScan();
213 RestartRegDataLevelChange();215 RestartRegDataLevelChange();
214 RestartRegisterConversationListener();216 RestartRegisterConversationListener();
215}217}
@@ -266,6 +266,13 @@
266 "DisableMetaPlugin";266 "DisableMetaPlugin";
267 "GetMetaPluginState";267 "GetMetaPluginState";
268 "SetLaneControlPolicy";268 "SetLaneControlPolicy";
269+ "StartPerceptionAdv";
270+ "SetPerceptionAdvHighFreq";
271+ "StopPerceptionAdv";
272+ "StartPerceptionScan";
273+ "StopPerceptionScan";
274+ "GetPerceptionDeviceList";
275+ "FreePerceptionDeviceList";
269 local:276 local:
270 *;277 *;
271};278};
@@ -3034,6 +3034,7 @@ ohos_unittest("LNNLaneHubTest") {
3034 "$dsoftbus_root_path/core/bus_center/lnn/lane/lane_hub/",3034 "$dsoftbus_root_path/core/bus_center/lnn/lane/lane_hub/",
3035 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/common/include",3035 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/common/include",
3036 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/heartbeat/include",3036 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/heartbeat/include",
3037+ "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/perception/include",
3037 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/lane_manager/include",3038 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/lane_manager/include",
3038 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/lane_qos/include",3039 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/lane_qos/include",
3039 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/time_sync/include",3040 "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/time_sync/include",
@@ -3068,6 +3069,42 @@ ohos_unittest("LNNLaneHubTest") {
3068 }3069 }
3069}3070}
3070 3071 
3072+ohos_unittest("PerceptionManagerTest") {
3073+ module_out_path = module_output_path
3074+ sources = [
3075+ "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/perception/src/perception_manager.c",
3076+ "$dsoftbus_root_path/core/bus_center/utils/src/lnn_async_callback_utils.c",
3077+ "$dsoftbus_root_path/tests/core/bus_center/lnn/lane/lane_hub/perception/perception_deps_mock.cpp",
3078+ "$dsoftbus_root_path/tests/core/bus_center/lnn/lane/lane_hub/perception/perception_manager_test.cpp",
3079+ ]
3080+ 
3081+ include_dirs = lnn_mock_test_include_dirs
3082+ include_dirs += [
3083+ "$dsoftbus_root_path/core/bus_center/lnn/lane/lane_hub/perception",
3084+ "$dsoftbus_root_path/core/bus_center/lnn/lane_hub/perception/include",
3085+ "$dsoftbus_root_path/core/frame/init/include",
3086+ ]
3087+ 
3088+ deps = [
3089+ "$dsoftbus_dfx_path:softbus_dfx",
3090+ "$dsoftbus_root_path/adapter:softbus_adapter",
3091+ "$dsoftbus_root_path/core/common:softbus_utils",
3092+ ]
3093+ 
3094+ external_deps = [
3095+ "googletest:gmock_main",
3096+ "googletest:gtest_main",
3097+ "hilog:libhilog",
3098+ ]
3099+ 
3100+ if (is_standard_system) {
3101+ external_deps += [
3102+ "c_utils:utils",
3103+ "device_auth:deviceauth_sdk",
3104+ ]
3105+ }
3106+}
3107+ 
3071ohos_unittest("LNNTransLaneMockTest") {3108ohos_unittest("LNNTransLaneMockTest") {
3072 module_out_path = module_output_path3109 module_out_path = module_output_path
3073 sources = [3110 sources = [
@@ -4391,6 +4428,10 @@ group("unittest") {
4391 ":LnnFragmentRecvTest",4428 ":LnnFragmentRecvTest",
4392 ":BusCenterClientAgentTest",4429 ":BusCenterClientAgentTest",
4393 ]4430 ]
4431+ if (dsoftbus_feature_lnn_frame && dsoftbus_feature_lnn_ble && dsoftbus_feature_conn_ble &&
4432+ dsoftbus_feature_inner_disc_broadcast) {
4433+ deps += [ ":PerceptionManagerTest" ]
4434+ }
4394 if (dsoftbus_feature_lnn_lane_mgr) {4435 if (dsoftbus_feature_lnn_lane_mgr) {
4395 deps += [4436 deps += [
4396 ":LNNLaneAllocTest",4437 ":LNNLaneAllocTest",
@@ -82,6 +82,16 @@ void LnnDeinitHeartbeat(void)
82 return GetLaneHubDepsInterface()->LnnDeinitHeartbeat();82 return GetLaneHubDepsInterface()->LnnDeinitHeartbeat();
83}83}
84 84 
85+int32_t PerceptionManagerInit(void)
86+{
87+ return GetLaneHubDepsInterface()->PerceptionManagerInit();
88+}
89+ 
90+void PerceptionManagerDeinit(void)
91+{
92+ return GetLaneHubDepsInterface()->PerceptionManagerDeinit();
93+}
94+ 
85int32_t InitControlPlanePacked(void)95int32_t InitControlPlanePacked(void)
86{96{
87 return GetLaneHubDepsInterface()->InitControlPlanePacked();97 return GetLaneHubDepsInterface()->InitControlPlanePacked();
@@ -36,6 +36,8 @@ public:
36 virtual void DeinitLane(void) = 0;36 virtual void DeinitLane(void) = 0;
37 virtual void LnnDeinitTimeSync(void) = 0;37 virtual void LnnDeinitTimeSync(void) = 0;
38 virtual void LnnDeinitHeartbeat(void) = 0;38 virtual void LnnDeinitHeartbeat(void) = 0;
39+ virtual int32_t PerceptionManagerInit(void) = 0;
40+ virtual void PerceptionManagerDeinit(void) = 0;
39 virtual int32_t InitControlPlanePacked(void) = 0;41 virtual int32_t InitControlPlanePacked(void) = 0;
40 virtual int32_t SoftBusRegBusCenterVarDump(char *dumpVar, SoftBusVarDumpCb cb) = 0;42 virtual int32_t SoftBusRegBusCenterVarDump(char *dumpVar, SoftBusVarDumpCb cb) = 0;
41};43};
@@ -54,6 +56,8 @@ public:
54 MOCK_METHOD0(DeinitLane, void (void));56 MOCK_METHOD0(DeinitLane, void (void));
55 MOCK_METHOD0(LnnDeinitTimeSync, void (void));57 MOCK_METHOD0(LnnDeinitTimeSync, void (void));
56 MOCK_METHOD0(LnnDeinitHeartbeat, void (void));58 MOCK_METHOD0(LnnDeinitHeartbeat, void (void));
59+ MOCK_METHOD0(PerceptionManagerInit, int32_t (void));
60+ MOCK_METHOD0(PerceptionManagerDeinit, void (void));
57 MOCK_METHOD0(InitControlPlanePacked, int32_t (void));61 MOCK_METHOD0(InitControlPlanePacked, int32_t (void));
58 MOCK_METHOD2(SoftBusRegBusCenterVarDump, int32_t (char *dumpVar, SoftBusVarDumpCb cb));62 MOCK_METHOD2(SoftBusRegBusCenterVarDump, int32_t (char *dumpVar, SoftBusVarDumpCb cb));
59};63};
@@ -0,0 +1,176 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+#include "perception_deps_mock.h"
17+ 
18+#include "softbus_error_code.h"
19+ 
20+namespace OHOS {
21+void *g_perceptionDepsInterface;
22+ 
23+PerceptionDepsMock::PerceptionDepsMock()
24+{
25+ g_perceptionDepsInterface = reinterpret_cast<void *>(this);
26+}
27+ 
28+PerceptionDepsMock::~PerceptionDepsMock()
29+{
30+ g_perceptionDepsInterface = nullptr;
31+}
32+ 
33+static PerceptionDepsInterface *GetPerceptionDepsInterface()
34+{
35+ if (g_perceptionDepsInterface == nullptr) {
36+ return nullptr;
37+ }
38+ return reinterpret_cast<PerceptionDepsInterface *>(g_perceptionDepsInterface);
39+}
40+ 
41+extern "C" {
42+int32_t PerceptionAdvertiserInit(void)
43+{
44+ auto *p = GetPerceptionDepsInterface();
45+ return p == nullptr ? SOFTBUS_ERR : p->PerceptionAdvertiserInit();
46+}
47+ 
48+void PerceptionAdvertiserDeinit(void)
49+{
50+ auto *p = GetPerceptionDepsInterface();
51+ if (p != nullptr) {
52+ p->PerceptionAdvertiserDeinit();
53+ }
54+}
55+ 
56+int32_t PerceptionScannerInit(void)
57+{
58+ auto *p = GetPerceptionDepsInterface();
59+ return p == nullptr ? SOFTBUS_ERR : p->PerceptionScannerInit();
60+}
61+ 
62+void PerceptionScannerDeinit(void)
63+{
64+ auto *p = GetPerceptionDepsInterface();
65+ if (p != nullptr) {
66+ p->PerceptionScannerDeinit();
67+ }
68+}
69+ 
70+int32_t PerceptionAdvStart(PerceptionType type, const PerceptionAdvParam *param)
71+{
72+ auto *p = GetPerceptionDepsInterface();
73+ return p == nullptr ? SOFTBUS_ERR : p->PerceptionAdvStart(type, param);
74+}
75+ 
76+int32_t PerceptionAdvSetHighFreq(PerceptionType type, const PerceptionAdvParam *param)
77+{
78+ auto *p = GetPerceptionDepsInterface();
79+ return p == nullptr ? SOFTBUS_ERR : p->PerceptionAdvSetHighFreq(type, param);
80+}
81+ 
82+int32_t PerceptionAdvStop(void)
83+{
84+ auto *p = GetPerceptionDepsInterface();
85+ return p == nullptr ? SOFTBUS_ERR : p->PerceptionAdvStop();
86+}
87+ 
88+int32_t PerceptionScanStart(PerceptionType type, PerceptionCycle cycle)
89+{
90+ auto *p = GetPerceptionDepsInterface();
91+ return p == nullptr ? SOFTBUS_ERR : p->PerceptionScanStart(type, cycle);
92+}
93+ 
94+int32_t PerceptionScanStop(void)
95+{
96+ auto *p = GetPerceptionDepsInterface();
97+ return p == nullptr ? SOFTBUS_ERR : p->PerceptionScanStop();
98+}
99+ 
100+int32_t PerceptionScanGetDeviceList(PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count)
101+{
102+ auto *p = GetPerceptionDepsInterface();
103+ return p == nullptr ? SOFTBUS_ERR : p->PerceptionScanGetDeviceList(type, list, count);
104+}
105+ 
106+int32_t PerceptionEnhanceInitPacked(void)
107+{
108+ auto *p = GetPerceptionDepsInterface();
109+ return p == nullptr ? SOFTBUS_NOT_IMPLEMENT : p->PerceptionEnhanceInitPacked();
110+}
111+ 
112+void PerceptionEnhanceDeinitPacked(void)
113+{
114+ auto *p = GetPerceptionDepsInterface();
115+ if (p != nullptr) {
116+ p->PerceptionEnhanceDeinitPacked();
117+ }
118+}
119+ 
120+bool IsSupportLpFeaturePacked(void)
121+{
122+ auto *p = GetPerceptionDepsInterface();
123+ return p == nullptr ? false : p->IsSupportLpFeaturePacked();
124+}
125+ 
126+bool LnnIsLocalSupportBurstFeature(void)
127+{
128+ auto *p = GetPerceptionDepsInterface();
129+ return p == nullptr ? false : p->LnnIsLocalSupportBurstFeature();
130+}
131+ 
132+int32_t LnnGetLocalNumInfo(InfoKey key, int32_t *info)
133+{
134+ auto *p = GetPerceptionDepsInterface();
135+ return p == nullptr ? SOFTBUS_ERR : p->LnnGetLocalNumInfo(key, info);
136+}
137+ 
138+int32_t LnnRegisterEventHandler(LnnEventType event, LnnEventHandler handler)
139+{
140+ auto *p = GetPerceptionDepsInterface();
141+ return p == nullptr ? SOFTBUS_ERR : p->LnnRegisterEventHandler(event, handler);
142+}
143+ 
144+void LnnUnregisterEventHandler(LnnEventType event, LnnEventHandler handler)
145+{
146+ auto *p = GetPerceptionDepsInterface();
147+ if (p != nullptr) {
148+ p->LnnUnregisterEventHandler(event, handler);
149+ }
150+}
151+ 
152+void PerceptionAdvOnBtStateChanged(bool isBtOn)
153+{
154+ auto *p = GetPerceptionDepsInterface();
155+ if (p != nullptr) {
156+ p->PerceptionAdvOnBtStateChanged(isBtOn);
157+ }
158+}
159+ 
160+void PerceptionScanOnBtStateChanged(bool isBtOn)
161+{
162+ auto *p = GetPerceptionDepsInterface();
163+ if (p != nullptr) {
164+ p->PerceptionScanOnBtStateChanged(isBtOn);
165+ }
166+}
167+ 
168+void PerceptionScanOnScreenStateChanged(bool isScreenOn)
169+{
170+ auto *p = GetPerceptionDepsInterface();
171+ if (p != nullptr) {
172+ p->PerceptionScanOnScreenStateChanged(isScreenOn);
173+ }
174+}
175+}
176+} // namespace OHOS
@@ -0,0 +1,83 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+#ifndef PERCEPTION_DEPS_MOCK_H
17+#define PERCEPTION_DEPS_MOCK_H
18+ 
19+#include <gmock/gmock.h>
20+ 
21+#include "bus_center_event_struct.h"
22+#include "bus_center_info_key_struct.h"
23+#include "g_enhance_lnn_func_pack.h"
24+#include "lnn_heartbeat_utils.h"
25+#include "lnn_perception.h"
26+#include "perception_advertiser.h"
27+#include "perception_scanner.h"
28+ 
29+namespace OHOS {
30+class PerceptionDepsInterface {
31+public:
32+ virtual ~PerceptionDepsInterface() = default;
33+ 
34+ virtual int32_t PerceptionAdvertiserInit(void) = 0;
35+ virtual void PerceptionAdvertiserDeinit(void) = 0;
36+ virtual int32_t PerceptionScannerInit(void) = 0;
37+ virtual void PerceptionScannerDeinit(void) = 0;
38+ virtual int32_t PerceptionAdvStart(PerceptionType type, const PerceptionAdvParam *param) = 0;
39+ virtual int32_t PerceptionAdvSetHighFreq(PerceptionType type, const PerceptionAdvParam *param) = 0;
40+ virtual int32_t PerceptionAdvStop(void) = 0;
41+ virtual int32_t PerceptionScanStart(PerceptionType type, PerceptionCycle cycle) = 0;
42+ virtual int32_t PerceptionScanStop(void) = 0;
43+ virtual int32_t PerceptionScanGetDeviceList(PerceptionType type, PerceptionDeviceInfo **list, uint32_t *count) = 0;
44+ virtual int32_t PerceptionEnhanceInitPacked(void) = 0;
45+ virtual void PerceptionEnhanceDeinitPacked(void) = 0;
46+ virtual bool IsSupportLpFeaturePacked(void) = 0;
47+ virtual bool LnnIsLocalSupportBurstFeature(void) = 0;
48+ virtual int32_t LnnGetLocalNumInfo(InfoKey key, int32_t *info) = 0;
49+ virtual int32_t LnnRegisterEventHandler(LnnEventType event, LnnEventHandler handler) = 0;
50+ virtual void LnnUnregisterEventHandler(LnnEventType event, LnnEventHandler handler) = 0;
51+ virtual void PerceptionAdvOnBtStateChanged(bool isBtOn) = 0;
52+ virtual void PerceptionScanOnBtStateChanged(bool isBtOn) = 0;
53+ virtual void PerceptionScanOnScreenStateChanged(bool isScreenOn) = 0;
54+};
55+ 
56+class PerceptionDepsMock : public PerceptionDepsInterface {
57+public:
58+ PerceptionDepsMock();
59+ ~PerceptionDepsMock() override;
60+ 
61+ MOCK_METHOD0(PerceptionAdvertiserInit, int32_t(void));
62+ MOCK_METHOD0(PerceptionAdvertiserDeinit, void(void));
63+ MOCK_METHOD0(PerceptionScannerInit, int32_t(void));
64+ MOCK_METHOD0(PerceptionScannerDeinit, void(void));
65+ MOCK_METHOD2(PerceptionAdvStart, int32_t(PerceptionType, const PerceptionAdvParam *));
66+ MOCK_METHOD2(PerceptionAdvSetHighFreq, int32_t(PerceptionType, const PerceptionAdvParam *));
67+ MOCK_METHOD0(PerceptionAdvStop, int32_t(void));
68+ MOCK_METHOD2(PerceptionScanStart, int32_t(PerceptionType, PerceptionCycle));
69+ MOCK_METHOD0(PerceptionScanStop, int32_t(void));
70+ MOCK_METHOD3(PerceptionScanGetDeviceList, int32_t(PerceptionType, PerceptionDeviceInfo **, uint32_t *));
71+ MOCK_METHOD0(PerceptionEnhanceInitPacked, int32_t(void));
72+ MOCK_METHOD0(PerceptionEnhanceDeinitPacked, void(void));
73+ MOCK_METHOD0(IsSupportLpFeaturePacked, bool(void));
74+ MOCK_METHOD0(LnnIsLocalSupportBurstFeature, bool(void));
75+ MOCK_METHOD2(LnnGetLocalNumInfo, int32_t(InfoKey, int32_t *));
76+ MOCK_METHOD2(LnnRegisterEventHandler, int32_t(LnnEventType, LnnEventHandler));
77+ MOCK_METHOD2(LnnUnregisterEventHandler, void(LnnEventType, LnnEventHandler));
78+ MOCK_METHOD1(PerceptionAdvOnBtStateChanged, void(bool));
79+ MOCK_METHOD1(PerceptionScanOnBtStateChanged, void(bool));
80+ MOCK_METHOD1(PerceptionScanOnScreenStateChanged, void(bool));
81+};
82+} // namespace OHOS
83+#endif // PERCEPTION_DEPS_MOCK_H