• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "mine_softbus_listener.h"
17 
18 #include <dlfcn.h>
19 #include <mutex>
20 #include <pthread.h>
21 #include <securec.h>
22 #include <thread>
23 #include <unistd.h>
24 #include <condition_variable>
25 #include <list>
26 
27 #include "device_manager_service.h"
28 #include "dm_anonymous.h"
29 #include "dm_constants.h"
30 #include "dm_device_info.h"
31 #include "dm_log.h"
32 #include "parameter.h"
33 #include "system_ability_definition.h"
34 #include "softbus_listener.h"
35 #include "json_object.h"
36 #include "dm_crypto.h"
37 #include "openssl/sha.h"
38 #include "openssl/evp.h"
39 
40 namespace OHOS {
41 namespace DistributedHardware {
42 enum PulishStatus {
43     STATUS_UNKNOWN = 0,
44     ALLOW_BE_DISCOVERY = 1,
45     NOT_ALLOW_BE_DISCOVERY = 2,
46 };
47 constexpr uint32_t DM_MAX_SCOPE_TLV_NUM = 3;
48 constexpr uint32_t DM_MAX_VERTEX_TLV_NUM = 6;
49 constexpr int32_t SHA256_OUT_DATA_LEN = 32;
50 constexpr int32_t MAX_RETRY_TIMES = 30;
51 constexpr int32_t SOFTBUS_CHECK_INTERVAL = 100000; // 100ms
52 constexpr int32_t DM_MAX_DEVICE_ALIAS_LEN = 65;
53 constexpr int32_t DM_MAX_DEVICE_UDID_LEN = 65;
54 constexpr int32_t DM_INVALID_DEVICE_NUMBER = -1;
55 constexpr int32_t DM_TLV_VERTEX_DATA_OFFSET = 2;
56 constexpr int32_t DM_TLV_SCOPE_DATA_OFFSET = 4;
57 constexpr int32_t MAX_SOFTBUS_DELAY_TIME = 10;
58 #if (defined(MINE_HARMONY))
59 constexpr int32_t DM_SEARCH_BROADCAST_MIN_LEN = 18;
60 #endif
61 constexpr const char* FIELD_DEVICE_MODE = "findDeviceMode";
62 constexpr const char* FIELD_TRUST_OPTIONS = "tructOptions";
63 constexpr const char* FIELD_FILTER_OPTIONS = "filterOptions";
64 constexpr const char* DEVICE_ALIAS = "persist.devicealias";
65 constexpr const char* DEVICE_NUMBER = "persist.devicenumber";
66 constexpr char BROADCAST_VERSION = 1;
67 constexpr char FIND_ALL_DEVICE = 1;
68 constexpr char FIND_SCOPE_DEVICE = 2;
69 constexpr char FIND_VERTEX_DEVICE = 3;
70 constexpr char FIND_TRUST_DEVICE = 3;
71 constexpr char DEVICE_ALIAS_NUMBER = 1;
72 constexpr char DEVICE_TYPE_TYPE = 1;
73 constexpr char DEVICE_SN_TYPE = 2;
74 constexpr char DEVICE_UDID_TYPE = 3;
75 constexpr char FIND_NOTRUST_DEVICE = 2;
76 constexpr uint32_t EVP_OK = 1;
77 
78 static std::mutex g_matchWaitDeviceLock;
79 static std::mutex g_publishLnnLock;
80 static std::list<DeviceInfo> g_matchQueue;
81 static std::vector<std::string> pkgNameVec_ = {};
82 bool g_publishLnnFlag = false;
83 bool g_matchDealFlag = false;
84 std::condition_variable g_matchDealNotify;
85 std::condition_variable g_publishLnnNotify;
86 
87 static IPublishCb publishLNNCallback_ = {
88     .OnPublishResult = MineSoftbusListener::OnPublishResult,
89 #if (defined(MINE_HARMONY))
90     .OndeviceFound = MineSoftbusListener::OnPublishDeviceFound,
91     .onRePublish = MineSoftbusListener::OnRePublish
92 #endif
93 };
94 
FromJson(const JsonItemObject & object,VertexOptionInfo & optionInfo)95 void FromJson(const JsonItemObject &object, VertexOptionInfo &optionInfo)
96 {
97     if (!object.Contains("type") || !object["type"].IsString()) {
98         LOGE("OptionInfo type json key is not exist or type error.");
99         return;
100     }
101     if (!object.Contains("value") || !object["value"].IsString()) {
102         LOGE("OptionInfo value json key is not exist or type error.");
103         return;
104     }
105     object["type"].GetTo(optionInfo.type);
106     object["value"].GetTo(optionInfo.value);
107 }
108 
FromJson(const JsonItemObject & object,ScopeOptionInfo & optionInfo)109 void FromJson(const JsonItemObject &object, ScopeOptionInfo &optionInfo)
110 {
111     if (!object.Contains("deviceAlias") || !object["deviceAlias"].IsString()) {
112         LOGE("OptionInfo deviceAlias json key is not exist or error.");
113         return;
114     }
115     if (!object.Contains("startNumber") || !object["startNumber"].IsNumberInteger()) {
116         LOGE("OptionInfo startNumber json key is not exist or error.");
117         return;
118     }
119     if (!object.Contains("endNumber") || !object["endNumber"].IsNumberInteger()) {
120         LOGE("OptionInfo endNumber json key is not exist or error.");
121         return;
122     }
123     object["deviceAlias"].GetTo(optionInfo.deviceAlias);
124     object["startNumber"].GetTo(optionInfo.startNumber);
125     object["endNumber"].GetTo(optionInfo.endNumber);
126 }
127 
MineSoftbusListener()128 MineSoftbusListener::MineSoftbusListener()
129 {
130 #if (defined(MINE_HARMONY))
131     if (PublishDeviceDiscovery() != DM_OK) {
132         LOGE("failed to publish device sn sha256 hash to softbus");
133     }
134     {
135         std::lock_guard<std::mutex> autoLock(g_matchWaitDeviceLock);
136         g_matchDealFlag = true;
137         std::thread([]() { MatchSearchDealTask(); }).detach();
138     }
139 #endif
140     LOGI("MineSoftbusListener constructor");
141 }
142 
~MineSoftbusListener()143 MineSoftbusListener::~MineSoftbusListener()
144 {
145 #if (defined(MINE_HARMONY))
146     if (StopPublishLNN(DM_PKG_NAME.c_str(), DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID) != DM_OK) {
147         LOGI("fail to unregister service public callback");
148     }
149     {
150         std::lock_guard<std::mutex> autoLock(g_matchWaitDeviceLock);
151         g_matchDealFlag = false;
152     }
153 #endif
154     LOGI("SoftbusConnector destructor");
155 }
156 
RefreshSoftbusLNN(const string & pkgName,const string & searchJson,const DmSubscribeInfo & dmSubscribeInfo)157 int32_t MineSoftbusListener::RefreshSoftbusLNN(const string &pkgName, const string &searchJson,
158     const DmSubscribeInfo &dmSubscribeInfo)
159 {
160     LOGI("start to start discovery device with pkgName: %{public}s", pkgName.c_str());
161     size_t outLen = 0;
162     char output[DISC_MAX_CUST_DATA_LEN] = {0};
163     if (ParseSearchJson(pkgName, searchJson, output, &outLen) != DM_OK) {
164         LOGE("failed to parse searchJson with pkgName: %{public}s", pkgName.c_str());
165         return ERR_DM_JSON_PARSE_STRING;
166     }
167     SubscribeInfo subscribeInfo;
168     SetSubscribeInfo(dmSubscribeInfo, subscribeInfo);
169     if (SendBroadcastInfo(pkgName, subscribeInfo, output, outLen) != DM_OK) {
170         LOGE("failed to start quick discovery beause sending broadcast info.");
171         return ERR_DM_SOFTBUS_SEND_BROADCAST;
172     }
173     LOGI("start discovery device successfully with pkgName: %{public}s", pkgName.c_str());
174     return DM_OK;
175 }
176 
StopRefreshSoftbusLNN(uint16_t subscribeId)177 int32_t MineSoftbusListener::StopRefreshSoftbusLNN(uint16_t subscribeId)
178 {
179     int retValue = StopRefreshLNN(DM_PKG_NAME, subscribeId);
180     if (retValue != SOFTBUS_OK) {
181         LOGE("failed to stop discovery device with ret: %{public}d", retValue);
182         return retValue;
183     }
184     return DM_OK;
185 }
186 
OnPublishResult(int publishId,PublishResult reason)187 void MineSoftbusListener::OnPublishResult(int publishId, PublishResult reason)
188 {
189     std::unique_lock<std::mutex> locker(g_publishLnnLock);
190     if (reason == PUBLISH_LNN_SUCCESS) {
191         g_publishLnnFlag = true;
192         LOGI("publishLNN successfully with publishId: %{public}d.", publishId);
193     } else {
194         g_publishLnnFlag = false;
195         LOGE("failed to publishLNN with publishId: %{public}d, reason: %{public}d.", publishId, (int)reason);
196     }
197     g_publishLnnNotify.notify_one();
198 }
199 
OnPublishDeviceFound(const DeviceInfo * deviceInfo)200 void MineSoftbusListener::OnPublishDeviceFound(const DeviceInfo *deviceInfo)
201 {
202     if (deviceInfo == nullptr) {
203         LOGE("deviceInfo is nullptr.");
204         return;
205     }
206 #if (defined(MINE_HARMONY))
207     if (deviceInfo->businessDataLen >= DISC_MAX_CUST_DATA_LEN ||
208         deviceInfo->businessDataLen < DM_SEARCH_BROADCAST_MIN_LEN) {
209         LOGE("deviceInfo data is too long or to short with dataLen: %{public}u", deviceInfo->businessDataLen);
210         return;
211     }
212     LOGI("broadcast data is received with DataLen: %{public}u", deviceInfo->businessDataLen);
213 #endif
214     std::unique_lock<std::mutex> autoLock(g_matchWaitDeviceLock);
215     g_matchQueue.push_back(*deviceInfo);
216     g_matchDealNotify.notify_one();
217 }
218 
OnRePublish(void)219 void MineSoftbusListener::OnRePublish(void)
220 {
221     LOGI("try to rePublishLNN");
222     int32_t retryTimes = 0;
223     PublishInfo publishInfo;
224     publishInfo.publishId = DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID;
225     publishInfo.mode = DiscoverMode::DISCOVER_MODE_PASSIVE;
226     publishInfo.medium = ExchangeMedium::COAP;
227     publishInfo.freq = ExchangeFreq::LOW;
228     publishInfo.capability = DM_CAPABILITY_OSD;
229     publishInfo.capabilityData = nullptr;
230     publishInfo.dataLen = 0;
231     retryTimes = 0;
232     while (PublishLNN(DM_PKG_NAME, &publishInfo, &publishLNNCallback_) != SOFTBUS_OK &&
233         retryTimes <= MAX_RETRY_TIMES) {
234         retryTimes++;
235         LOGW("failed to rePublishLNN with retryTimes: %{public}d", retryTimes);
236         usleep(SOFTBUS_CHECK_INTERVAL);
237     }
238     LOGI("rePublishLNN finish");
239 }
240 
ParseSearchJson(const string & pkgName,const string & searchJson,char * output,size_t * outLen)241 int32_t MineSoftbusListener::ParseSearchJson(const string &pkgName, const string &searchJson, char *output,
242     size_t *outLen)
243 {
244     JsonObject object(searchJson);
245     if (object.IsDiscarded()) {
246         LOGE("failed to parse filter options string.");
247         return ERR_DM_INVALID_JSON_STRING;
248     }
249     int32_t retValue = DM_OK;
250     uint32_t findMode = 0;
251     if (IsUint32(object, FIELD_DEVICE_MODE)) {
252         findMode = object[FIELD_DEVICE_MODE].Get<uint32_t>();
253     }
254     LOGI("quick search device mode is: %{public}u", findMode);
255     switch (findMode) {
256         case FIND_ALL_DEVICE:
257             retValue = ParseSearchAllDevice(object, pkgName, output, outLen);
258             break;
259         case FIND_SCOPE_DEVICE:
260             retValue = ParseSearchScopeDevice(object, pkgName, output, outLen);
261             break;
262         case FIND_VERTEX_DEVICE:
263             retValue = ParseSearchVertexDevice(object, pkgName, output, outLen);
264             break;
265         default:
266             LOGE("key type is not match key: %{public}s.", FIELD_DEVICE_MODE);
267     }
268     if (retValue != DM_OK) {
269         LOGE("fail to parse search find device with ret: %{public}d.", retValue);
270         return retValue;
271     }
272     LOGI("parse search json successfully with pkgName: %{public}s, outLen: %{public}zu,", pkgName.c_str(), *outLen);
273     return DM_OK;
274 }
275 
ParseSearchAllDevice(const JsonObject & object,const string & pkgName,char * output,size_t * outLen)276 int32_t MineSoftbusListener::ParseSearchAllDevice(const JsonObject &object, const string &pkgName, char *output,
277     size_t *outLen)
278 {
279     BroadcastHead broadcastHead;
280     if (SetBroadcastHead(object, pkgName, broadcastHead) != DM_OK) {
281         LOGE("fail to set broadcast head.");
282         return ERR_DM_FAILED;
283     }
284     broadcastHead.tlvDataLen = 0;
285     broadcastHead.findMode = FIND_ALL_DEVICE;
286     AddHeadToBroadcast(broadcastHead, output);
287     *outLen = sizeof(BroadcastHead);
288     return DM_OK;
289 }
290 
ParseSearchScopeDevice(const JsonObject & object,const string & pkgName,char * output,size_t * outLen)291 int32_t MineSoftbusListener::ParseSearchScopeDevice(const JsonObject &object, const string &pkgName, char *output,
292     size_t *outLen)
293 {
294     BroadcastHead broadcastHead;
295     if (SetBroadcastHead(object, pkgName, broadcastHead) != DM_OK) {
296         LOGE("fail to set broadcast head.");
297         return ERR_DM_FAILED;
298     }
299     if (!object.Contains(FIELD_FILTER_OPTIONS) || !object[FIELD_FILTER_OPTIONS].IsArray()) {
300         LOGE("failed to get %{public}s scope cjson object or is not array.", FIELD_FILTER_OPTIONS);
301         return ERR_DM_FAILED;
302     }
303     std::vector<ScopeOptionInfo> optionInfoVec;
304     object[FIELD_FILTER_OPTIONS].Get(optionInfoVec);
305     size_t optionInfoVecSize = optionInfoVec.size();
306     if (optionInfoVecSize == 0 || optionInfoVecSize > DM_MAX_SCOPE_TLV_NUM) {
307         LOGE("failed to get search josn array lenght.");
308         return ERR_DM_INVALID_JSON_STRING;
309     }
310     LOGI("start to parse scope search array json with size:%{public}zu.", optionInfoVecSize);
311     if (ParseScopeDeviceJsonArray(optionInfoVec, output + sizeof(BroadcastHead), outLen) != DM_OK) {
312         LOGE("failed to parse scope json array.");
313         return ERR_DM_FAILED;
314     }
315 
316     broadcastHead.findMode = FIND_SCOPE_DEVICE;
317     broadcastHead.tlvDataLen = *outLen;
318     AddHeadToBroadcast(broadcastHead, output);
319     *outLen = *outLen + sizeof(BroadcastHead);
320     return DM_OK;
321 }
322 
ParseSearchVertexDevice(const JsonObject & object,const string & pkgName,char * output,size_t * outLen)323 int32_t MineSoftbusListener::ParseSearchVertexDevice(const JsonObject &object, const string &pkgName, char *output,
324     size_t *outLen)
325 {
326     BroadcastHead broadcastHead;
327     if (SetBroadcastHead(object, pkgName, broadcastHead) != DM_OK) {
328         LOGE("fail to set broadcast head.");
329         return ERR_DM_FAILED;
330     }
331     if (!object.Contains(FIELD_FILTER_OPTIONS) || !object[FIELD_FILTER_OPTIONS].IsArray()) {
332         LOGE("failed to get %{public}s vertex cjson object or is not array.", FIELD_FILTER_OPTIONS);
333         return ERR_DM_FAILED;
334     }
335     std::vector<VertexOptionInfo> optionInfoVec;
336     object[FIELD_FILTER_OPTIONS].Get(optionInfoVec);
337     size_t optionInfoVecSize = optionInfoVec.size();
338     if (optionInfoVecSize == 0 || optionInfoVecSize > DM_MAX_VERTEX_TLV_NUM) {
339         LOGE("failed to get search josn array lenght.");
340         return ERR_DM_FAILED;
341     }
342     LOGI("start to parse vertex search array json with size: %{public}zu.", optionInfoVecSize);
343     if (ParseVertexDeviceJsonArray(optionInfoVec, output + sizeof(BroadcastHead), outLen) != DM_OK) {
344         LOGE("failed to parse vertex json array.");
345         return ERR_DM_FAILED;
346     }
347 
348     broadcastHead.findMode = FIND_VERTEX_DEVICE;
349     broadcastHead.tlvDataLen = *outLen;
350     AddHeadToBroadcast(broadcastHead, output);
351     *outLen = *outLen + sizeof(BroadcastHead);
352     return DM_OK;
353 }
354 
SetBroadcastHead(const JsonObject & object,const string & pkgName,BroadcastHead & broadcastHead)355 int32_t MineSoftbusListener::SetBroadcastHead(const JsonObject &object, const string &pkgName,
356     BroadcastHead &broadcastHead)
357 {
358     broadcastHead.version = BROADCAST_VERSION;
359     broadcastHead.headDataLen = sizeof(BroadcastHead);
360     broadcastHead.tlvDataLen = 0;
361     broadcastHead.findMode = 0;
362     if (SetBroadcastTrustOptions(object, broadcastHead) != DM_OK) {
363         LOGE("fail to set trust options to search broadcast.");
364         return ERR_DM_FAILED;
365     }
366     if (SetBroadcastPkgname(pkgName, broadcastHead) != DM_OK) {
367         LOGE("fail to set pkgname to search broadcast.");
368         return ERR_DM_FAILED;
369     }
370     return DM_OK;
371 }
372 
AddHeadToBroadcast(const BroadcastHead & broadcastHead,char * output)373 void MineSoftbusListener::AddHeadToBroadcast(const BroadcastHead &broadcastHead, char *output)
374 {
375     size_t startPos = 0;
376     output[startPos++] = broadcastHead.version;
377     output[startPos++] = broadcastHead.headDataLen;
378     output[startPos++] = broadcastHead.tlvDataLen;
379     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
380         output[startPos++] = broadcastHead.pkgNameHash[i];
381     }
382     output[startPos++] = broadcastHead.findMode;
383     output[startPos++] = broadcastHead.trustFilter;
384     LOGI("find device info with version: %{public}d, findMode: %{public}d, HeadLen: %{public}d, tlvDataLen: %{public}d,"
385         "trustFilter: %{public}d", (int)(broadcastHead.version), (int)(broadcastHead.findMode),
386         (int)(broadcastHead.headDataLen), (int)(broadcastHead.tlvDataLen), (int)(broadcastHead.trustFilter));
387 }
388 
ParseScopeDeviceJsonArray(const vector<ScopeOptionInfo> & optionInfo,char * output,size_t * outLen)389 int32_t MineSoftbusListener::ParseScopeDeviceJsonArray(const vector<ScopeOptionInfo> &optionInfo,
390     char *output, size_t *outLen)
391 {
392     errno_t retValue = EOK;
393     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
394     size_t arraySize = optionInfo.size();
395 
396     for (size_t i = 0; i < arraySize; i++) {
397         if (GetSha256Hash(optionInfo[i].deviceAlias.c_str(),
398                           optionInfo[i].deviceAlias.size(), sha256Out) != DM_OK) {
399             LOGE("failed to get sha256 hash with index: %{public}zu, value: %{public}s.", i,
400                 optionInfo[i].deviceAlias.c_str());
401             return ERR_DM_FAILED;
402         }
403         output[(*outLen)++] = DEVICE_ALIAS_NUMBER;
404         output[(*outLen)++] = DM_HASH_DATA_LEN;
405         output[(*outLen)++] = DM_DEVICE_NUMBER_LEN;
406         output[(*outLen)++] = DM_DEVICE_NUMBER_LEN;
407         for (size_t j = 0; j < DM_HASH_DATA_LEN; j++) {
408             output[(*outLen)++] = sha256Out[j];
409         }
410         retValue = sprintf_s(&output[*outLen], DM_DEVICE_NUMBER_LEN, "%010d", optionInfo[i].startNumber);
411         if (retValue <= 0) {
412             LOGE("fail to add device number to data buffer");
413             return ERR_DM_FAILED;
414         }
415         *outLen = *outLen + DM_DEVICE_NUMBER_LEN;
416         retValue = sprintf_s(&output[*outLen], DM_DEVICE_NUMBER_LEN, "%010d", optionInfo[i].endNumber);
417         if (retValue <= 0) {
418             LOGE("fail to add device number to data buffer");
419             return ERR_DM_FAILED;
420         }
421         *outLen = *outLen + DM_DEVICE_NUMBER_LEN;
422     }
423     return DM_OK;
424 }
425 
ParseVertexDeviceJsonArray(const std::vector<VertexOptionInfo> & optionInfo,char * output,size_t * outLen)426 int32_t MineSoftbusListener::ParseVertexDeviceJsonArray(const std::vector<VertexOptionInfo> &optionInfo,
427     char *output, size_t *outLen)
428 {
429     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
430     size_t arraySize = optionInfo.size();
431 
432     for (size_t i = 0; i < arraySize; i++) {
433         if (optionInfo[i].type.empty() || optionInfo[i].value.empty()) {
434             LOGE("failed to get type or value cjosn object with index: %{public}zu", i);
435             continue;
436         }
437         if (optionInfo[i].type == "deviceUdid") {
438             output[(*outLen)++] = DEVICE_UDID_TYPE;
439         } else if (optionInfo[i].type == "deviceType") {
440             output[(*outLen)++] = DEVICE_TYPE_TYPE;
441         } else if (optionInfo[i].type == "deviceSn") {
442             output[(*outLen)++] = DEVICE_SN_TYPE;
443         } else {
444             LOGE("type:%{public}s is not allowed with index: %{public}zu.", optionInfo[i].type.c_str(), i);
445             return ERR_DM_FAILED;
446         }
447         output[(*outLen)++] = DM_HASH_DATA_LEN;
448         if (GetSha256Hash((const char *) optionInfo[i].value.data(), optionInfo[i].value.size(),
449                           sha256Out) != DM_OK) {
450             LOGE("failed to get value sha256 hash with index: %{public}zu", i);
451             return ERR_DM_GET_DATA_SHA256_HASH;
452         }
453         for (size_t j = 0; j < DM_HASH_DATA_LEN; j++) {
454             output[(*outLen)++] = sha256Out[j];
455         }
456     }
457     return DM_OK;
458 }
459 
GetSha256Hash(const char * data,size_t len,char * output)460 int32_t MineSoftbusListener::GetSha256Hash(const char *data, size_t len, char *output)
461 {
462     if (data == nullptr || output == nullptr || len == 0) {
463         LOGE("Input param invalied.");
464         return ERR_DM_INPUT_PARA_INVALID;
465     }
466     SHA256_CTX ctx;
467     SHA256_Init(&ctx);
468     SHA256_Update(&ctx, data, len);
469     SHA256_Final((unsigned char *)output, &ctx);
470     return DM_OK;
471 }
472 
SetBroadcastTrustOptions(const JsonObject & object,BroadcastHead & broadcastHead)473 int32_t MineSoftbusListener::SetBroadcastTrustOptions(const JsonObject &object, BroadcastHead &broadcastHead)
474 {
475     if (!object.Contains(FIELD_TRUST_OPTIONS)) {
476         broadcastHead.trustFilter = 0;
477         return DM_OK;
478     } else if (object[FIELD_TRUST_OPTIONS].IsBoolean() && object[FIELD_TRUST_OPTIONS].Get<bool>()) {
479         broadcastHead.trustFilter = FIND_TRUST_DEVICE;
480         return DM_OK;
481     } else if (object[FIELD_TRUST_OPTIONS].IsBoolean() && !object[FIELD_TRUST_OPTIONS].Get<bool>()) {
482         broadcastHead.trustFilter = FIND_NOTRUST_DEVICE;
483         return DM_OK;
484     }
485     LOGE("key type is error with key: %{public}s", FIELD_TRUST_OPTIONS);
486     return ERR_DM_FAILED;
487 }
488 
SetBroadcastPkgname(const string & pkgName,BroadcastHead & broadcastHead)489 int32_t MineSoftbusListener::SetBroadcastPkgname(const string &pkgName, BroadcastHead &broadcastHead)
490 {
491     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
492     if (GetSha256Hash((const char *)pkgName.c_str(), pkgName.size(), sha256Out) != DM_OK) {
493         LOGE("failed to get search pkgName sha256 hash while search all device.");
494         return ERR_DM_FAILED;
495     }
496     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
497         broadcastHead.pkgNameHash[i] = sha256Out[i];
498     }
499     return DM_OK;
500 }
501 
SetSubscribeInfo(const DmSubscribeInfo & dmSubscribeInfo,SubscribeInfo & subscribeInfo)502 void MineSoftbusListener::SetSubscribeInfo(const DmSubscribeInfo &dmSubscribeInfo, SubscribeInfo &subscribeInfo)
503 {
504     subscribeInfo.subscribeId = dmSubscribeInfo.subscribeId;
505     subscribeInfo.mode = (DiscoverMode)dmSubscribeInfo.mode;
506     subscribeInfo.medium = (ExchangeMedium)dmSubscribeInfo.medium;
507     subscribeInfo.freq = (ExchangeFreq)dmSubscribeInfo.freq;
508     subscribeInfo.isSameAccount = dmSubscribeInfo.isSameAccount;
509     subscribeInfo.isWakeRemote = dmSubscribeInfo.isWakeRemote;
510     subscribeInfo.capability = dmSubscribeInfo.capability;
511     subscribeInfo.capabilityData = nullptr;
512     subscribeInfo.dataLen = 0;
513 }
514 
SendBroadcastInfo(const string & pkgName,SubscribeInfo & subscribeInfo,char * output,size_t outputLen)515 int32_t MineSoftbusListener::SendBroadcastInfo(const string &pkgName, SubscribeInfo &subscribeInfo, char *output,
516     size_t outputLen)
517 {
518     size_t base64OutLen = 0;
519     int retValue;
520     char base64Out[DISC_MAX_CUST_DATA_LEN] = {0};
521     retValue = DmBase64Encode(base64Out, DISC_MAX_CUST_DATA_LEN, output, outputLen, base64OutLen);
522     if (retValue != 0) {
523         LOGE("failed to get search data base64 encode type data with ret: %{public}d.", retValue);
524         return ERR_DM_FAILED;
525     }
526 #if (defined(MINE_HARMONY))
527     subscribeInfo.custData = base64Out;
528     subscribeInfo.custDataLen = base64OutLen;
529     IRefreshCallback softbusRefreshCallback_ = SoftbusListener::GetSoftbusRefreshCb();
530     retValue = RefreshLNN(DM_PKG_NAME, &subscribeInfo, &softbusRefreshCallback_);
531     if (retValue != SOFTBUS_OK) {
532         LOGE("failed to start to refresh quick discovery with ret: %{public}d.", retValue);
533         return ERR_DM_FAILED;
534     }
535 #endif
536     LOGI("send search broadcast info by softbus successfully with dataLen: %{public}zu, pkgName: %{public}s.",
537         base64OutLen, pkgName.c_str());
538     return DM_OK;
539 }
540 
DmBase64Encode(char * output,size_t outputLen,const char * input,size_t inputLen,size_t & base64OutLen)541 int32_t MineSoftbusListener::DmBase64Encode(char *output, size_t outputLen, const char *input,
542     size_t inputLen, size_t &base64OutLen)
543 {
544     LOGI("MineSoftbusListener::DmBase64Encode");
545     if (output == nullptr || input == nullptr || outputLen == 0 || inputLen == 0) {
546         LOGE("Input param invalied.");
547         return ERR_DM_INPUT_PARA_INVALID;
548     }
549     int32_t outLen = 0;
550     base64OutLen = 0;
551     EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
552     if (ctx == nullptr) {
553         LOGE("create ctx failed.");
554         EVP_ENCODE_CTX_free(ctx);
555         return ERR_DM_FAILED;
556     }
557     EVP_EncodeInit(ctx);
558     if (EVP_EncodeUpdate(ctx, (unsigned char *)output, &outLen, (const unsigned char *)input, inputLen) != EVP_OK) {
559         LOGE("EVP_EncodeUpdate failed.");
560         EVP_ENCODE_CTX_free(ctx);
561         return ERR_DM_FAILED;
562     }
563     base64OutLen += static_cast<size_t>(outLen);
564     EVP_EncodeFinal(ctx, (unsigned char *)(output + outLen), &outLen);
565     base64OutLen += static_cast<size_t>(outLen);
566     EVP_ENCODE_CTX_free(ctx);
567     return DM_OK;
568 }
569 
DmBase64Decode(char * output,size_t outputLen,const char * input,size_t inputLen,size_t & base64OutLen)570 int32_t MineSoftbusListener::DmBase64Decode(char *output, size_t outputLen, const char *input,
571     size_t inputLen, size_t &base64OutLen)
572 {
573     LOGI("MineSoftbusListener::DmBase64Decode");
574     if (output == nullptr || outputLen == 0 || input == nullptr || inputLen == 0) {
575         LOGE("Input param invalied.");
576         return ERR_DM_INPUT_PARA_INVALID;
577     }
578     base64OutLen = 0;
579     int32_t outLen = 0;
580     EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
581     if (ctx == nullptr) {
582         LOGE("create ctx failed.");
583         EVP_ENCODE_CTX_free(ctx);
584         return ERR_DM_FAILED;
585     }
586     EVP_DecodeInit(ctx);
587     if (EVP_DecodeUpdate(ctx, (unsigned char *)output, &outLen, (const unsigned char *)input, inputLen) != EVP_OK) {
588         LOGE("EVP_DecodeUpdate failed.");
589         EVP_ENCODE_CTX_free(ctx);
590         return ERR_DM_FAILED;
591     }
592     base64OutLen += static_cast<size_t>(outLen);
593     if (EVP_DecodeFinal(ctx, (unsigned char *)(output + outLen), &outLen) != EVP_OK) {
594         LOGE("EVP_DecodeFinal failed.");
595         EVP_ENCODE_CTX_free(ctx);
596         return ERR_DM_FAILED;
597     }
598     base64OutLen += static_cast<size_t>(outLen);
599     EVP_ENCODE_CTX_free(ctx);
600     return DM_OK;
601 }
602 
PublishDeviceDiscovery(void)603 int32_t MineSoftbusListener::PublishDeviceDiscovery(void)
604 {
605     PublishInfo publishInfo;
606     publishInfo.publishId = DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID;
607     publishInfo.mode = DiscoverMode::DISCOVER_MODE_ACTIVE;
608     publishInfo.medium = ExchangeMedium::AUTO;
609     publishInfo.freq = ExchangeFreq::LOW;
610     publishInfo.capability = DM_CAPABILITY_OSD;
611     publishInfo.capabilityData = nullptr;
612     publishInfo.dataLen = 0;
613     int retValue = PublishLNN(DM_PKG_NAME, &publishInfo, &publishLNNCallback_);
614     if (retValue != SOFTBUS_OK) {
615         LOGE("failed to call softbus publishLNN function with ret: %{public}d.", retValue);
616         return retValue;
617     }
618     std::chrono::seconds timeout = std::chrono::seconds(MAX_SOFTBUS_DELAY_TIME);
619     std::unique_lock<std::mutex> locker(g_publishLnnLock);
620     if (!g_publishLnnNotify.wait_for(locker, timeout, [] { return g_publishLnnFlag; })) {
621         g_publishLnnFlag = false;
622         return ERR_DM_SOFTBUS_PUBLISH_SERVICE;
623     }
624     g_publishLnnFlag = false;
625     return DM_OK;
626 }
627 
MatchSearchDealTask(void)628 void MineSoftbusListener::MatchSearchDealTask(void)
629 {
630     LOGI("the match deal task has started to run.");
631 #if (defined(MINE_HARMONY))
632     DeviceInfo tempDeviceInfo;
633     while (true) {
634         {
635             std::unique_lock<std::mutex> autoLock(g_matchWaitDeviceLock);
636             if (!g_matchDealFlag) {
637                 LOGI("the match deal task will stop to run.");
638                 return;
639             }
640             g_matchDealNotify.wait(autoLock, [] { return !g_matchQueue.empty(); });
641             tempDeviceInfo = g_matchQueue.front();
642             g_matchQueue.pop_front();
643         }
644         if (ParseBroadcastInfo(tempDeviceInfo) != DM_OK) {
645             LOGE("failed to parse broadcast info.");
646         }
647     }
648 #endif
649 }
650 
ParseBroadcastInfo(DeviceInfo & deviceInfo)651 int32_t MineSoftbusListener::ParseBroadcastInfo(DeviceInfo &deviceInfo)
652 {
653     char output[DISC_MAX_CUST_DATA_LEN] = {0};
654     if (!GetBroadcastData(deviceInfo, output, DISC_MAX_CUST_DATA_LEN)) {
655         LOGE("fail to get broadcast data");
656         return ERR_DM_FAILED;
657     }
658     DevicePolicyInfo devicePolicyInfo;
659     Action matchResult = BUSINESS_EXACT_NOT_MATCH;
660     BroadcastHead broadcastHead = *(BroadcastHead *)output;
661     LOGI("parse device info with version: %{public}d, findMode: %{public}d, HeadLen: %{public}d, tlvDataLen:"
662         "%{public}d, trustFilter: %{public}d", (int)(broadcastHead.version), (int)(broadcastHead.findMode),
663         (int)(broadcastHead.headDataLen), (int)(broadcastHead.tlvDataLen), (int)broadcastHead.trustFilter);
664 
665     char findMode = broadcastHead.findMode;
666     switch (findMode) {
667         case FIND_ALL_DEVICE:
668             matchResult = MatchSearchAllDevice(deviceInfo, broadcastHead);
669             break;
670         case FIND_SCOPE_DEVICE:
671             GetScopeDevicePolicyInfo(devicePolicyInfo);
672             matchResult = MatchSearchScopeDevice(deviceInfo, output + sizeof(BroadcastHead),
673                 devicePolicyInfo, broadcastHead);
674             break;
675         case FIND_VERTEX_DEVICE:
676             GetVertexDevicePolicyInfo(devicePolicyInfo);
677             matchResult = MatchSearchVertexDevice(deviceInfo, output + sizeof(BroadcastHead),
678                 devicePolicyInfo, broadcastHead);
679             break;
680         default:
681             LOGE("key type is not match key: %{public}s.", FIELD_DEVICE_MODE);
682             return ERR_DM_FAILED;
683     }
684     LOGI("parse broadcast info matchResult: %{public}d.", (int)matchResult);
685     if (matchResult == BUSINESS_EXACT_MATCH) {
686         return SendReturnwave(deviceInfo, broadcastHead, matchResult);
687     }
688     return DM_OK;
689 }
690 
GetBroadcastData(DeviceInfo & deviceInfo,char * output,size_t outLen)691 bool MineSoftbusListener::GetBroadcastData(DeviceInfo &deviceInfo, char *output, size_t outLen)
692 {
693     size_t base64OutLen = 0;
694 #if (defined(MINE_HARMONY))
695     size_t dataLen = deviceInfo.businessDataLen;
696     unsigned char *data = (unsigned char *)deviceInfo.businessData;
697     int retValue = DmBase64Decode(output, outLen, data, dataLen, base64OutLen);
698     if (retValue != 0) {
699         LOGE("failed to with ret: %{public}d.", retValue);
700         return false;
701     }
702     if (base64OutLen < DM_SEARCH_BROADCAST_MIN_LEN) {
703         LOGE("data length too short with outLen: %{public}zu.", base64OutLen);
704         return false;
705     }
706 #endif
707     BroadcastHead *broadcastHead = (BroadcastHead *)output;
708     size_t hDataLen = broadcastHead->headDataLen;
709     size_t tlvDataLen = broadcastHead->tlvDataLen;
710     if (hDataLen >= DISC_MAX_CUST_DATA_LEN || tlvDataLen >= DISC_MAX_CUST_DATA_LEN ||
711         (hDataLen + tlvDataLen) != base64OutLen) {
712         LOGE("data lenght is not valid with: headDataLen: %{public}zu, tlvDataLen: %{public}zu, base64OutLen:"
713             "%{public}zu.", hDataLen, tlvDataLen, base64OutLen);
714         return false;
715     }
716     return true;
717 }
718 
MatchSearchAllDevice(DeviceInfo & deviceInfo,const BroadcastHead & broadcastHead)719 Action MineSoftbusListener::MatchSearchAllDevice(DeviceInfo &deviceInfo, const BroadcastHead &broadcastHead)
720 {
721     if (broadcastHead.trustFilter == 0) {
722         return BUSINESS_EXACT_MATCH;
723     }
724     if ((deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_TRUST_DEVICE)) {
725         return BUSINESS_EXACT_MATCH;
726     } else if ((deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_NOTRUST_DEVICE)) {
727         return BUSINESS_EXACT_NOT_MATCH;
728     } else if (!(deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_TRUST_DEVICE)) {
729         return BUSINESS_EXACT_NOT_MATCH;
730     } else {
731         return BUSINESS_EXACT_MATCH;
732     }
733 }
734 
GetScopeDevicePolicyInfo(DevicePolicyInfo & devicePolicyInfo)735 void MineSoftbusListener::GetScopeDevicePolicyInfo(DevicePolicyInfo &devicePolicyInfo)
736 {
737     devicePolicyInfo.numberValid = false;
738     devicePolicyInfo.aliasHashValid = false;
739     if (GetDeviceAliasHash(devicePolicyInfo.aliasHash)) {
740         devicePolicyInfo.aliasHashValid = true;
741     }
742     if (GetDeviceNumber(devicePolicyInfo.number)) {
743         devicePolicyInfo.numberValid = true;
744     }
745 }
746 
MatchSearchScopeDevice(DeviceInfo & deviceInfo,char * output,const DevicePolicyInfo & devicePolicyInfo,const BroadcastHead & broadcastHead)747 Action MineSoftbusListener::MatchSearchScopeDevice(DeviceInfo &deviceInfo, char *output,
748     const DevicePolicyInfo &devicePolicyInfo, const BroadcastHead &broadcastHead)
749 {
750     vector<int> matchItemNum(DM_MAX_SCOPE_TLV_NUM, 0);
751     vector<int> matchItemResult(DM_MAX_SCOPE_TLV_NUM, 0);
752 
753     if ((deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_NOTRUST_DEVICE)) {
754         return BUSINESS_EXACT_NOT_MATCH;
755     } else if (!(deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_TRUST_DEVICE)) {
756         return BUSINESS_EXACT_NOT_MATCH;
757     }
758 
759     size_t tlvLen = broadcastHead.tlvDataLen;
760     const size_t ONE_TLV_DATA_LEN = DM_TLV_SCOPE_DATA_OFFSET + DM_HASH_DATA_LEN +
761         DM_DEVICE_NUMBER_LEN + DM_DEVICE_NUMBER_LEN;
762     for (size_t i = 0; (i + ONE_TLV_DATA_LEN) <= tlvLen; i += ONE_TLV_DATA_LEN) {
763         if (output[i] == DEVICE_ALIAS_NUMBER) {
764             size_t dataPosition = i + DM_TLV_SCOPE_DATA_OFFSET;
765             size_t startNumberPosition = dataPosition + DM_HASH_DATA_LEN;
766             int startNumber = atoi(&output[startNumberPosition]);
767             if (startNumber == 0) {
768                 LOGE("the value of start device number is not allowed");
769                 continue;
770             }
771             size_t endNumberPosition = startNumberPosition + DM_DEVICE_NUMBER_LEN;
772             int endNumber = atoi(&output[endNumberPosition]);
773             if (endNumber == 0) {
774                 LOGE("the value of end device number is not allowed.");
775                 continue;
776             }
777             matchItemNum[DEVICE_ALIAS_NUMBER] = 1;
778             if (CheckDeviceAliasMatch(devicePolicyInfo, &output[dataPosition]) &&
779                 CheckDeviceNumberMatch(devicePolicyInfo, startNumber, endNumber)) {
780                 matchItemResult[DEVICE_ALIAS_NUMBER] = 1;
781             }
782         } else {
783             LOGE("the value of type is not allowed with type: %{public}u.", output[i]);
784             continue;
785         }
786     }
787     return GetMatchResult(matchItemNum, matchItemResult);
788 }
789 
GetVertexDevicePolicyInfo(DevicePolicyInfo & devicePolicyInfo)790 void MineSoftbusListener::GetVertexDevicePolicyInfo(DevicePolicyInfo &devicePolicyInfo)
791 {
792     devicePolicyInfo.snHashValid = false;
793     devicePolicyInfo.typeHashValid = false;
794     devicePolicyInfo.udidHashValid = false;
795     if (GetDeviceSnHash(devicePolicyInfo.snHash)) {
796         devicePolicyInfo.snHashValid = true;
797     }
798     if (GetDeviceUdidHash(devicePolicyInfo.udidHash)) {
799         devicePolicyInfo.udidHashValid = true;
800     }
801     if (GetDeviceTypeHash(devicePolicyInfo.typeHash)) {
802         devicePolicyInfo.typeHashValid = true;
803     }
804 }
805 
MatchSearchVertexDevice(DeviceInfo & deviceInfo,char * output,const DevicePolicyInfo & devicePolicyInfo,const BroadcastHead & broadcastHead)806 Action MineSoftbusListener::MatchSearchVertexDevice(DeviceInfo &deviceInfo, char *output,
807     const DevicePolicyInfo &devicePolicyInfo, const BroadcastHead &broadcastHead)
808 {
809     vector<int> matchItemNum(DM_MAX_VERTEX_TLV_NUM, 0);
810     vector<int> matchItemResult(DM_MAX_VERTEX_TLV_NUM, 0);
811 
812     if ((deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_NOTRUST_DEVICE)) {
813         return BUSINESS_EXACT_NOT_MATCH;
814     } else if (!(deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_TRUST_DEVICE)) {
815         return BUSINESS_EXACT_NOT_MATCH;
816     }
817 
818     size_t tlvLen = broadcastHead.tlvDataLen;
819     const size_t ONE_TLV_DATA_LEN = DM_TLV_VERTEX_DATA_OFFSET + DM_HASH_DATA_LEN;
820     for (size_t i = 0; (i + ONE_TLV_DATA_LEN) <= tlvLen; i += ONE_TLV_DATA_LEN) {
821         size_t dataPosition = 0;
822         if (output[i] == DEVICE_TYPE_TYPE) {
823             dataPosition = i + DM_TLV_VERTEX_DATA_OFFSET;
824             matchItemNum[DEVICE_TYPE_TYPE] = 1;
825             if (CheckDeviceTypeMatch(devicePolicyInfo, &output[dataPosition])) {
826                 matchItemResult[DEVICE_TYPE_TYPE] = 1;
827             }
828         } else if (output[i] == DEVICE_SN_TYPE) {
829             dataPosition = i + DM_TLV_VERTEX_DATA_OFFSET;
830             matchItemNum[DEVICE_SN_TYPE] = 1;
831             if (CheckDeviceSnMatch(devicePolicyInfo, &output[dataPosition])) {
832                 matchItemResult[DEVICE_SN_TYPE] = 1;
833             }
834         } else if (output[i] == DEVICE_UDID_TYPE) {
835             dataPosition = i + DM_TLV_VERTEX_DATA_OFFSET;
836             matchItemNum[DEVICE_UDID_TYPE] = 1;
837             if (CheckDeviceUdidMatch(devicePolicyInfo, &output[dataPosition])) {
838                 matchItemResult[DEVICE_UDID_TYPE] = 1;
839             }
840         } else {
841             LOGE("the value of type is not allowed with type: %{public}u.", output[i]);
842         }
843     }
844     return GetMatchResult(matchItemNum, matchItemResult);
845 }
846 
SendReturnwave(DeviceInfo & deviceInfo,const BroadcastHead & broadcastHead,Action matchResult)847 int32_t MineSoftbusListener::SendReturnwave(DeviceInfo &deviceInfo, const BroadcastHead &broadcastHead,
848     Action matchResult)
849 {
850     size_t outLen = 0;
851     unsigned char outData[DISC_MAX_CUST_DATA_LEN] = {0};
852     outData[outLen++] = BROADCAST_VERSION;
853     outData[outLen++] = sizeof(ReturnwaveHead);
854     size_t base64OutLen = 0;
855 #if (defined(MINE_HARMONY))
856     if (HiChainConnector::IsCredentialExist()) {
857         outData[outLen++] = true;
858     } else {
859         outData[outLen++] = false;
860     }
861     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
862         outData[outLen++] = broadcastHead.pkgNameHash[i];
863     }
864     int retValue;
865 
866     int retValue = DmBase64Encode((char *)(deviceInfo.businessData), DISC_MAX_CUST_DATA_LEN,
867         outData, outLen, base64OutLen);
868     if (retValue != 0) {
869         LOGE("failed to get search data base64 encode type data with ret: %{public}d.", retValue);
870         return ERR_DM_FAILED;
871     }
872     deviceInfo.businessData[base64OutLen] = '\0';
873     retValue = SetDiscoveryPolicy(DM_PKG_NAME, &deviceInfo, (int32_t)matchResult);
874     if (retValue != SOFTBUS_OK) {
875         LOGE("failed to set discovery policy with ret: %{public}d.", retValue);
876     }
877 #endif
878     LOGI("set discovery policy successfully with dataLen: %{public}zu.", base64OutLen);
879     return DM_OK;
880 }
881 
GetDeviceAliasHash(char * output)882 bool MineSoftbusListener::GetDeviceAliasHash(char *output)
883 {
884     char deviceAlias[DM_MAX_DEVICE_ALIAS_LEN + 1] = {0};
885     int32_t retValue = GetParameter(DEVICE_ALIAS, "not exist", deviceAlias, DM_MAX_DEVICE_ALIAS_LEN);
886     if (retValue < 0 || strcmp((const char *)deviceAlias, "not exist") == 0) {
887         LOGE("failed to get device alias from system parameter with ret: %{public}d.", retValue);
888         return false;
889     }
890     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
891     if (GetSha256Hash((const char *)deviceAlias, strlen(deviceAlias), sha256Out) != DM_OK) {
892         LOGE("failed to generated device alias sha256 hash.");
893         return false;
894     }
895     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
896         output[i] = sha256Out[i];
897     }
898     return true;
899 }
900 
GetDeviceSnHash(char * output)901 bool MineSoftbusListener::GetDeviceSnHash(char *output)
902 {
903     const char *deviceSn = GetSerial();
904     if (deviceSn == NULL) {
905         LOGE("failed to get device sn from system parameter.");
906         return false;
907     }
908     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
909     if (GetSha256Hash((const char *)deviceSn, strlen(deviceSn), sha256Out) != DM_OK) {
910         LOGE("failed to generated device sn sha256 hash.");
911         return false;
912     }
913     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
914         output[i] = sha256Out[i];
915     }
916     return true;
917 }
918 
GetDeviceUdidHash(char * output)919 bool MineSoftbusListener::GetDeviceUdidHash(char *output)
920 {
921     char deviceUdid[DM_MAX_DEVICE_UDID_LEN + 1] = {0};
922     int32_t retValue = GetDevUdid(deviceUdid, DM_MAX_DEVICE_UDID_LEN);
923     if (retValue != 0) {
924         LOGE("failed to get local device udid with ret: %{public}d.", retValue);
925         return false;
926     }
927     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
928     if (GetSha256Hash((const char *)deviceUdid, strlen(deviceUdid), sha256Out) != DM_OK) {
929         LOGE("failed to generated device udid sha256 hash.");
930         return false;
931     }
932     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
933         output[i] = sha256Out[i];
934     }
935     return true;
936 }
937 
GetDeviceTypeHash(char * output)938 bool MineSoftbusListener::GetDeviceTypeHash(char *output)
939 {
940     const char *deviceType = GetDeviceType();
941     if (deviceType == NULL) {
942         LOGE("failed to get device type from system parameter.");
943         return false;
944     }
945     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
946     if (GetSha256Hash((const char *)deviceType, strlen(deviceType), sha256Out) != DM_OK) {
947         LOGE("failed to generated device type sha256 hash.");
948         return false;
949     }
950     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
951         output[i] = sha256Out[i];
952     }
953     return true;
954 }
955 
GetDeviceNumber(char * output)956 bool MineSoftbusListener::GetDeviceNumber(char *output)
957 {
958     char deviceNumber[DM_DEVICE_NUMBER_LEN + 1] = {0};
959     int32_t retValue = GetParameter(DEVICE_NUMBER, "not exist", deviceNumber, DM_DEVICE_NUMBER_LEN);
960     if (retValue < 0 || strcmp((const char *)deviceNumber, "not exist") == 0) {
961         LOGE("failed to get device number from system parameter with ret: %{public}d.", retValue);
962         return false;
963     }
964     for (size_t i = 0; i < DM_DEVICE_NUMBER_LEN; i++) {
965         output[i] = deviceNumber[i];
966     }
967     return true;
968 }
969 
CheckDeviceAliasMatch(const DevicePolicyInfo & devicePolicyInfo,const char * data)970 bool MineSoftbusListener::CheckDeviceAliasMatch(const DevicePolicyInfo &devicePolicyInfo, const char *data)
971 {
972     if (!devicePolicyInfo.aliasHashValid) {
973         LOGE("device alias is not valid");
974         return false;
975     }
976     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
977         if (data[i] != devicePolicyInfo.aliasHash[i]) {
978             LOGI("device alias is not match.");
979             return false;
980         }
981     }
982     LOGI("device alias is match.");
983     return true;
984 }
985 
CheckDeviceNumberMatch(const DevicePolicyInfo & devicePolicyInfo,int32_t startNumber,int32_t endNumber)986 bool MineSoftbusListener::CheckDeviceNumberMatch(const DevicePolicyInfo &devicePolicyInfo,
987     int32_t startNumber, int32_t endNumber)
988 {
989     if (!devicePolicyInfo.numberValid) {
990         LOGE("device number is not valid");
991         return false;
992     }
993     if (startNumber <= DM_INVALID_DEVICE_NUMBER || endNumber <= DM_INVALID_DEVICE_NUMBER) {
994         LOGI("device number is match");
995         return true;
996     }
997     int deviceNumber = atoi((const char *)devicePolicyInfo.number);
998     if (deviceNumber < startNumber || deviceNumber > endNumber) {
999         LOGI("device number is not match.");
1000         return false;
1001     }
1002     LOGI("device number is match.");
1003     return true;
1004 }
1005 
CheckDeviceSnMatch(const DevicePolicyInfo & devicePolicyInfo,const char * data)1006 bool MineSoftbusListener::CheckDeviceSnMatch(const DevicePolicyInfo &devicePolicyInfo, const char *data)
1007 {
1008     if (!devicePolicyInfo.snHashValid) {
1009         LOGE("device sn is not valid");
1010         return false;
1011     }
1012     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
1013         if (data[i] != devicePolicyInfo.snHash[i]) {
1014             LOGI("device sn is not match.");
1015             return false;
1016         }
1017     }
1018     LOGI("device sn is match.");
1019     return true;
1020 }
1021 
CheckDeviceTypeMatch(const DevicePolicyInfo & devicePolicyInfo,const char * data)1022 bool MineSoftbusListener::CheckDeviceTypeMatch(const DevicePolicyInfo &devicePolicyInfo, const char *data)
1023 {
1024     if (!devicePolicyInfo.typeHashValid) {
1025         LOGE("device type is not valid");
1026         return false;
1027     }
1028     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
1029         if (data[i] != devicePolicyInfo.typeHash[i]) {
1030             LOGI("device type is not match.");
1031             return false;
1032         }
1033     }
1034     LOGI("device type is match.");
1035     return true;
1036 }
1037 
CheckDeviceUdidMatch(const DevicePolicyInfo & devicePolicyInfo,const char * data)1038 bool MineSoftbusListener::CheckDeviceUdidMatch(const DevicePolicyInfo &devicePolicyInfo, const char *data)
1039 {
1040     if (!devicePolicyInfo.udidHashValid) {
1041         LOGE("device udid is not valid");
1042         return false;
1043     }
1044     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
1045         if (data[i] != devicePolicyInfo.udidHash[i]) {
1046             LOGI("device udid is not match.");
1047             return false;
1048         }
1049     }
1050     LOGI("device udid is match.");
1051     return true;
1052 }
1053 
GetMatchResult(const vector<int> & matchItemNum,const vector<int> & matchItemResult)1054 Action MineSoftbusListener::GetMatchResult(const vector<int> &matchItemNum, const vector<int> &matchItemResult)
1055 {
1056     int matchItemSum = 0;
1057     int matchResultSum = 0;
1058     size_t matchItemNumLen = matchItemNum.size();
1059     size_t matchItemResultLen = matchItemResult.size();
1060     size_t minLen = (matchItemNumLen >= matchItemResultLen ? matchItemResultLen : matchItemNumLen);
1061     for (size_t i = 0; i < minLen; i++) {
1062         matchResultSum += matchItemResult[i];
1063         matchItemSum += matchItemNum[i];
1064     }
1065     if (matchResultSum == 0) {
1066         return BUSINESS_EXACT_NOT_MATCH;
1067     } else if (matchItemSum == matchResultSum) {
1068         return BUSINESS_EXACT_MATCH;
1069     } else {
1070         return BUSINESS_PARTIAL_MATCH;
1071     }
1072 }
1073 } // namespace DistributedHardware
1074 } // namespace OHOS