• 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 = object[FIELD_DEVICE_MODE].Get<uint32_t>();
251     LOGI("quick search device mode is: %{public}u", findMode);
252     switch (findMode) {
253         case FIND_ALL_DEVICE:
254             retValue = ParseSearchAllDevice(object, pkgName, output, outLen);
255             break;
256         case FIND_SCOPE_DEVICE:
257             retValue = ParseSearchScopeDevice(object, pkgName, output, outLen);
258             break;
259         case FIND_VERTEX_DEVICE:
260             retValue = ParseSearchVertexDevice(object, pkgName, output, outLen);
261             break;
262         default:
263             LOGE("key type is not match key: %{public}s.", FIELD_DEVICE_MODE);
264     }
265     if (retValue != DM_OK) {
266         LOGE("fail to parse search find device with ret: %{public}d.", retValue);
267         return retValue;
268     }
269     LOGI("parse search json successfully with pkgName: %{public}s, outLen: %{public}zu,", pkgName.c_str(), *outLen);
270     return DM_OK;
271 }
272 
ParseSearchAllDevice(const JsonObject & object,const string & pkgName,char * output,size_t * outLen)273 int32_t MineSoftbusListener::ParseSearchAllDevice(const JsonObject &object, const string &pkgName, char *output,
274     size_t *outLen)
275 {
276     BroadcastHead broadcastHead;
277     if (SetBroadcastHead(object, pkgName, broadcastHead) != DM_OK) {
278         LOGE("fail to set broadcast head.");
279         return ERR_DM_FAILED;
280     }
281     broadcastHead.tlvDataLen = 0;
282     broadcastHead.findMode = FIND_ALL_DEVICE;
283     AddHeadToBroadcast(broadcastHead, output);
284     *outLen = sizeof(BroadcastHead);
285     return DM_OK;
286 }
287 
ParseSearchScopeDevice(const JsonObject & object,const string & pkgName,char * output,size_t * outLen)288 int32_t MineSoftbusListener::ParseSearchScopeDevice(const JsonObject &object, const string &pkgName, char *output,
289     size_t *outLen)
290 {
291     BroadcastHead broadcastHead;
292     if (SetBroadcastHead(object, pkgName, broadcastHead) != DM_OK) {
293         LOGE("fail to set broadcast head.");
294         return ERR_DM_FAILED;
295     }
296     if (!object.Contains(FIELD_FILTER_OPTIONS) || !object[FIELD_FILTER_OPTIONS].IsArray()) {
297         LOGE("failed to get %{public}s scope cjson object or is not array.", FIELD_FILTER_OPTIONS);
298         return ERR_DM_FAILED;
299     }
300     std::vector<ScopeOptionInfo> optionInfoVec;
301     object[FIELD_FILTER_OPTIONS].Get(optionInfoVec);
302     size_t optionInfoVecSize = optionInfoVec.size();
303     if (optionInfoVecSize == 0 || optionInfoVecSize > DM_MAX_SCOPE_TLV_NUM) {
304         LOGE("failed to get search josn array lenght.");
305         return ERR_DM_INVALID_JSON_STRING;
306     }
307     LOGI("start to parse scope search array json with size:%{public}zu.", optionInfoVecSize);
308     if (ParseScopeDeviceJsonArray(optionInfoVec, output + sizeof(BroadcastHead), outLen) != DM_OK) {
309         LOGE("failed to parse scope json array.");
310         return ERR_DM_FAILED;
311     }
312 
313     broadcastHead.findMode = FIND_SCOPE_DEVICE;
314     broadcastHead.tlvDataLen = *outLen;
315     AddHeadToBroadcast(broadcastHead, output);
316     *outLen = *outLen + sizeof(BroadcastHead);
317     return DM_OK;
318 }
319 
ParseSearchVertexDevice(const JsonObject & object,const string & pkgName,char * output,size_t * outLen)320 int32_t MineSoftbusListener::ParseSearchVertexDevice(const JsonObject &object, const string &pkgName, char *output,
321     size_t *outLen)
322 {
323     BroadcastHead broadcastHead;
324     if (SetBroadcastHead(object, pkgName, broadcastHead) != DM_OK) {
325         LOGE("fail to set broadcast head.");
326         return ERR_DM_FAILED;
327     }
328     if (!object.Contains(FIELD_FILTER_OPTIONS) || !object[FIELD_FILTER_OPTIONS].IsArray()) {
329         LOGE("failed to get %{public}s vertex cjson object or is not array.", FIELD_FILTER_OPTIONS);
330         return ERR_DM_FAILED;
331     }
332     std::vector<VertexOptionInfo> optionInfoVec;
333     object[FIELD_FILTER_OPTIONS].Get(optionInfoVec);
334     size_t optionInfoVecSize = optionInfoVec.size();
335     if (optionInfoVecSize == 0 || optionInfoVecSize > DM_MAX_VERTEX_TLV_NUM) {
336         LOGE("failed to get search josn array lenght.");
337         return ERR_DM_FAILED;
338     }
339     LOGI("start to parse vertex search array json with size: %{public}zu.", optionInfoVecSize);
340     if (ParseVertexDeviceJsonArray(optionInfoVec, output + sizeof(BroadcastHead), outLen) != DM_OK) {
341         LOGE("failed to parse vertex json array.");
342         return ERR_DM_FAILED;
343     }
344 
345     broadcastHead.findMode = FIND_VERTEX_DEVICE;
346     broadcastHead.tlvDataLen = *outLen;
347     AddHeadToBroadcast(broadcastHead, output);
348     *outLen = *outLen + sizeof(BroadcastHead);
349     return DM_OK;
350 }
351 
SetBroadcastHead(const JsonObject & object,const string & pkgName,BroadcastHead & broadcastHead)352 int32_t MineSoftbusListener::SetBroadcastHead(const JsonObject &object, const string &pkgName,
353     BroadcastHead &broadcastHead)
354 {
355     broadcastHead.version = BROADCAST_VERSION;
356     broadcastHead.headDataLen = sizeof(BroadcastHead);
357     broadcastHead.tlvDataLen = 0;
358     broadcastHead.findMode = 0;
359     if (SetBroadcastTrustOptions(object, broadcastHead) != DM_OK) {
360         LOGE("fail to set trust options to search broadcast.");
361         return ERR_DM_FAILED;
362     }
363     if (SetBroadcastPkgname(pkgName, broadcastHead) != DM_OK) {
364         LOGE("fail to set pkgname to search broadcast.");
365         return ERR_DM_FAILED;
366     }
367     return DM_OK;
368 }
369 
AddHeadToBroadcast(const BroadcastHead & broadcastHead,char * output)370 void MineSoftbusListener::AddHeadToBroadcast(const BroadcastHead &broadcastHead, char *output)
371 {
372     size_t startPos = 0;
373     output[startPos++] = broadcastHead.version;
374     output[startPos++] = broadcastHead.headDataLen;
375     output[startPos++] = broadcastHead.tlvDataLen;
376     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
377         output[startPos++] = broadcastHead.pkgNameHash[i];
378     }
379     output[startPos++] = broadcastHead.findMode;
380     output[startPos++] = broadcastHead.trustFilter;
381     LOGI("find device info with version: %{public}d, findMode: %{public}d, HeadLen: %{public}d, tlvDataLen: %{public}d,"
382         "trustFilter: %{public}d", (int)(broadcastHead.version), (int)(broadcastHead.findMode),
383         (int)(broadcastHead.headDataLen), (int)(broadcastHead.tlvDataLen), (int)(broadcastHead.trustFilter));
384 }
385 
ParseScopeDeviceJsonArray(const vector<ScopeOptionInfo> & optionInfo,char * output,size_t * outLen)386 int32_t MineSoftbusListener::ParseScopeDeviceJsonArray(const vector<ScopeOptionInfo> &optionInfo,
387     char *output, size_t *outLen)
388 {
389     errno_t retValue = EOK;
390     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
391     size_t arraySize = optionInfo.size();
392 
393     for (size_t i = 0; i < arraySize; i++) {
394         if (GetSha256Hash(optionInfo[i].deviceAlias.c_str(),
395                           optionInfo[i].deviceAlias.size(), sha256Out) != DM_OK) {
396             LOGE("failed to get sha256 hash with index: %{public}zu, value: %{public}s.", i,
397                 optionInfo[i].deviceAlias.c_str());
398             return ERR_DM_FAILED;
399         }
400         output[(*outLen)++] = DEVICE_ALIAS_NUMBER;
401         output[(*outLen)++] = DM_HASH_DATA_LEN;
402         output[(*outLen)++] = DM_DEVICE_NUMBER_LEN;
403         output[(*outLen)++] = DM_DEVICE_NUMBER_LEN;
404         for (size_t j = 0; j < DM_HASH_DATA_LEN; j++) {
405             output[(*outLen)++] = sha256Out[j];
406         }
407         retValue = sprintf_s(&output[*outLen], DM_DEVICE_NUMBER_LEN, "%010d", optionInfo[i].startNumber);
408         if (retValue <= 0) {
409             LOGE("fail to add device number to data buffer");
410             return ERR_DM_FAILED;
411         }
412         *outLen = *outLen + DM_DEVICE_NUMBER_LEN;
413         retValue = sprintf_s(&output[*outLen], DM_DEVICE_NUMBER_LEN, "%010d", optionInfo[i].endNumber);
414         if (retValue <= 0) {
415             LOGE("fail to add device number to data buffer");
416             return ERR_DM_FAILED;
417         }
418         *outLen = *outLen + DM_DEVICE_NUMBER_LEN;
419     }
420     return DM_OK;
421 }
422 
ParseVertexDeviceJsonArray(const std::vector<VertexOptionInfo> & optionInfo,char * output,size_t * outLen)423 int32_t MineSoftbusListener::ParseVertexDeviceJsonArray(const std::vector<VertexOptionInfo> &optionInfo,
424     char *output, size_t *outLen)
425 {
426     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
427     size_t arraySize = optionInfo.size();
428 
429     for (size_t i = 0; i < arraySize; i++) {
430         if (optionInfo[i].type.empty() || optionInfo[i].value.empty()) {
431             LOGE("failed to get type or value cjosn object with index: %{public}zu", i);
432             continue;
433         }
434         if (optionInfo[i].type == "deviceUdid") {
435             output[(*outLen)++] = DEVICE_UDID_TYPE;
436         } else if (optionInfo[i].type == "deviceType") {
437             output[(*outLen)++] = DEVICE_TYPE_TYPE;
438         } else if (optionInfo[i].type == "deviceSn") {
439             output[(*outLen)++] = DEVICE_SN_TYPE;
440         } else {
441             LOGE("type:%{public}s is not allowed with index: %{public}zu.", optionInfo[i].type.c_str(), i);
442             return ERR_DM_FAILED;
443         }
444         output[(*outLen)++] = DM_HASH_DATA_LEN;
445         if (GetSha256Hash((const char *) optionInfo[i].value.data(), optionInfo[i].value.size(),
446                           sha256Out) != DM_OK) {
447             LOGE("failed to get value sha256 hash with index: %{public}zu", i);
448             return ERR_DM_GET_DATA_SHA256_HASH;
449         }
450         for (size_t j = 0; j < DM_HASH_DATA_LEN; j++) {
451             output[(*outLen)++] = sha256Out[j];
452         }
453     }
454     return DM_OK;
455 }
456 
GetSha256Hash(const char * data,size_t len,char * output)457 int32_t MineSoftbusListener::GetSha256Hash(const char *data, size_t len, char *output)
458 {
459     if (data == nullptr || output == nullptr || len == 0) {
460         LOGE("Input param invalied.");
461         return ERR_DM_INPUT_PARA_INVALID;
462     }
463     SHA256_CTX ctx;
464     SHA256_Init(&ctx);
465     SHA256_Update(&ctx, data, len);
466     SHA256_Final((unsigned char *)output, &ctx);
467     return DM_OK;
468 }
469 
SetBroadcastTrustOptions(const JsonObject & object,BroadcastHead & broadcastHead)470 int32_t MineSoftbusListener::SetBroadcastTrustOptions(const JsonObject &object, BroadcastHead &broadcastHead)
471 {
472     if (!object.Contains(FIELD_TRUST_OPTIONS)) {
473         broadcastHead.trustFilter = 0;
474         return DM_OK;
475     } else if (object[FIELD_TRUST_OPTIONS].IsBoolean() && object[FIELD_TRUST_OPTIONS].Get<bool>()) {
476         broadcastHead.trustFilter = FIND_TRUST_DEVICE;
477         return DM_OK;
478     } else if (object[FIELD_TRUST_OPTIONS].IsBoolean() && !object[FIELD_TRUST_OPTIONS].Get<bool>()) {
479         broadcastHead.trustFilter = FIND_NOTRUST_DEVICE;
480         return DM_OK;
481     }
482     LOGE("key type is error with key: %{public}s", FIELD_TRUST_OPTIONS);
483     return ERR_DM_FAILED;
484 }
485 
SetBroadcastPkgname(const string & pkgName,BroadcastHead & broadcastHead)486 int32_t MineSoftbusListener::SetBroadcastPkgname(const string &pkgName, BroadcastHead &broadcastHead)
487 {
488     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
489     if (GetSha256Hash((const char *)pkgName.c_str(), pkgName.size(), sha256Out) != DM_OK) {
490         LOGE("failed to get search pkgName sha256 hash while search all device.");
491         return ERR_DM_FAILED;
492     }
493     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
494         broadcastHead.pkgNameHash[i] = sha256Out[i];
495     }
496     return DM_OK;
497 }
498 
SetSubscribeInfo(const DmSubscribeInfo & dmSubscribeInfo,SubscribeInfo & subscribeInfo)499 void MineSoftbusListener::SetSubscribeInfo(const DmSubscribeInfo &dmSubscribeInfo, SubscribeInfo &subscribeInfo)
500 {
501     subscribeInfo.subscribeId = dmSubscribeInfo.subscribeId;
502     subscribeInfo.mode = (DiscoverMode)dmSubscribeInfo.mode;
503     subscribeInfo.medium = (ExchangeMedium)dmSubscribeInfo.medium;
504     subscribeInfo.freq = (ExchangeFreq)dmSubscribeInfo.freq;
505     subscribeInfo.isSameAccount = dmSubscribeInfo.isSameAccount;
506     subscribeInfo.isWakeRemote = dmSubscribeInfo.isWakeRemote;
507     subscribeInfo.capability = dmSubscribeInfo.capability;
508     subscribeInfo.capabilityData = nullptr;
509     subscribeInfo.dataLen = 0;
510 }
511 
SendBroadcastInfo(const string & pkgName,SubscribeInfo & subscribeInfo,char * output,size_t outputLen)512 int32_t MineSoftbusListener::SendBroadcastInfo(const string &pkgName, SubscribeInfo &subscribeInfo, char *output,
513     size_t outputLen)
514 {
515     size_t base64OutLen = 0;
516     int retValue;
517     char base64Out[DISC_MAX_CUST_DATA_LEN] = {0};
518     retValue = DmBase64Encode(base64Out, DISC_MAX_CUST_DATA_LEN, output, outputLen, base64OutLen);
519     if (retValue != 0) {
520         LOGE("failed to get search data base64 encode type data with ret: %{public}d.", retValue);
521         return ERR_DM_FAILED;
522     }
523 #if (defined(MINE_HARMONY))
524     subscribeInfo.custData = base64Out;
525     subscribeInfo.custDataLen = base64OutLen;
526     IRefreshCallback softbusRefreshCallback_ = SoftbusListener::GetSoftbusRefreshCb();
527     retValue = RefreshLNN(DM_PKG_NAME, &subscribeInfo, &softbusRefreshCallback_);
528     if (retValue != SOFTBUS_OK) {
529         LOGE("failed to start to refresh quick discovery with ret: %{public}d.", retValue);
530         return ERR_DM_FAILED;
531     }
532 #endif
533     LOGI("send search broadcast info by softbus successfully with dataLen: %{public}zu, pkgName: %{public}s.",
534         base64OutLen, pkgName.c_str());
535     return DM_OK;
536 }
537 
DmBase64Encode(char * output,size_t outputLen,const char * input,size_t inputLen,size_t & base64OutLen)538 int32_t MineSoftbusListener::DmBase64Encode(char *output, size_t outputLen, const char *input,
539     size_t inputLen, size_t &base64OutLen)
540 {
541     LOGI("MineSoftbusListener::DmBase64Encode");
542     if (output == nullptr || input == nullptr || outputLen == 0 || inputLen == 0) {
543         LOGE("Input param invalied.");
544         return ERR_DM_INPUT_PARA_INVALID;
545     }
546     int32_t outLen = 0;
547     base64OutLen = 0;
548     EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
549     if (ctx == nullptr) {
550         LOGE("create ctx failed.");
551         EVP_ENCODE_CTX_free(ctx);
552         return ERR_DM_FAILED;
553     }
554     EVP_EncodeInit(ctx);
555     if (EVP_EncodeUpdate(ctx, (unsigned char *)output, &outLen, (const unsigned char *)input, inputLen) != EVP_OK) {
556         LOGE("EVP_EncodeUpdate failed.");
557         EVP_ENCODE_CTX_free(ctx);
558         return ERR_DM_FAILED;
559     }
560     base64OutLen += static_cast<size_t>(outLen);
561     EVP_EncodeFinal(ctx, (unsigned char *)(output + outLen), &outLen);
562     base64OutLen += static_cast<size_t>(outLen);
563     EVP_ENCODE_CTX_free(ctx);
564     return DM_OK;
565 }
566 
DmBase64Decode(char * output,size_t outputLen,const char * input,size_t inputLen,size_t & base64OutLen)567 int32_t MineSoftbusListener::DmBase64Decode(char *output, size_t outputLen, const char *input,
568     size_t inputLen, size_t &base64OutLen)
569 {
570     LOGI("MineSoftbusListener::DmBase64Decode");
571     if (output == nullptr || outputLen == 0 || input == nullptr || inputLen == 0) {
572         LOGE("Input param invalied.");
573         return ERR_DM_INPUT_PARA_INVALID;
574     }
575     base64OutLen = 0;
576     int32_t outLen = 0;
577     EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
578     if (ctx == nullptr) {
579         LOGE("create ctx failed.");
580         EVP_ENCODE_CTX_free(ctx);
581         return ERR_DM_FAILED;
582     }
583     EVP_DecodeInit(ctx);
584     if (EVP_DecodeUpdate(ctx, (unsigned char *)output, &outLen, (const unsigned char *)input, inputLen) != EVP_OK) {
585         LOGE("EVP_DecodeUpdate failed.");
586         EVP_ENCODE_CTX_free(ctx);
587         return ERR_DM_FAILED;
588     }
589     base64OutLen += static_cast<size_t>(outLen);
590     if (EVP_DecodeFinal(ctx, (unsigned char *)(output + outLen), &outLen) != EVP_OK) {
591         LOGE("EVP_DecodeFinal failed.");
592         EVP_ENCODE_CTX_free(ctx);
593         return ERR_DM_FAILED;
594     }
595     base64OutLen += static_cast<size_t>(outLen);
596     EVP_ENCODE_CTX_free(ctx);
597     return DM_OK;
598 }
599 
PublishDeviceDiscovery(void)600 int32_t MineSoftbusListener::PublishDeviceDiscovery(void)
601 {
602     PublishInfo publishInfo;
603     publishInfo.publishId = DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID;
604     publishInfo.mode = DiscoverMode::DISCOVER_MODE_ACTIVE;
605     publishInfo.medium = ExchangeMedium::AUTO;
606     publishInfo.freq = ExchangeFreq::LOW;
607     publishInfo.capability = DM_CAPABILITY_OSD;
608     publishInfo.capabilityData = nullptr;
609     publishInfo.dataLen = 0;
610     int retValue = PublishLNN(DM_PKG_NAME, &publishInfo, &publishLNNCallback_);
611     if (retValue != SOFTBUS_OK) {
612         LOGE("failed to call softbus publishLNN function with ret: %{public}d.", retValue);
613         return retValue;
614     }
615     std::chrono::seconds timeout = std::chrono::seconds(MAX_SOFTBUS_DELAY_TIME);
616     std::unique_lock<std::mutex> locker(g_publishLnnLock);
617     if (!g_publishLnnNotify.wait_for(locker, timeout, [] { return g_publishLnnFlag; })) {
618         g_publishLnnFlag = false;
619         return ERR_DM_SOFTBUS_PUBLISH_SERVICE;
620     }
621     g_publishLnnFlag = false;
622     return DM_OK;
623 }
624 
MatchSearchDealTask(void)625 void MineSoftbusListener::MatchSearchDealTask(void)
626 {
627     LOGI("the match deal task has started to run.");
628 #if (defined(MINE_HARMONY))
629     DeviceInfo tempDeviceInfo;
630     while (true) {
631         {
632             std::unique_lock<std::mutex> autoLock(g_matchWaitDeviceLock);
633             if (!g_matchDealFlag) {
634                 LOGI("the match deal task will stop to run.");
635                 return;
636             }
637             g_matchDealNotify.wait(autoLock, [] { return !g_matchQueue.empty(); });
638             tempDeviceInfo = g_matchQueue.front();
639             g_matchQueue.pop_front();
640         }
641         if (ParseBroadcastInfo(tempDeviceInfo) != DM_OK) {
642             LOGE("failed to parse broadcast info.");
643         }
644     }
645 #endif
646 }
647 
ParseBroadcastInfo(DeviceInfo & deviceInfo)648 int32_t MineSoftbusListener::ParseBroadcastInfo(DeviceInfo &deviceInfo)
649 {
650     char output[DISC_MAX_CUST_DATA_LEN] = {0};
651     if (!GetBroadcastData(deviceInfo, output, DISC_MAX_CUST_DATA_LEN)) {
652         LOGE("fail to get broadcast data");
653         return ERR_DM_FAILED;
654     }
655     DevicePolicyInfo devicePolicyInfo;
656     Action matchResult = BUSINESS_EXACT_NOT_MATCH;
657     BroadcastHead broadcastHead = *(BroadcastHead *)output;
658     LOGI("parse device info with version: %{public}d, findMode: %{public}d, HeadLen: %{public}d, tlvDataLen:"
659         "%{public}d, trustFilter: %{public}d", (int)(broadcastHead.version), (int)(broadcastHead.findMode),
660         (int)(broadcastHead.headDataLen), (int)(broadcastHead.tlvDataLen), (int)broadcastHead.trustFilter);
661 
662     char findMode = broadcastHead.findMode;
663     switch (findMode) {
664         case FIND_ALL_DEVICE:
665             matchResult = MatchSearchAllDevice(deviceInfo, broadcastHead);
666             break;
667         case FIND_SCOPE_DEVICE:
668             GetScopeDevicePolicyInfo(devicePolicyInfo);
669             matchResult = MatchSearchScopeDevice(deviceInfo, output + sizeof(BroadcastHead),
670                 devicePolicyInfo, broadcastHead);
671             break;
672         case FIND_VERTEX_DEVICE:
673             GetVertexDevicePolicyInfo(devicePolicyInfo);
674             matchResult = MatchSearchVertexDevice(deviceInfo, output + sizeof(BroadcastHead),
675                 devicePolicyInfo, broadcastHead);
676             break;
677         default:
678             LOGE("key type is not match key: %{public}s.", FIELD_DEVICE_MODE);
679             return ERR_DM_FAILED;
680     }
681     LOGI("parse broadcast info matchResult: %{public}d.", (int)matchResult);
682     if (matchResult == BUSINESS_EXACT_MATCH) {
683         return SendReturnwave(deviceInfo, broadcastHead, matchResult);
684     }
685     return DM_OK;
686 }
687 
GetBroadcastData(DeviceInfo & deviceInfo,char * output,size_t outLen)688 bool MineSoftbusListener::GetBroadcastData(DeviceInfo &deviceInfo, char *output, size_t outLen)
689 {
690     size_t base64OutLen = 0;
691 #if (defined(MINE_HARMONY))
692     size_t dataLen = deviceInfo.businessDataLen;
693     unsigned char *data = (unsigned char *)deviceInfo.businessData;
694     int retValue = DmBase64Decode(output, outLen, data, dataLen, base64OutLen);
695     if (retValue != 0) {
696         LOGE("failed to with ret: %{public}d.", retValue);
697         return false;
698     }
699     if (base64OutLen < DM_SEARCH_BROADCAST_MIN_LEN) {
700         LOGE("data length too short with outLen: %{public}zu.", base64OutLen);
701         return false;
702     }
703 #endif
704     BroadcastHead *broadcastHead = (BroadcastHead *)output;
705     size_t hDataLen = broadcastHead->headDataLen;
706     size_t tlvDataLen = broadcastHead->tlvDataLen;
707     if (hDataLen >= DISC_MAX_CUST_DATA_LEN || tlvDataLen >= DISC_MAX_CUST_DATA_LEN ||
708         (hDataLen + tlvDataLen) != base64OutLen) {
709         LOGE("data lenght is not valid with: headDataLen: %{public}zu, tlvDataLen: %{public}zu, base64OutLen:"
710             "%{public}zu.", hDataLen, tlvDataLen, base64OutLen);
711         return false;
712     }
713     return true;
714 }
715 
MatchSearchAllDevice(DeviceInfo & deviceInfo,const BroadcastHead & broadcastHead)716 Action MineSoftbusListener::MatchSearchAllDevice(DeviceInfo &deviceInfo, const BroadcastHead &broadcastHead)
717 {
718     if (broadcastHead.trustFilter == 0) {
719         return BUSINESS_EXACT_MATCH;
720     }
721     if ((deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_TRUST_DEVICE)) {
722         return BUSINESS_EXACT_MATCH;
723     } else if ((deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_NOTRUST_DEVICE)) {
724         return BUSINESS_EXACT_NOT_MATCH;
725     } else if (!(deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_TRUST_DEVICE)) {
726         return BUSINESS_EXACT_NOT_MATCH;
727     } else {
728         return BUSINESS_EXACT_MATCH;
729     }
730 }
731 
GetScopeDevicePolicyInfo(DevicePolicyInfo & devicePolicyInfo)732 void MineSoftbusListener::GetScopeDevicePolicyInfo(DevicePolicyInfo &devicePolicyInfo)
733 {
734     devicePolicyInfo.numberValid = false;
735     devicePolicyInfo.aliasHashValid = false;
736     if (GetDeviceAliasHash(devicePolicyInfo.aliasHash)) {
737         devicePolicyInfo.aliasHashValid = true;
738     }
739     if (GetDeviceNumber(devicePolicyInfo.number)) {
740         devicePolicyInfo.numberValid = true;
741     }
742 }
743 
MatchSearchScopeDevice(DeviceInfo & deviceInfo,char * output,const DevicePolicyInfo & devicePolicyInfo,const BroadcastHead & broadcastHead)744 Action MineSoftbusListener::MatchSearchScopeDevice(DeviceInfo &deviceInfo, char *output,
745     const DevicePolicyInfo &devicePolicyInfo, const BroadcastHead &broadcastHead)
746 {
747     vector<int> matchItemNum(DM_MAX_SCOPE_TLV_NUM, 0);
748     vector<int> matchItemResult(DM_MAX_SCOPE_TLV_NUM, 0);
749 
750     if ((deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_NOTRUST_DEVICE)) {
751         return BUSINESS_EXACT_NOT_MATCH;
752     } else if (!(deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_TRUST_DEVICE)) {
753         return BUSINESS_EXACT_NOT_MATCH;
754     }
755 
756     size_t tlvLen = broadcastHead.tlvDataLen;
757     const size_t ONE_TLV_DATA_LEN = DM_TLV_SCOPE_DATA_OFFSET + DM_HASH_DATA_LEN +
758         DM_DEVICE_NUMBER_LEN + DM_DEVICE_NUMBER_LEN;
759     for (size_t i = 0; (i + ONE_TLV_DATA_LEN) <= tlvLen; i += ONE_TLV_DATA_LEN) {
760         if (output[i] == DEVICE_ALIAS_NUMBER) {
761             size_t dataPosition = i + DM_TLV_SCOPE_DATA_OFFSET;
762             size_t startNumberPosition = dataPosition + DM_HASH_DATA_LEN;
763             int startNumber = atoi(&output[startNumberPosition]);
764             if (startNumber == 0) {
765                 LOGE("the value of start device number is not allowed");
766                 continue;
767             }
768             size_t endNumberPosition = startNumberPosition + DM_DEVICE_NUMBER_LEN;
769             int endNumber = atoi(&output[endNumberPosition]);
770             if (endNumber == 0) {
771                 LOGE("the value of end device number is not allowed.");
772                 continue;
773             }
774             matchItemNum[DEVICE_ALIAS_NUMBER] = 1;
775             if (CheckDeviceAliasMatch(devicePolicyInfo, &output[dataPosition]) &&
776                 CheckDeviceNumberMatch(devicePolicyInfo, startNumber, endNumber)) {
777                 matchItemResult[DEVICE_ALIAS_NUMBER] = 1;
778             }
779         } else {
780             LOGE("the value of type is not allowed with type: %{public}u.", output[i]);
781             continue;
782         }
783     }
784     return GetMatchResult(matchItemNum, matchItemResult);
785 }
786 
GetVertexDevicePolicyInfo(DevicePolicyInfo & devicePolicyInfo)787 void MineSoftbusListener::GetVertexDevicePolicyInfo(DevicePolicyInfo &devicePolicyInfo)
788 {
789     devicePolicyInfo.snHashValid = false;
790     devicePolicyInfo.typeHashValid = false;
791     devicePolicyInfo.udidHashValid = false;
792     if (GetDeviceSnHash(devicePolicyInfo.snHash)) {
793         devicePolicyInfo.snHashValid = true;
794     }
795     if (GetDeviceUdidHash(devicePolicyInfo.udidHash)) {
796         devicePolicyInfo.udidHashValid = true;
797     }
798     if (GetDeviceTypeHash(devicePolicyInfo.typeHash)) {
799         devicePolicyInfo.typeHashValid = true;
800     }
801 }
802 
MatchSearchVertexDevice(DeviceInfo & deviceInfo,char * output,const DevicePolicyInfo & devicePolicyInfo,const BroadcastHead & broadcastHead)803 Action MineSoftbusListener::MatchSearchVertexDevice(DeviceInfo &deviceInfo, char *output,
804     const DevicePolicyInfo &devicePolicyInfo, const BroadcastHead &broadcastHead)
805 {
806     vector<int> matchItemNum(DM_MAX_VERTEX_TLV_NUM, 0);
807     vector<int> matchItemResult(DM_MAX_VERTEX_TLV_NUM, 0);
808 
809     if ((deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_NOTRUST_DEVICE)) {
810         return BUSINESS_EXACT_NOT_MATCH;
811     } else if (!(deviceInfo.isOnline) && (broadcastHead.trustFilter == FIND_TRUST_DEVICE)) {
812         return BUSINESS_EXACT_NOT_MATCH;
813     }
814 
815     size_t tlvLen = broadcastHead.tlvDataLen;
816     const size_t ONE_TLV_DATA_LEN = DM_TLV_VERTEX_DATA_OFFSET + DM_HASH_DATA_LEN;
817     for (size_t i = 0; (i + ONE_TLV_DATA_LEN) <= tlvLen; i += ONE_TLV_DATA_LEN) {
818         size_t dataPosition = 0;
819         if (output[i] == DEVICE_TYPE_TYPE) {
820             dataPosition = i + DM_TLV_VERTEX_DATA_OFFSET;
821             matchItemNum[DEVICE_TYPE_TYPE] = 1;
822             if (CheckDeviceTypeMatch(devicePolicyInfo, &output[dataPosition])) {
823                 matchItemResult[DEVICE_TYPE_TYPE] = 1;
824             }
825         } else if (output[i] == DEVICE_SN_TYPE) {
826             dataPosition = i + DM_TLV_VERTEX_DATA_OFFSET;
827             matchItemNum[DEVICE_SN_TYPE] = 1;
828             if (CheckDeviceSnMatch(devicePolicyInfo, &output[dataPosition])) {
829                 matchItemResult[DEVICE_SN_TYPE] = 1;
830             }
831         } else if (output[i] == DEVICE_UDID_TYPE) {
832             dataPosition = i + DM_TLV_VERTEX_DATA_OFFSET;
833             matchItemNum[DEVICE_UDID_TYPE] = 1;
834             if (CheckDeviceUdidMatch(devicePolicyInfo, &output[dataPosition])) {
835                 matchItemResult[DEVICE_UDID_TYPE] = 1;
836             }
837         } else {
838             LOGE("the value of type is not allowed with type: %{public}u.", output[i]);
839         }
840     }
841     return GetMatchResult(matchItemNum, matchItemResult);
842 }
843 
SendReturnwave(DeviceInfo & deviceInfo,const BroadcastHead & broadcastHead,Action matchResult)844 int32_t MineSoftbusListener::SendReturnwave(DeviceInfo &deviceInfo, const BroadcastHead &broadcastHead,
845     Action matchResult)
846 {
847     size_t outLen = 0;
848     unsigned char outData[DISC_MAX_CUST_DATA_LEN] = {0};
849     outData[outLen++] = BROADCAST_VERSION;
850     outData[outLen++] = sizeof(ReturnwaveHead);
851     size_t base64OutLen = 0;
852 #if (defined(MINE_HARMONY))
853     if (HiChainConnector::IsCredentialExist()) {
854         outData[outLen++] = true;
855     } else {
856         outData[outLen++] = false;
857     }
858     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
859         outData[outLen++] = broadcastHead.pkgNameHash[i];
860     }
861     int retValue;
862 
863     int retValue = DmBase64Encode((char *)(deviceInfo.businessData), DISC_MAX_CUST_DATA_LEN,
864         outData, outLen, base64OutLen);
865     if (retValue != 0) {
866         LOGE("failed to get search data base64 encode type data with ret: %{public}d.", retValue);
867         return ERR_DM_FAILED;
868     }
869     deviceInfo.businessData[base64OutLen] = '\0';
870     retValue = SetDiscoveryPolicy(DM_PKG_NAME, &deviceInfo, (int32_t)matchResult);
871     if (retValue != SOFTBUS_OK) {
872         LOGE("failed to set discovery policy with ret: %{public}d.", retValue);
873     }
874 #endif
875     LOGI("set discovery policy successfully with dataLen: %{public}zu.", base64OutLen);
876     return DM_OK;
877 }
878 
GetDeviceAliasHash(char * output)879 bool MineSoftbusListener::GetDeviceAliasHash(char *output)
880 {
881     char deviceAlias[DM_MAX_DEVICE_ALIAS_LEN + 1] = {0};
882     int32_t retValue = GetParameter(DEVICE_ALIAS, "not exist", deviceAlias, DM_MAX_DEVICE_ALIAS_LEN);
883     if (retValue < 0 || strcmp((const char *)deviceAlias, "not exist") == 0) {
884         LOGE("failed to get device alias from system parameter with ret: %{public}d.", retValue);
885         return false;
886     }
887     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
888     if (GetSha256Hash((const char *)deviceAlias, strlen(deviceAlias), sha256Out) != DM_OK) {
889         LOGE("failed to generated device alias sha256 hash.");
890         return false;
891     }
892     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
893         output[i] = sha256Out[i];
894     }
895     return true;
896 }
897 
GetDeviceSnHash(char * output)898 bool MineSoftbusListener::GetDeviceSnHash(char *output)
899 {
900     const char *deviceSn = GetSerial();
901     if (deviceSn == NULL) {
902         LOGE("failed to get device sn from system parameter.");
903         return false;
904     }
905     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
906     if (GetSha256Hash((const char *)deviceSn, strlen(deviceSn), sha256Out) != DM_OK) {
907         LOGE("failed to generated device sn sha256 hash.");
908         return false;
909     }
910     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
911         output[i] = sha256Out[i];
912     }
913     return true;
914 }
915 
GetDeviceUdidHash(char * output)916 bool MineSoftbusListener::GetDeviceUdidHash(char *output)
917 {
918     char deviceUdid[DM_MAX_DEVICE_UDID_LEN + 1] = {0};
919     int32_t retValue = GetDevUdid(deviceUdid, DM_MAX_DEVICE_UDID_LEN);
920     if (retValue != 0) {
921         LOGE("failed to get local device udid with ret: %{public}d.", retValue);
922         return false;
923     }
924     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
925     if (GetSha256Hash((const char *)deviceUdid, strlen(deviceUdid), sha256Out) != DM_OK) {
926         LOGE("failed to generated device udid sha256 hash.");
927         return false;
928     }
929     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
930         output[i] = sha256Out[i];
931     }
932     return true;
933 }
934 
GetDeviceTypeHash(char * output)935 bool MineSoftbusListener::GetDeviceTypeHash(char *output)
936 {
937     const char *deviceType = GetDeviceType();
938     if (deviceType == NULL) {
939         LOGE("failed to get device type from system parameter.");
940         return false;
941     }
942     char sha256Out[SHA256_OUT_DATA_LEN] = {0};
943     if (GetSha256Hash((const char *)deviceType, strlen(deviceType), sha256Out) != DM_OK) {
944         LOGE("failed to generated device type sha256 hash.");
945         return false;
946     }
947     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
948         output[i] = sha256Out[i];
949     }
950     return true;
951 }
952 
GetDeviceNumber(char * output)953 bool MineSoftbusListener::GetDeviceNumber(char *output)
954 {
955     char deviceNumber[DM_DEVICE_NUMBER_LEN + 1] = {0};
956     int32_t retValue = GetParameter(DEVICE_NUMBER, "not exist", deviceNumber, DM_DEVICE_NUMBER_LEN);
957     if (retValue < 0 || strcmp((const char *)deviceNumber, "not exist") == 0) {
958         LOGE("failed to get device number from system parameter with ret: %{public}d.", retValue);
959         return false;
960     }
961     for (size_t i = 0; i < DM_DEVICE_NUMBER_LEN; i++) {
962         output[i] = deviceNumber[i];
963     }
964     return true;
965 }
966 
CheckDeviceAliasMatch(const DevicePolicyInfo & devicePolicyInfo,const char * data)967 bool MineSoftbusListener::CheckDeviceAliasMatch(const DevicePolicyInfo &devicePolicyInfo, const char *data)
968 {
969     if (!devicePolicyInfo.aliasHashValid) {
970         LOGE("device alias is not valid");
971         return false;
972     }
973     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
974         if (data[i] != devicePolicyInfo.aliasHash[i]) {
975             LOGI("device alias is not match.");
976             return false;
977         }
978     }
979     LOGI("device alias is match.");
980     return true;
981 }
982 
CheckDeviceNumberMatch(const DevicePolicyInfo & devicePolicyInfo,int32_t startNumber,int32_t endNumber)983 bool MineSoftbusListener::CheckDeviceNumberMatch(const DevicePolicyInfo &devicePolicyInfo,
984     int32_t startNumber, int32_t endNumber)
985 {
986     if (!devicePolicyInfo.numberValid) {
987         LOGE("device number is not valid");
988         return false;
989     }
990     if (startNumber <= DM_INVALID_DEVICE_NUMBER || endNumber <= DM_INVALID_DEVICE_NUMBER) {
991         LOGI("device number is match");
992         return true;
993     }
994     int deviceNumber = atoi((const char *)devicePolicyInfo.number);
995     if (deviceNumber < startNumber || deviceNumber > endNumber) {
996         LOGI("device number is not match.");
997         return false;
998     }
999     LOGI("device number is match.");
1000     return true;
1001 }
1002 
CheckDeviceSnMatch(const DevicePolicyInfo & devicePolicyInfo,const char * data)1003 bool MineSoftbusListener::CheckDeviceSnMatch(const DevicePolicyInfo &devicePolicyInfo, const char *data)
1004 {
1005     if (!devicePolicyInfo.snHashValid) {
1006         LOGE("device sn is not valid");
1007         return false;
1008     }
1009     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
1010         if (data[i] != devicePolicyInfo.snHash[i]) {
1011             LOGI("device sn is not match.");
1012             return false;
1013         }
1014     }
1015     LOGI("device sn is match.");
1016     return true;
1017 }
1018 
CheckDeviceTypeMatch(const DevicePolicyInfo & devicePolicyInfo,const char * data)1019 bool MineSoftbusListener::CheckDeviceTypeMatch(const DevicePolicyInfo &devicePolicyInfo, const char *data)
1020 {
1021     if (!devicePolicyInfo.typeHashValid) {
1022         LOGE("device type is not valid");
1023         return false;
1024     }
1025     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
1026         if (data[i] != devicePolicyInfo.typeHash[i]) {
1027             LOGI("device type is not match.");
1028             return false;
1029         }
1030     }
1031     LOGI("device type is match.");
1032     return true;
1033 }
1034 
CheckDeviceUdidMatch(const DevicePolicyInfo & devicePolicyInfo,const char * data)1035 bool MineSoftbusListener::CheckDeviceUdidMatch(const DevicePolicyInfo &devicePolicyInfo, const char *data)
1036 {
1037     if (!devicePolicyInfo.udidHashValid) {
1038         LOGE("device udid is not valid");
1039         return false;
1040     }
1041     for (size_t i = 0; i < DM_HASH_DATA_LEN; i++) {
1042         if (data[i] != devicePolicyInfo.udidHash[i]) {
1043             LOGI("device udid is not match.");
1044             return false;
1045         }
1046     }
1047     LOGI("device udid is match.");
1048     return true;
1049 }
1050 
GetMatchResult(const vector<int> & matchItemNum,const vector<int> & matchItemResult)1051 Action MineSoftbusListener::GetMatchResult(const vector<int> &matchItemNum, const vector<int> &matchItemResult)
1052 {
1053     int matchItemSum = 0;
1054     int matchResultSum = 0;
1055     size_t matchItemNumLen = matchItemNum.size();
1056     size_t matchItemResultLen = matchItemResult.size();
1057     size_t minLen = (matchItemNumLen >= matchItemResultLen ? matchItemResultLen : matchItemNumLen);
1058     for (size_t i = 0; i < minLen; i++) {
1059         matchResultSum += matchItemResult[i];
1060         matchItemSum += matchItemNum[i];
1061     }
1062     if (matchResultSum == 0) {
1063         return BUSINESS_EXACT_NOT_MATCH;
1064     } else if (matchItemSum == matchResultSum) {
1065         return BUSINESS_EXACT_MATCH;
1066     } else {
1067         return BUSINESS_PARTIAL_MATCH;
1068     }
1069 }
1070 } // namespace DistributedHardware
1071 } // namespace OHOS