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