1 /*
2  * Copyright (c) 2022-2024 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  * miscservices under the License is miscservices 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 "softbus_hisysevt_discreporter.h"
17 
18 #include "comm_log.h"
19 #include "securec.h"
20 #include "softbus_adapter_thread.h"
21 #include "softbus_adapter_mem.h"
22 #include "softbus_errcode.h"
23 #include "softbus_hisysevt_bus_center.h"
24 #include "softbus_hisysevt_common.h"
25 #include "softbus_utils.h"
26 
27 #define MODULE_NAME_MAX_LEN 65
28 
29 #define FIRST_DISC_DURATION_PARAM_NUM 10
30 #define SOFT_BUS_VERSION_KEY "SOFT_BUS_VERSION"
31 #define PACKAGE_VERSION_KEY "PACKAGE_VERSION"
32 #define LINK_TYPE_KEY "LINK_TYPE"
33 #define TOTAL_TIME_KEY "TOTAL_TIME"
34 #define TOTAL_COUNT_KEY "TOTAL_COUNT"
35 #define COUNT1_KEY "COUNT1"
36 #define COUNT2_KEY "COUNT2"
37 #define COUNT3_KEY "COUNT3"
38 #define COUNT4_KEY "COUNT4"
39 #define COUNT5_KEY "COUNT5"
40 
41 #define DISCOVERY_DETAILS_PARAM_NUM 6
42 #define MODULE_KEY "MODULE"
43 #define DISC_TYPE_KEY "DISCTYPE"
44 #define DURATION_KEY "DURATION"
45 #define REPORT_TIMES_KEY "REPTIMES"
46 #define DEVICE_NUM_KEY "DEVNUM"
47 #define DISC_TIMES_KEY "DISCTIMES"
48 
49 #define DISCOVERY_BLE_RSSI_PARAM_NUM 2
50 #define RANGE_ID_KEY "RANGEID"
51 #define RANGE_DATA_KEY "RANGEDATA"
52 
53 #define BLE_RSSI_RANGE_SIZE 52
54 #define MAX_RANGE_ID 130
55 #define MIN_RANGE_ID (-130)
56 #define INTERVAL_OF_RSSI 5
57 
58 typedef enum {
59     STANDARD_S = 500,
60     STANDARD_A = 1000,
61     STANDARD_B = 1500,
62     STANDARD_C = 2000,
63     STANDARD_D = 2500,
64 } DiscoveryThreshold;
65 
66 typedef struct {
67     SoftBusMutex lock;
68     uint64_t mDiscTotalTime;
69     uint32_t mDiscTotalCount;
70     uint32_t mDiscCount1;
71     uint32_t mDiscCount2;
72     uint32_t mDiscCount3;
73     uint32_t mDiscCount4;
74     uint32_t mDiscCount5;
75 } FirstDiscTime;
76 
77 typedef struct {
78     SoftBusEvtParamType paramType;
79     char paramName[SOFTBUS_HISYSEVT_NAME_LEN];
80     size_t paramSize;
81 } SoftBusEvtParamSize;
82 
83 static SoftBusEvtParamSize g_firstDsicTimeParam[FIRST_DISC_DURATION_PARAM_NUM] = {
84     {SOFTBUS_EVT_PARAMTYPE_STRING, SOFT_BUS_VERSION_KEY},
85     {SOFTBUS_EVT_PARAMTYPE_STRING, PACKAGE_VERSION_KEY},
86     {SOFTBUS_EVT_PARAMTYPE_UINT32, LINK_TYPE_KEY},
87     {SOFTBUS_EVT_PARAMTYPE_UINT64, TOTAL_TIME_KEY},
88     {SOFTBUS_EVT_PARAMTYPE_UINT32, TOTAL_COUNT_KEY},
89     {SOFTBUS_EVT_PARAMTYPE_UINT32, COUNT1_KEY},
90     {SOFTBUS_EVT_PARAMTYPE_UINT32, COUNT2_KEY},
91     {SOFTBUS_EVT_PARAMTYPE_UINT32, COUNT3_KEY},
92     {SOFTBUS_EVT_PARAMTYPE_UINT32, COUNT4_KEY},
93     {SOFTBUS_EVT_PARAMTYPE_UINT32, COUNT5_KEY},
94 };
95 
96 typedef struct {
97     ListNode node;
98     char moduleName[MODULE_NAME_MAX_LEN];
99     uint32_t discType;
100     uint64_t duration;
101     uint32_t repTimes;
102     uint32_t devNum;
103     uint32_t discTimes;
104 } DiscDetailNode;
105 
106 static char g_softbusVersion[SOFTBUS_HISYSEVT_PARAM_LEN] = "default softbus version";
107 static char g_packageVersion[SOFTBUS_HISYSEVT_PARAM_LEN] = "default package version";
108 static FirstDiscTime g_firstDiscTime[SOFTBUS_HISYSEVT_DISC_MEDIUM_BUTT];
109 
110 static SoftBusMutex g_discDetailLock = {0};
111 static ListNode g_discDetailList = {0};
112 
113 static uint32_t g_bleRssiRangeId[BLE_RSSI_RANGE_SIZE] = {0};
114 static uint32_t g_bleRssiRangeData[BLE_RSSI_RANGE_SIZE] = {0};
115 static SoftBusMutex g_bleRssiRangeLock = {0};
116 
ClearFirstDiscTime(void)117 static inline void ClearFirstDiscTime(void)
118 {
119     for (int32_t i = SOFTBUS_HISYSEVT_DISC_MEDIUM_BLE; i < SOFTBUS_HISYSEVT_DISC_MEDIUM_BUTT; i++) {
120         FirstDiscTime *record = &g_firstDiscTime[i];
121         record->mDiscTotalTime = 0;
122         record->mDiscTotalCount = 0;
123         record->mDiscCount1 = 0;
124         record->mDiscCount2 = 0;
125         record->mDiscCount3 = 0;
126         record->mDiscCount4 = 0;
127         record->mDiscCount5 = 0;
128     }
129 }
130 
ClearBleRssi(void)131 static inline void ClearBleRssi(void)
132 {
133     for (size_t rangeId = 0; rangeId < BLE_RSSI_RANGE_SIZE; rangeId++) {
134         g_bleRssiRangeId[rangeId] = 0;
135         g_bleRssiRangeData[rangeId] = 0;
136     }
137 }
138 
SetMsgParamNameAndType(SoftBusEvtReportMsg * msg,SoftBusEvtParamSize * paramSize)139 static int32_t SetMsgParamNameAndType(SoftBusEvtReportMsg *msg, SoftBusEvtParamSize *paramSize)
140 {
141     SoftBusEvtParam *param = NULL;
142     for (uint32_t i = SOFTBUS_EVT_PARAM_ZERO; i < msg->paramNum; i++) {
143         param = &msg->paramArray[i];
144         param->paramType = paramSize[i].paramType;
145         if (strcpy_s(param->paramName, SOFTBUS_HISYSEVT_PARAM_LEN, paramSize[i].paramName) != EOK) {
146             COMM_LOGE(COMM_EVENT, "set msg strcpy_s param name fail. paramName=%{public}s", paramSize[i].paramName);
147             return SOFTBUS_STRCPY_ERR;
148         }
149     }
150     return SOFTBUS_OK;
151 }
152 
SetDevFirstDiscMsgParamValve(SoftBusEvtReportMsg * msg,uint32_t medium)153 static int32_t SetDevFirstDiscMsgParamValve(SoftBusEvtReportMsg *msg, uint32_t medium)
154 {
155     SoftBusEvtParam *param = msg->paramArray;
156     errno_t ret = strcpy_s(param[SOFTBUS_EVT_PARAM_ZERO].paramValue.str, SOFTBUS_HISYSEVT_PARAM_LEN, g_softbusVersion);
157     COMM_CHECK_AND_RETURN_RET_LOGE(ret == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT, "strcpy softbus version fail");
158 
159     ret = strcpy_s(param[SOFTBUS_EVT_PARAM_ONE].paramValue.str, SOFTBUS_HISYSEVT_PARAM_LEN, g_packageVersion);
160     COMM_CHECK_AND_RETURN_RET_LOGE(ret == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT, "strcpy package version fail");
161 
162     param[SOFTBUS_EVT_PARAM_TWO].paramValue.u32v = medium;
163     FirstDiscTime *firstDisc = &g_firstDiscTime[medium];
164     param[SOFTBUS_EVT_PARAM_THREE].paramValue.u64v = firstDisc->mDiscTotalTime;
165     param[SOFTBUS_EVT_PARAM_FOUR].paramValue.u32v = firstDisc->mDiscTotalCount;
166     param[SOFTBUS_EVT_PARAM_FIVE].paramValue.u32v = firstDisc->mDiscCount1;
167     param[SOFTBUS_EVT_PARAM_SIX].paramValue.u32v = firstDisc->mDiscCount2;
168     param[SOFTBUS_EVT_PARAM_SEVEN].paramValue.u32v = firstDisc->mDiscCount3;
169     param[SOFTBUS_EVT_PARAM_EIGHT].paramValue.u32v = firstDisc->mDiscCount4;
170     param[SOFTBUS_EVT_PARAM_NINE].paramValue.u32v = firstDisc->mDiscCount5;
171     return SOFTBUS_OK;
172 }
173 
SoftBusCreateFirstDiscDurMsg(SoftBusEvtReportMsg * msg,uint32_t medium)174 static int32_t SoftBusCreateFirstDiscDurMsg(SoftBusEvtReportMsg *msg, uint32_t medium)
175 {
176     errno_t errnoRet = strcpy_s(msg->evtName, SOFTBUS_HISYSEVT_NAME_LEN, STATISTIC_EVT_FIRST_DISC_DURATION);
177     if (errnoRet != EOK) {
178         COMM_LOGE(COMM_EVENT,
179             "strcpy evtname fail. STATISTIC_EVT_FIRST_DISC_DURATION=%{public}s", STATISTIC_EVT_FIRST_DISC_DURATION);
180         return SOFTBUS_STRCPY_ERR;
181     }
182     msg->evtType = SOFTBUS_EVT_TYPE_STATISTIC;
183     msg->paramNum = FIRST_DISC_DURATION_PARAM_NUM;
184 
185     if (SetMsgParamNameAndType(msg, g_firstDsicTimeParam) != SOFTBUS_OK) {
186         COMM_LOGE(COMM_EVENT, "set param name and type fail");
187         return SOFTBUS_STRCPY_ERR;
188     }
189     if (SetDevFirstDiscMsgParamValve(msg, medium) != SOFTBUS_OK) {
190         COMM_LOGE(COMM_EVENT, "set param valve fail");
191         return SOFTBUS_STRCPY_ERR;
192     }
193     return SOFTBUS_OK;
194 }
195 
ClearDiscDetails(void)196 static inline void ClearDiscDetails(void)
197 {
198     DiscDetailNode *item = NULL;
199     DiscDetailNode *next = NULL;
200     if (g_discDetailList.prev == NULL && g_discDetailList.next == NULL) {
201         COMM_LOGE(COMM_EVENT, "g_discDetailList is NULL");
202         return;
203     }
204 
205     LIST_FOR_EACH_ENTRY_SAFE(item, next, &(g_discDetailList), DiscDetailNode, node) {
206         ListDelete(&item->node);
207         SoftBusFree(item);
208     }
209 }
210 
GetDiscDetailByModuleName(char * moduleName)211 static DiscDetailNode *GetDiscDetailByModuleName(char *moduleName)
212 {
213     DiscDetailNode *item = NULL;
214     DiscDetailNode *next = NULL;
215 
216     LIST_FOR_EACH_ENTRY_SAFE(item, next, &(g_discDetailList), DiscDetailNode, node) {
217         if (strcmp(item->moduleName, moduleName) == 0) {
218             return item;
219         }
220     }
221     return NULL;
222 }
223 
AddDiscDetailNode(DiscDetailNode ** discDetailNode,char * moduleName)224 static int32_t AddDiscDetailNode(DiscDetailNode **discDetailNode, char *moduleName)
225 {
226     COMM_CHECK_AND_RETURN_RET_LOGE(discDetailNode != NULL, SOFTBUS_INVALID_PARAM, COMM_EVENT, "invalid discDetailNode");
227     DiscDetailNode *newNode = (DiscDetailNode *)SoftBusCalloc(sizeof(DiscDetailNode));
228     COMM_CHECK_AND_RETURN_RET_LOGE(newNode != NULL, SOFTBUS_MALLOC_ERR, COMM_EVENT, "malloc fail");
229     if (strcpy_s(newNode->moduleName, MODULE_NAME_MAX_LEN, moduleName) != EOK) {
230         COMM_LOGE(COMM_EVENT, "strcpy module name fail. moduleName=%{public}s", moduleName);
231         SoftBusFree(newNode);
232         return SOFTBUS_STRCPY_ERR;
233     }
234     newNode->discType = SOFTBUS_HISYSEVT_DISC_MEDIUM_BLE;
235     newNode->devNum = 0;
236     newNode->discTimes = 0;
237     newNode->duration = 0;
238     newNode->repTimes = 0;
239     ListAdd(&g_discDetailList, &newNode->node);
240     *discDetailNode = newNode;
241     return SOFTBUS_OK;
242 }
243 
SoftBusCreateDiscDetailsMsg(SoftBusEvtReportMsg * msg,DiscDetailNode * discDetailItem)244 static int32_t SoftBusCreateDiscDetailsMsg(SoftBusEvtReportMsg *msg, DiscDetailNode *discDetailItem)
245 {
246     errno_t errnoRet = strcpy_s(msg->evtName, SOFTBUS_HISYSEVT_NAME_LEN, STATISTIC_EVT_DISCOVERY_DETAILS);
247     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
248         "strcpy evtName fail. STATISTIC_EVT_DISCOVERY_DETAILS=%{public}s", STATISTIC_EVT_DISCOVERY_DETAILS);
249     msg->evtType = SOFTBUS_EVT_TYPE_STATISTIC;
250     msg->paramNum = DISCOVERY_DETAILS_PARAM_NUM;
251 
252     SoftBusEvtParam* param = &msg->paramArray[SOFTBUS_EVT_PARAM_ZERO];
253     param->paramType = SOFTBUS_EVT_PARAMTYPE_STRING;
254     errnoRet = strcpy_s(param->paramName, SOFTBUS_HISYSEVT_PARAM_LEN, MODULE_KEY);
255     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
256         "strcpy paramName fail. MODULE_KEY=%{public}s", MODULE_KEY);
257     errnoRet = strcpy_s(param->paramValue.str, SOFTBUS_HISYSEVT_PARAM_LEN, discDetailItem->moduleName);
258     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
259         "strcpy moduleName fail. g_softbusVersion=%{public}s", g_softbusVersion);
260 
261     param = &msg->paramArray[SOFTBUS_EVT_PARAM_ONE];
262     param->paramType = SOFTBUS_EVT_PARAMTYPE_UINT32;
263     errnoRet = strcpy_s(param->paramName, SOFTBUS_HISYSEVT_PARAM_LEN, DISC_TYPE_KEY);
264     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
265         "strcpy paramName fail. DISC_TYPE_KEY=%{public}s", DISC_TYPE_KEY);
266     param->paramValue.u32v = discDetailItem->discType;
267 
268     param = &msg->paramArray[SOFTBUS_EVT_PARAM_TWO];
269     param->paramType = SOFTBUS_EVT_PARAMTYPE_UINT64;
270     errnoRet = strcpy_s(param->paramName, SOFTBUS_HISYSEVT_PARAM_LEN, DURATION_KEY);
271     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
272         "strcpy paramName fail. DURATION_KEY=%{public}s", DURATION_KEY);
273     param->paramValue.u64v = discDetailItem->duration;
274 
275     param = &msg->paramArray[SOFTBUS_EVT_PARAM_THREE];
276     param->paramType = SOFTBUS_EVT_PARAMTYPE_UINT32;
277     errnoRet = strcpy_s(param->paramName, SOFTBUS_HISYSEVT_PARAM_LEN, REPORT_TIMES_KEY);
278     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
279         "strcpy paramName fail. REPORT_TIMES_KEY=%{public}s", REPORT_TIMES_KEY);
280     param->paramValue.u32v = discDetailItem->repTimes;
281 
282     param = &msg->paramArray[SOFTBUS_EVT_PARAM_FOUR];
283     param->paramType = SOFTBUS_EVT_PARAMTYPE_UINT32;
284     errnoRet = strcpy_s(param->paramName, SOFTBUS_HISYSEVT_PARAM_LEN, DEVICE_NUM_KEY);
285     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
286         "strcpy paramName fail. DEVICE_NUM_KEY=%{public}s", DEVICE_NUM_KEY);
287     param->paramValue.u32v = discDetailItem->devNum;
288 
289     param = &msg->paramArray[SOFTBUS_EVT_PARAM_FIVE];
290     param->paramType = SOFTBUS_EVT_PARAMTYPE_UINT32;
291     errnoRet = strcpy_s(param->paramName, SOFTBUS_HISYSEVT_PARAM_LEN, DISC_TIMES_KEY);
292     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
293         "strcpy paramName fail. DISC_TIMES_KEY=%{public}s", DISC_TIMES_KEY);
294     param->paramValue.u32v = discDetailItem->discTimes;
295     return SOFTBUS_OK;
296 }
297 
SoftBusCreateDiscBleRssiMsg(SoftBusEvtReportMsg * msg)298 static int32_t SoftBusCreateDiscBleRssiMsg(SoftBusEvtReportMsg *msg)
299 {
300     errno_t errnoRet = strcpy_s(msg->evtName, SOFTBUS_HISYSEVT_NAME_LEN, STATISTIC_EVT_DISCOVERY_BLE_RSSI);
301     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
302         "strcpy evtname fail. STATISTIC_EVT_DISCOVERY_BLE_RSSI=%{public}s", STATISTIC_EVT_DISCOVERY_BLE_RSSI);
303     msg->evtType = SOFTBUS_EVT_TYPE_STATISTIC;
304     msg->paramNum = DISCOVERY_BLE_RSSI_PARAM_NUM;
305 
306     SoftBusEvtParam* param = &msg->paramArray[SOFTBUS_EVT_PARAM_ZERO];
307     param->paramType = SOFTBUS_EVT_PARAMTYPE_UINT32_ARRAY;
308     errnoRet = strcpy_s(param->paramName, SOFTBUS_HISYSEVT_PARAM_LEN, RANGE_ID_KEY);
309     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
310         "strcpy paramName fail. RANGE_ID_KEY=%{public}s", RANGE_ID_KEY);
311     for (int i = 0; i < SOFTBUS_HISYSEVT_PARAM_UINT32_ARRAY_SIZE; i++) {
312         param->paramValue.u32a[i] = g_bleRssiRangeId[i];
313     }
314 
315     param = &msg->paramArray[SOFTBUS_EVT_PARAM_ONE];
316     param->paramType = SOFTBUS_EVT_PARAMTYPE_UINT32_ARRAY;
317     errnoRet = strcpy_s(param->paramName, SOFTBUS_HISYSEVT_PARAM_LEN, RANGE_DATA_KEY);
318     COMM_CHECK_AND_RETURN_RET_LOGE(errnoRet == EOK, SOFTBUS_STRCPY_ERR, COMM_EVENT,
319         "strcpy paramName fail. RANGE_DATA_KEY=%{public}s", RANGE_DATA_KEY);
320     for (int i = 0; i < SOFTBUS_HISYSEVT_PARAM_UINT32_ARRAY_SIZE; i++) {
321         param->paramValue.u32a[i] = g_bleRssiRangeData[i];
322     }
323     return SOFTBUS_OK;
324 }
325 
SoftBusReportFirstDiscDurationEvt(void)326 static int32_t SoftBusReportFirstDiscDurationEvt(void)
327 {
328     COMM_LOGD(COMM_EVENT, "report first disc duration event");
329     SoftBusEvtReportMsg *msg = SoftbusCreateEvtReportMsg(FIRST_DISC_DURATION_PARAM_NUM);
330     COMM_CHECK_AND_RETURN_RET_LOGE(msg != NULL, SOFTBUS_MALLOC_ERR, COMM_EVENT, "create reportMsg fail");
331     int32_t ret = SOFTBUS_OK;
332     for (int32_t i = SOFTBUS_HISYSEVT_DISC_MEDIUM_BLE; i < SOFTBUS_HISYSEVT_DISC_MEDIUM_BUTT; i++) {
333         if (SoftBusMutexLock(&g_firstDiscTime[i].lock) != SOFTBUS_OK) {
334             SoftbusFreeEvtReportMsg(msg);
335             ClearFirstDiscTime();
336             COMM_LOGE(COMM_EVENT, "lock first disc time fail");
337             return SOFTBUS_LOCK_ERR;
338         }
339         if (g_firstDiscTime[i].mDiscTotalCount == 0) {
340             SoftBusMutexUnlock(&g_firstDiscTime[i].lock);
341             continue;
342         }
343         ret = SoftBusCreateFirstDiscDurMsg(msg, i);
344         if (ret != SOFTBUS_OK) {
345             ClearFirstDiscTime();
346             SoftBusMutexUnlock(&g_firstDiscTime[i].lock);
347             SoftbusFreeEvtReportMsg(msg);
348             COMM_LOGE(COMM_EVENT, "create first disc duration reportMsg fail");
349             return ret;
350         }
351         ret = SoftbusWriteHisEvt(msg);
352         if (ret != SOFTBUS_OK) {
353             ClearFirstDiscTime();
354             SoftBusMutexUnlock(&g_firstDiscTime[i].lock);
355             SoftbusFreeEvtReportMsg(msg);
356             COMM_LOGE(COMM_EVENT, "write first disc duration reportMsg fail");
357             return ret;
358         }
359         SoftBusMutexUnlock(&g_firstDiscTime[i].lock);
360     }
361     SoftbusFreeEvtReportMsg(msg);
362     ClearFirstDiscTime();
363     return SOFTBUS_OK;
364 }
365 
FreeDiscDetailsMsg(SoftBusEvtReportMsg * msg)366 static inline void FreeDiscDetailsMsg(SoftBusEvtReportMsg *msg)
367 {
368     SoftbusFreeEvtReportMsg(msg);
369     ClearDiscDetails();
370     (void)SoftBusMutexUnlock(&g_discDetailLock);
371 }
372 
SoftBusReportDiscDetailsEvt(void)373 static int32_t SoftBusReportDiscDetailsEvt(void)
374 {
375     COMM_LOGD(COMM_EVENT, "report disc detail event");
376     int32_t ret = SoftBusMutexLock(&g_discDetailLock);
377     COMM_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, COMM_EVENT, "disc detail lock fail");
378 
379     SoftBusEvtReportMsg *msg = SoftbusCreateEvtReportMsg(DISCOVERY_DETAILS_PARAM_NUM);
380     if (msg == NULL) {
381         COMM_LOGE(COMM_EVENT, "create disc details reportMsg fail");
382         ClearDiscDetails();
383         (void)SoftBusMutexUnlock(&g_discDetailLock);
384         return SOFTBUS_MEM_ERR;
385     }
386     DiscDetailNode *item = NULL;
387     DiscDetailNode *next = NULL;
388 
389     LIST_FOR_EACH_ENTRY_SAFE(item, next, &(g_discDetailList), DiscDetailNode, node) {
390         if (SoftBusCreateDiscDetailsMsg(msg, item) != SOFTBUS_OK) {
391             FreeDiscDetailsMsg(msg);
392             COMM_LOGE(COMM_EVENT, "create first disc detials reportMsg fail");
393             return SOFTBUS_STRCPY_ERR;
394         }
395         ret = SoftbusWriteHisEvt(msg);
396         if (ret != SOFTBUS_OK) {
397             COMM_LOGE(COMM_EVENT, "write disc detail evt fail");
398             FreeDiscDetailsMsg(msg);
399             return ret;
400         }
401     }
402     FreeDiscDetailsMsg(msg);
403     return SOFTBUS_OK;
404 }
405 
FreeDiscBleRssiMsg(SoftBusEvtReportMsg * msg)406 static inline void FreeDiscBleRssiMsg(SoftBusEvtReportMsg *msg)
407 {
408     SoftbusFreeEvtReportMsg(msg);
409     ClearBleRssi();
410     (void)SoftBusMutexUnlock(&g_bleRssiRangeLock);
411 }
412 
SoftBusReportDiscBleRssiEvt(void)413 static int32_t SoftBusReportDiscBleRssiEvt(void)
414 {
415     COMM_LOGD(COMM_EVENT, "report disc ble rssi event");
416     int32_t ret = SoftBusMutexLock(&g_bleRssiRangeLock);
417     COMM_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, COMM_EVENT, "ble rssi range lock fail");
418 
419     SoftBusEvtReportMsg *msg = SoftbusCreateEvtReportMsg(DISCOVERY_BLE_RSSI_PARAM_NUM);
420     if (msg == NULL) {
421         COMM_LOGE(COMM_EVENT, "create disc ble rssi reportMsg fail");
422         ClearBleRssi();
423         SoftBusMutexUnlock(&g_bleRssiRangeLock);
424         return SOFTBUS_MEM_ERR;
425     }
426     ret = SoftBusCreateDiscBleRssiMsg(msg);
427     if (ret != SOFTBUS_OK) {
428         FreeDiscBleRssiMsg(msg);
429         COMM_LOGE(COMM_EVENT, "create disc ble rssi reportMsg fail");
430         return ret;
431     }
432     ret = SoftbusWriteHisEvt(msg);
433     if (ret != SOFTBUS_OK) {
434         COMM_LOGE(COMM_EVENT, "write disc ble rssi evt fail");
435         FreeDiscBleRssiMsg(msg);
436         return ret;
437     }
438     FreeDiscBleRssiMsg(msg);
439     return SOFTBUS_OK;
440 }
441 
SoftbusRecordFirstDiscTime(SoftBusDiscMedium medium,uint64_t costTime)442 int32_t SoftbusRecordFirstDiscTime(SoftBusDiscMedium medium, uint64_t costTime)
443 {
444     COMM_LOGD(COMM_EVENT, "record first disc time start");
445     if (medium >= SOFTBUS_HISYSEVT_DISC_MEDIUM_BUTT || medium < SOFTBUS_HISYSEVT_DISC_MEDIUM_BLE) {
446         COMM_LOGE(COMM_EVENT, "medium is invalid");
447         return SOFTBUS_INVALID_PARAM;
448     }
449     if (SoftBusMutexLock(&g_firstDiscTime[medium].lock) != SOFTBUS_OK) {
450         COMM_LOGE(COMM_EVENT, "first disc time lock fail");
451         return SOFTBUS_LOCK_ERR;
452     }
453     FirstDiscTime *record = &g_firstDiscTime[medium];
454     uint64_t diffTime = UINT64_MAX - record->mDiscTotalTime;
455     if (diffTime > costTime) {
456         record->mDiscTotalTime += costTime;
457     } else {
458         COMM_LOGE(COMM_EVENT, "time is too long");
459         record->mDiscTotalTime = costTime - diffTime;
460     }
461     record->mDiscTotalCount++;
462     if (costTime > STANDARD_S) {
463         record->mDiscCount1++;
464     }
465     if (costTime > STANDARD_A) {
466         record->mDiscCount2++;
467     }
468     if (costTime > STANDARD_B) {
469         record->mDiscCount3++;
470     }
471     if (costTime > STANDARD_C) {
472         record->mDiscCount4++;
473     }
474     if (costTime > STANDARD_D) {
475         record->mDiscCount5++;
476     }
477     if (SoftBusMutexUnlock(&record->lock) != SOFTBUS_OK) {
478         COMM_LOGE(COMM_EVENT, "record first disc time unlock fail");
479         return SOFTBUS_LOCK_ERR;
480     }
481     return SOFTBUS_OK;
482 }
483 
AddAndCheckOverflowUint32(uint32_t a,uint32_t b)484 static inline uint32_t AddAndCheckOverflowUint32(uint32_t a, uint32_t b)
485 {
486     return (a > UINT32_MAX - b) ? UINT32_MAX : (a + b);
487 }
488 
AddAndCheckOverflowUint64(uint64_t a,uint64_t b)489 static inline uint64_t AddAndCheckOverflowUint64(uint64_t a, uint64_t b)
490 {
491     return (a > UINT64_MAX - b) ? UINT64_MAX : (a + b);
492 }
493 
SoftbusRecordBleDiscDetails(char * moduleName,uint64_t duration,uint32_t repTimes,uint32_t devNum,uint32_t discTimes)494 int32_t SoftbusRecordBleDiscDetails(char *moduleName, uint64_t duration, uint32_t repTimes, uint32_t devNum,
495                                     uint32_t discTimes)
496 {
497     COMM_LOGD(COMM_EVENT, "record ble disc detail");
498     COMM_CHECK_AND_RETURN_RET_LOGE(IsValidString(moduleName, MODULE_NAME_MAX_LEN), SOFTBUS_INVALID_PKGNAME, COMM_EVENT,
499         "invalid param!");
500     int32_t ret = SoftBusMutexLock(&g_discDetailLock);
501     COMM_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, COMM_EVENT, "disc detail lock fail");
502     DiscDetailNode *discDetailNode = GetDiscDetailByModuleName(moduleName);
503     if (discDetailNode == NULL) {
504         ret = AddDiscDetailNode(&discDetailNode, moduleName);
505         if (ret != SOFTBUS_OK) {
506             COMM_LOGE(COMM_EVENT, "add disc detail node fail");
507             SoftBusMutexUnlock(&g_discDetailLock);
508             return ret;
509         }
510     }
511 
512     discDetailNode->devNum = AddAndCheckOverflowUint32(discDetailNode->devNum, devNum);
513     discDetailNode->discTimes = AddAndCheckOverflowUint32(discDetailNode->discTimes, discTimes);
514     discDetailNode->duration = AddAndCheckOverflowUint64(discDetailNode->duration, duration);
515     discDetailNode->repTimes = AddAndCheckOverflowUint32(discDetailNode->repTimes, repTimes);
516     (void)SoftBusMutexUnlock(&g_discDetailLock);
517     return SOFTBUS_OK;
518 }
519 
SoftbusRecordDiscBleRssi(int32_t rssi)520 int32_t SoftbusRecordDiscBleRssi(int32_t rssi)
521 {
522     COMM_LOGD(COMM_EVENT, "record disc ble rssi");
523     if (rssi > MAX_RANGE_ID || rssi <= MIN_RANGE_ID) {
524         COMM_LOGE(COMM_EVENT, "invalid param");
525         return SOFTBUS_INVALID_PARAM;
526     }
527     COMM_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_bleRssiRangeLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR, COMM_EVENT,
528                                    "ble rssi range lock fail");
529 
530     uint32_t rangeId = (uint32_t)((MAX_RANGE_ID - rssi) / INTERVAL_OF_RSSI);
531     if (rangeId >= BLE_RSSI_RANGE_SIZE) {
532         COMM_LOGE(COMM_EVENT, "range id fail");
533         (void)SoftBusMutexUnlock(&g_bleRssiRangeLock);
534         return SOFTBUS_INVALID_NUM;
535     }
536     g_bleRssiRangeId[rangeId] = rangeId;
537     g_bleRssiRangeData[rangeId] += 1;
538     (void)SoftBusMutexUnlock(&g_bleRssiRangeLock);
539     return SOFTBUS_OK;
540 }
541 
InitDiscItemMutexLock(uint32_t index,SoftBusMutexAttr * mutexAttr)542 static int32_t InitDiscItemMutexLock(uint32_t index, SoftBusMutexAttr *mutexAttr)
543 {
544     if (SoftBusMutexInit(&g_firstDiscTime[index].lock, mutexAttr) != SOFTBUS_OK) {
545         COMM_LOGE(COMM_EVENT, "init first disc time lock fail");
546         return SOFTBUS_LOCK_ERR;
547     }
548     return SOFTBUS_OK;
549 }
550 
InitDiscEvtMutexLock(void)551 static int32_t InitDiscEvtMutexLock(void)
552 {
553     SoftBusMutexAttr mutexAttr = {SOFTBUS_MUTEX_RECURSIVE};
554     COMM_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexInit(&g_discDetailLock, &mutexAttr) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
555                                    COMM_EVENT, "init disc detail lock fail");
556     int32_t nRet = SoftBusMutexInit(&g_bleRssiRangeLock, &mutexAttr);
557     if (nRet != SOFTBUS_OK) {
558         COMM_LOGE(COMM_EVENT, "init ble rssi range lock fail");
559         (void)SoftBusMutexDestroy(&g_discDetailLock);
560     }
561     for (int32_t i = SOFTBUS_HISYSEVT_DISC_MEDIUM_BLE; i < SOFTBUS_HISYSEVT_DISC_MEDIUM_BUTT; i++) {
562         nRet = InitDiscItemMutexLock(i, &mutexAttr);
563     }
564     if (nRet != SOFTBUS_OK) {
565         COMM_LOGE(COMM_EVENT, "init disc first time lock fail");
566         (void)SoftBusMutexDestroy(&g_discDetailLock);
567         (void)SoftBusMutexDestroy(&g_bleRssiRangeLock);
568     }
569     return nRet;
570 }
571 
SoftbusReportDiscFault(SoftBusDiscMedium medium,int32_t errCode)572 int32_t SoftbusReportDiscFault(SoftBusDiscMedium medium, int32_t errCode)
573 {
574     COMM_LOGI(COMM_EVENT, "report disc fault event");
575     if (medium >= SOFTBUS_HISYSEVT_DISC_MEDIUM_BUTT || medium < SOFTBUS_HISYSEVT_DISC_MEDIUM_BLE) {
576         COMM_LOGE(COMM_EVENT, "medium is invalid");
577         return SOFTBUS_INVALID_PARAM;
578     }
579     SoftBusFaultEvtInfo discFaultInfo;
580     (void)memset_s(&discFaultInfo, sizeof(SoftBusFaultEvtInfo), 0, sizeof(SoftBusFaultEvtInfo));
581     discFaultInfo.moduleType = MODULE_TYPE_DISCOVERY;
582     discFaultInfo.linkType = medium;
583     discFaultInfo.errorCode = errCode;
584     int32_t ret = SoftBusReportBusCenterFaultEvt(&discFaultInfo);
585     if (ret != SOFTBUS_OK) {
586         COMM_LOGE(COMM_EVENT, "report disc fault evt fail");
587         return ret;
588     }
589     return SOFTBUS_OK;
590 }
591 
InitDiscStatisticSysEvt(void)592 int32_t InitDiscStatisticSysEvt(void)
593 {
594     ListInit(&g_discDetailList);
595     int32_t ret = InitDiscEvtMutexLock();
596     if (ret != SOFTBUS_OK) {
597         COMM_LOGE(COMM_EVENT, "disc Statistic Evt Lock Init Fail!");
598         return ret;
599     }
600     ClearDiscDetails();
601     ClearBleRssi();
602     ClearFirstDiscTime();
603 
604     SetStatisticEvtReportFunc(SOFTBUS_STATISTIC_EVT_DISC_BLE_RSSI, SoftBusReportDiscBleRssiEvt);
605     SetStatisticEvtReportFunc(SOFTBUS_STATISTIC_EVT_DISC_DETAILS, SoftBusReportDiscDetailsEvt);
606     SetStatisticEvtReportFunc(SOFTBUS_STATISTIC_EVT_FIRST_DISC_DURATION, SoftBusReportFirstDiscDurationEvt);
607     return SOFTBUS_OK;
608 }
DestroyMutex(void)609 static void DestroyMutex(void)
610 {
611     SoftBusMutexDestroy(&g_discDetailLock);
612     SoftBusMutexDestroy(&g_bleRssiRangeLock);
613     for (int32_t i = SOFTBUS_HISYSEVT_DISC_MEDIUM_BLE; i < SOFTBUS_HISYSEVT_DISC_MEDIUM_BUTT; i++) {
614         SoftBusMutexDestroy(&g_firstDiscTime[i].lock);
615     }
616 }
617 
DeinitDiscStatisticSysEvt(void)618 void DeinitDiscStatisticSysEvt(void)
619 {
620     ClearDiscDetails();
621     DestroyMutex();
622 }
623