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