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