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