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 "hichain_connector.h"
17
18 #include <cstdlib>
19 #include <ctime>
20 #include <functional>
21 #include <securec.h>
22
23 #include "dm_anonymous.h"
24 #include "dm_constants.h"
25 #include "dm_dfx_constants.h"
26 #include "dm_hisysevent.h"
27 #include "dm_log.h"
28 #include "dm_random.h"
29 #include "dm_radar_helper.h"
30 #include "hichain_connector_callback.h"
31 #include "multiple_user_connector.h"
32 #include "nlohmann/json.hpp"
33 #include "parameter.h"
34 #include "unistd.h"
35
36 namespace OHOS {
37 namespace DistributedHardware {
38 const int32_t PIN_CODE_NETWORK = 0;
39 const int32_t CREDENTIAL_NETWORK = 1;
40 const int32_t DELAY_TIME_MS = 10000; // 10ms
41 const int32_t FIELD_EXPIRE_TIME_VALUE = 7;
42 const int32_t SAME_ACCOUNT = 1;
43 const int32_t DEVICE_ID_HALF = 2;
44
45 constexpr const char* DEVICE_ID = "DEVICE_ID";
46 constexpr const char* FIELD_CREDENTIAL = "credential";
47 constexpr const char* ADD_HICHAIN_GROUP_SUCCESS = "ADD_HICHAIN_GROUP_SUCCESS";
48 constexpr const char* ADD_HICHAIN_GROUP_FAILED = "ADD_HICHAIN_GROUP_FAILED";
49 constexpr const char* DM_CREATE_GROUP_SUCCESS = "DM_CREATE_GROUP_SUCCESS";
50 constexpr const char* DM_CREATE_GROUP_FAILED = "DM_CREATE_GROUP_FAILED";
51 constexpr const char* ADD_HICHAIN_GROUP_SUCCESS_MSG = "dm add member to group success.";
52 constexpr const char* ADD_HICHAIN_GROUP_FAILED_MSG = "dm add member to group failed.";
53 constexpr const char* DM_CREATE_GROUP_SUCCESS_MSG = "dm create group success.";
54 constexpr const char* DM_CREATE_GROUP_FAILED_MSG = "dm create group failed.";
55 constexpr const char* DM_PKG_NAME_EXT = "com.huawei.devicemanager";
from_json(const nlohmann::json &jsonObject, GroupInfo &groupInfo)56 void from_json(const nlohmann::json &jsonObject, GroupInfo &groupInfo)
57 {
58 if (jsonObject.find(FIELD_GROUP_NAME) != jsonObject.end() && jsonObject.at(FIELD_GROUP_NAME).is_string()) {
59 groupInfo.groupName = jsonObject.at(FIELD_GROUP_NAME).get<std::string>();
60 }
61
62 if (jsonObject.find(FIELD_GROUP_ID) != jsonObject.end() && jsonObject.at(FIELD_GROUP_ID).is_string()) {
63 groupInfo.groupId = jsonObject.at(FIELD_GROUP_ID).get<std::string>();
64 }
65
66 if (jsonObject.find(FIELD_GROUP_OWNER) != jsonObject.end() && jsonObject.at(FIELD_GROUP_OWNER).is_string()) {
67 groupInfo.groupOwner = jsonObject.at(FIELD_GROUP_OWNER).get<std::string>();
68 }
69
70 if (jsonObject.find(FIELD_GROUP_TYPE) != jsonObject.end() && jsonObject.at(FIELD_GROUP_TYPE).is_number_integer()) {
71 groupInfo.groupType = jsonObject.at(FIELD_GROUP_TYPE).get<int32_t>();
72 }
73
74 if (jsonObject.find(FIELD_GROUP_VISIBILITY) != jsonObject.end() &&
75 jsonObject.at(FIELD_GROUP_VISIBILITY).is_number_integer()) {
76 groupInfo.groupVisibility = jsonObject.at(FIELD_GROUP_VISIBILITY).get<int32_t>();
77 }
78
79 if (jsonObject.find(FIELD_USER_ID) != jsonObject.end() && jsonObject.at(FIELD_USER_ID).is_string()) {
80 groupInfo.userId = jsonObject.at(FIELD_USER_ID).get<std::string>();
81 }
82 }
83
84 std::shared_ptr<IHiChainConnectorCallback> HiChainConnector::hiChainConnectorCallback_ = nullptr;
85 std::shared_ptr<IDmGroupResCallback> HiChainConnector::hiChainResCallback_ = nullptr;
86 int32_t HiChainConnector::networkStyle_ = PIN_CODE_NETWORK;
87 bool g_createGroupFlag = false;
88 bool g_deleteGroupFlag = false;
89 bool g_groupIsRedundance = false;
90
HiChainConnector()91 HiChainConnector::HiChainConnector()
92 {
93 LOGI("HiChainConnector::constructor");
94 deviceAuthCallback_ = {.onTransmit = nullptr,
95 .onSessionKeyReturned = nullptr,
96 .onFinish = HiChainConnector::onFinish,
97 .onError = HiChainConnector::onError,
98 .onRequest = HiChainConnector::onRequest};
99 InitDeviceAuthService();
100 deviceGroupManager_ = GetGmInstance();
101 if (deviceGroupManager_ == nullptr) {
102 LOGE("[HICHAIN]failed to init group manager.");
103 return;
104 }
105 int32_t ret = deviceGroupManager_->regCallback(DM_PKG_NAME, &deviceAuthCallback_);
106 if (ret != HC_SUCCESS) {
107 LOGE("[HICHAIN]fail to register callback to hachain with ret:%{public}d.", ret);
108 return;
109 }
110 LOGI("HiChainConnector::constructor success.");
111 }
112
~HiChainConnector()113 HiChainConnector::~HiChainConnector()
114 {
115 LOGI("HiChainConnector::destructor.");
116 }
117
RegisterHiChainCallback(std::shared_ptr<IHiChainConnectorCallback> callback)118 int32_t HiChainConnector::RegisterHiChainCallback(std::shared_ptr<IHiChainConnectorCallback> callback)
119 {
120 hiChainConnectorCallback_ = callback;
121 return DM_OK;
122 }
123
UnRegisterHiChainCallback()124 int32_t HiChainConnector::UnRegisterHiChainCallback()
125 {
126 hiChainConnectorCallback_ = nullptr;
127 return DM_OK;
128 }
129
CreateGroup(int64_t requestId, const std::string &groupName)130 int32_t HiChainConnector::CreateGroup(int64_t requestId, const std::string &groupName)
131 {
132 if (deviceGroupManager_ == nullptr) {
133 LOGE("HiChainConnector::CreateGroup group manager is null, requestId %{public}" PRId64, requestId);
134 return ERR_DM_INPUT_PARA_INVALID;
135 }
136 networkStyle_ = PIN_CODE_NETWORK;
137 GroupInfo groupInfo;
138 if (IsGroupCreated(groupName, groupInfo)) {
139 DeleteGroup(groupInfo.groupId);
140 }
141 LOGI("HiChainConnector::CreateGroup requestId %{public}" PRId64, requestId);
142 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
143 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
144 std::string sLocalDeviceId = localDeviceId;
145 nlohmann::json jsonObj;
146 jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
147 jsonObj[FIELD_DEVICE_ID] = sLocalDeviceId;
148 jsonObj[FIELD_GROUP_NAME] = groupName;
149 jsonObj[FIELD_USER_TYPE] = 0;
150 jsonObj[FIELD_GROUP_VISIBILITY] = GROUP_VISIBILITY_PUBLIC;
151 jsonObj[FIELD_EXPIRE_TIME] = FIELD_EXPIRE_TIME_VALUE;
152 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
153 if (userId < 0) {
154 LOGE("get current process account user id failed");
155 return ERR_DM_FAILED;
156 }
157
158 int32_t ret = deviceGroupManager_->createGroup(userId, requestId, DM_PKG_NAME, jsonObj.dump().c_str());
159 struct RadarInfo info = {
160 .funcName = "CreateGroup",
161 .toCallPkg = HICHAINNAME,
162 .stageRes = (ret != 0) ?
163 static_cast<int32_t>(StageRes::STAGE_FAIL) : static_cast<int32_t>(StageRes::STAGE_IDLE),
164 .bizState = (ret != 0) ?
165 static_cast<int32_t>(BizState::BIZ_STATE_END) : static_cast<int32_t>(BizState::BIZ_STATE_START),
166 .errCode = DmRadarHelper::GetInstance().GetErrCode(ERR_DM_CREATE_GROUP_FAILED),
167 };
168 if (!DmRadarHelper::GetInstance().ReportAuthCreateGroup(info)) {
169 LOGE("ReportAuthCreateGroup failed");
170 }
171 if (ret != 0) {
172 LOGE("[HICHAIN]fail to create group with ret:%{public}d, requestId:%{public}" PRId64, ret, requestId);
173 return ERR_DM_CREATE_GROUP_FAILED;
174 }
175 return DM_OK;
176 }
177
IsGroupCreated(std::string groupName, GroupInfo &groupInfo)178 bool HiChainConnector::IsGroupCreated(std::string groupName, GroupInfo &groupInfo)
179 {
180 nlohmann::json jsonObj;
181 jsonObj[FIELD_GROUP_NAME] = groupName.c_str();
182 std::string queryParams = jsonObj.dump();
183 std::vector<GroupInfo> groupList;
184 if (GetGroupInfo(queryParams, groupList)) {
185 groupInfo = groupList[0];
186 return true;
187 }
188 return false;
189 }
190
IsRedundanceGroup(const std::string &userId, int32_t authType, std::vector<GroupInfo> &groupList)191 bool HiChainConnector::IsRedundanceGroup(const std::string &userId, int32_t authType, std::vector<GroupInfo> &groupList)
192 {
193 nlohmann::json jsonObj;
194 jsonObj[FIELD_GROUP_TYPE] = authType;
195 std::string queryParams = jsonObj.dump();
196
197 int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
198 if (osAccountUserId < 0) {
199 LOGE("get current process account user id failed");
200 return ERR_DM_FAILED;
201 }
202 if (!GetGroupInfo(osAccountUserId, queryParams, groupList)) {
203 return false;
204 }
205 for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
206 if (iter->userId != userId) {
207 return true;
208 }
209 }
210 return false;
211 }
212
GetGroupInfo(const std::string &queryParams, std::vector<GroupInfo> &groupList)213 bool HiChainConnector::GetGroupInfo(const std::string &queryParams, std::vector<GroupInfo> &groupList)
214 {
215 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
216 if (userId < 0) {
217 LOGE("get current process account user id failed");
218 return false;
219 }
220 return GetGroupInfo(userId, queryParams, groupList);
221 }
222
GetGroupInfo(const int32_t userId, const std::string &queryParams, std::vector<GroupInfo> &groupList)223 bool HiChainConnector::GetGroupInfo(const int32_t userId, const std::string &queryParams,
224 std::vector<GroupInfo> &groupList)
225 {
226 return GetGroupInfoCommon(userId, queryParams, DM_PKG_NAME, groupList);
227 }
228
GetGroupInfoExt(const int32_t userId, const std::string &queryParams, std::vector<GroupInfo> &groupList)229 bool HiChainConnector::GetGroupInfoExt(const int32_t userId, const std::string &queryParams,
230 std::vector<GroupInfo> &groupList)
231 {
232 return GetGroupInfoCommon(userId, queryParams, DM_PKG_NAME_EXT, groupList);
233 }
234
GetGroupInfoCommon(const int32_t userId, const std::string &queryParams, const char* pkgName, std::vector<GroupInfo> &groupList)235 bool HiChainConnector::GetGroupInfoCommon(const int32_t userId, const std::string &queryParams, const char* pkgName,
236 std::vector<GroupInfo> &groupList)
237 {
238 char *groupVec = nullptr;
239 uint32_t num = 0;
240 if (deviceGroupManager_ == nullptr) {
241 LOGE("deviceGroupManager_ is null");
242 return false;
243 }
244 int32_t ret = deviceGroupManager_->getGroupInfo(userId, pkgName, queryParams.c_str(), &groupVec, &num);
245 if (ret != 0) {
246 LOGE("[HICHAIN]fail to get group info with ret:%{public}d.", ret);
247 return false;
248 }
249 if (groupVec == nullptr) {
250 LOGE("[HICHAIN]return groups info point is nullptr");
251 return false;
252 }
253 if (num == 0) {
254 LOGE("[HICHAIN]return groups info number is zero.");
255 return false;
256 }
257 LOGI("HiChainConnector::GetGroupInfo groupNum(%{public}u)", num);
258 std::string relatedGroups = std::string(groupVec);
259 deviceGroupManager_->destroyInfo(&groupVec);
260 nlohmann::json jsonObject = nlohmann::json::parse(relatedGroups, nullptr, false);
261 if (jsonObject.is_discarded()) {
262 LOGE("returnGroups parse error");
263 return false;
264 }
265 if (!jsonObject.is_array()) {
266 LOGE("json string is not array.");
267 return false;
268 }
269 std::vector<GroupInfo> groupInfos = jsonObject.get<std::vector<GroupInfo>>();
270 if (groupInfos.size() == 0) {
271 LOGE("HiChainConnector::GetGroupInfo group failed, groupInfos is empty.");
272 return false;
273 }
274 groupList = groupInfos;
275 return true;
276 }
277
GetGroupType(const std::string &deviceId)278 DmAuthForm HiChainConnector::GetGroupType(const std::string &deviceId)
279 {
280 std::vector<OHOS::DistributedHardware::GroupInfo> groupList;
281 int32_t ret = GetRelatedGroups(deviceId, groupList);
282 if (ret != DM_OK) {
283 LOGE("HiChainConnector::GetGroupType get related groups failed");
284 return DmAuthForm::INVALID_TYPE;
285 }
286
287 if (groupList.size() == 0) {
288 LOGE("HiChainConnector::GetGroupType group list is empty");
289 return DmAuthForm::INVALID_TYPE;
290 }
291
292 AuthFormPriority highestPriority = AuthFormPriority::PRIORITY_PEER_TO_PEER;
293 for (auto it = groupList.begin(); it != groupList.end(); ++it) {
294 if (g_authFormPriorityMap.count(it->groupType) == 0) {
295 LOGE("HiChainConnector::GetGroupType unsupported auth form");
296 return DmAuthForm::INVALID_TYPE;
297 }
298 AuthFormPriority priority = g_authFormPriorityMap.at(it->groupType);
299 if (priority > highestPriority) {
300 highestPriority = priority;
301 }
302 }
303
304 if (highestPriority == AuthFormPriority::PRIORITY_IDENTICAL_ACCOUNT) {
305 return DmAuthForm::IDENTICAL_ACCOUNT;
306 } else if (highestPriority == AuthFormPriority::PRIORITY_ACROSS_ACCOUNT) {
307 return DmAuthForm::ACROSS_ACCOUNT;
308 } else if (highestPriority == AuthFormPriority::PRIORITY_PEER_TO_PEER) {
309 return DmAuthForm::PEER_TO_PEER;
310 }
311
312 return DmAuthForm::INVALID_TYPE;
313 }
314
AddMember(const std::string &deviceId, const std::string &connectInfo)315 int32_t HiChainConnector::AddMember(const std::string &deviceId, const std::string &connectInfo)
316 {
317 LOGI("HiChainConnector::AddMember");
318 if (deviceGroupManager_ == nullptr) {
319 LOGI("HiChainConnector::AddMember group manager is null.");
320 return ERR_DM_POINT_NULL;
321 }
322 nlohmann::json jsonObject = nlohmann::json::parse(connectInfo, nullptr, false);
323 if (jsonObject.is_discarded()) {
324 LOGE("DecodeRequestAuth jsonStr error");
325 return ERR_DM_FAILED;
326 }
327 if (!IsString(jsonObject, TAG_DEVICE_ID) || !IsInt32(jsonObject, PIN_CODE_KEY) ||
328 !IsString(jsonObject, TAG_GROUP_ID) || !IsInt64(jsonObject, TAG_REQUEST_ID) ||
329 !IsString(jsonObject, TAG_GROUP_NAME)) {
330 LOGE("HiChainConnector::AddMember err json string.");
331 return ERR_DM_FAILED;
332 }
333 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
334 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
335 std::string connectInfomation = GetConnectPara(deviceId, jsonObject[TAG_DEVICE_ID].get<std::string>());
336
337 int32_t pinCode = jsonObject[PIN_CODE_KEY].get<int32_t>();
338 std::string groupId = jsonObject[TAG_GROUP_ID].get<std::string>();
339 nlohmann::json jsonObj;
340 jsonObj[FIELD_GROUP_ID] = groupId;
341 jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
342 jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode).c_str();
343 jsonObj[FIELD_IS_ADMIN] = false;
344 jsonObj[FIELD_DEVICE_ID] = localDeviceId;
345 jsonObj[FIELD_GROUP_NAME] = jsonObject[TAG_GROUP_NAME].get<std::string>();
346 jsonObj[FIELD_CONNECT_PARAMS] = connectInfomation.c_str();
347 std::string tmpStr = jsonObj.dump();
348 int64_t requestId = jsonObject[TAG_REQUEST_ID].get<int64_t>();
349 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
350 if (userId < 0) {
351 LOGE("get current process account user id failed");
352 return ERR_DM_FAILED;
353 }
354 int32_t ret = deviceGroupManager_->addMemberToGroup(userId, requestId, DM_PKG_NAME, tmpStr.c_str());
355 if (ret != 0) {
356 LOGE("[HICHAIN]fail to add number to hichain group with ret:%{public}d.", ret);
357 }
358 LOGI("HiChainConnector::AddMember completed");
359 return ret;
360 }
361
onFinish(int64_t requestId, int operationCode, const char *returnData)362 void HiChainConnector::onFinish(int64_t requestId, int operationCode, const char *returnData)
363 {
364 std::string data = (returnData != nullptr) ? std::string(returnData) : "";
365 LOGI("HiChainConnector::onFinish reqId:%{public}" PRId64 ", operation:%{public}d", requestId, operationCode);
366 if (operationCode == GroupOperationCode::MEMBER_JOIN) {
367 LOGI("Add Member To Group success");
368 if (!DmRadarHelper::GetInstance().ReportAuthAddGroupCb(
369 "onFinish", static_cast<int32_t>(StageRes::STAGE_SUCC))) {
370 LOGE("ReportAuthAddGroupCb failed");
371 }
372 SysEventWrite(std::string(ADD_HICHAIN_GROUP_SUCCESS), DM_HISYEVENT_BEHAVIOR,
373 std::string(ADD_HICHAIN_GROUP_SUCCESS_MSG));
374 if (hiChainConnectorCallback_ != nullptr) {
375 hiChainConnectorCallback_->OnMemberJoin(requestId, DM_OK);
376 }
377 }
378 if (operationCode == GroupOperationCode::GROUP_CREATE) {
379 LOGI("Create group success");
380 if (!DmRadarHelper::GetInstance().ReportAuthCreateGroupCb(
381 "onFinish", static_cast<int32_t>(StageRes::STAGE_SUCC))) {
382 LOGE("ReportAuthCreateGroupCb failed");
383 }
384 SysEventWrite(std::string(DM_CREATE_GROUP_SUCCESS), DM_HISYEVENT_BEHAVIOR,
385 std::string(DM_CREATE_GROUP_SUCCESS_MSG));
386 if (networkStyle_ == CREDENTIAL_NETWORK) {
387 if (hiChainResCallback_ != nullptr) {
388 int32_t importAction = 0;
389 hiChainResCallback_->OnGroupResult(requestId, importAction, data);
390 g_createGroupFlag = true;
391 }
392 } else {
393 if (hiChainConnectorCallback_ != nullptr) {
394 hiChainConnectorCallback_->OnMemberJoin(requestId, DM_OK);
395 hiChainConnectorCallback_->OnGroupCreated(requestId, data);
396 }
397 }
398 }
399 if (operationCode == GroupOperationCode::MEMBER_DELETE) {
400 LOGI("Delete Member from group success");
401 }
402 if (operationCode == GroupOperationCode::GROUP_DISBAND) {
403 if (networkStyle_ == CREDENTIAL_NETWORK && hiChainResCallback_ != nullptr) {
404 if (!g_groupIsRedundance) {
405 int32_t deleteAction = 1;
406 hiChainResCallback_->OnGroupResult(requestId, deleteAction, data);
407 }
408 g_deleteGroupFlag = true;
409 }
410 LOGI("Disband group success");
411 }
412 }
413
onError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn)414 void HiChainConnector::onError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn)
415 {
416 std::string data = (errorReturn != nullptr) ? std::string(errorReturn) : "";
417 LOGI("HichainAuthenCallBack::onError reqId:%{public}" PRId64 ", operation:%{public}d, errorCode:%{public}d.",
418 requestId, operationCode, errorCode);
419 if (operationCode == GroupOperationCode::MEMBER_JOIN) {
420 LOGE("Add Member To Group failed");
421 if (!DmRadarHelper::GetInstance().ReportAuthAddGroupCb(
422 "onError", static_cast<int32_t>(StageRes::STAGE_FAIL))) {
423 LOGE("ReportAuthAddGroupCb failed");
424 }
425 SysEventWrite(std::string(ADD_HICHAIN_GROUP_FAILED), DM_HISYEVENT_BEHAVIOR,
426 std::string(ADD_HICHAIN_GROUP_FAILED_MSG));
427 if (hiChainConnectorCallback_ != nullptr) {
428 hiChainConnectorCallback_->OnMemberJoin(requestId, ERR_DM_ADD_GROUP_FAILED);
429 }
430 }
431 if (operationCode == GroupOperationCode::GROUP_CREATE) {
432 LOGE("Create group failed");
433 if (!DmRadarHelper::GetInstance().ReportAuthCreateGroupCb(
434 "onError", static_cast<int32_t>(StageRes::STAGE_FAIL))) {
435 LOGE("ReportAuthCreateGroupCb failed");
436 }
437 SysEventWrite(std::string(DM_CREATE_GROUP_FAILED), DM_HISYEVENT_BEHAVIOR,
438 std::string(DM_CREATE_GROUP_FAILED_MSG));
439 if (networkStyle_ == CREDENTIAL_NETWORK) {
440 if (hiChainResCallback_ != nullptr) {
441 int32_t importAction = 0;
442 hiChainResCallback_->OnGroupResult(requestId, importAction, data);
443 g_createGroupFlag = true;
444 }
445 } else {
446 if (hiChainConnectorCallback_ != nullptr) {
447 hiChainConnectorCallback_->OnGroupCreated(requestId, "{}");
448 }
449 }
450 }
451 if (operationCode == GroupOperationCode::MEMBER_DELETE) {
452 LOGE("Delete Member from group failed");
453 }
454 if (operationCode == GroupOperationCode::GROUP_DISBAND) {
455 if (networkStyle_ == CREDENTIAL_NETWORK && hiChainResCallback_ != nullptr) {
456 if (!g_groupIsRedundance) {
457 int32_t deleteAction = 1;
458 hiChainResCallback_->OnGroupResult(requestId, deleteAction, data);
459 }
460 g_deleteGroupFlag = true;
461 }
462 LOGE("Disband group failed");
463 }
464 }
465
onRequest(int64_t requestId, int operationCode, const char *reqParams)466 char *HiChainConnector::onRequest(int64_t requestId, int operationCode, const char *reqParams)
467 {
468 (void)requestId;
469 (void)reqParams;
470 if (operationCode != GroupOperationCode::MEMBER_JOIN) {
471 LOGE("HiChainConnector::onRequest operationCode %{public}d", operationCode);
472 return nullptr;
473 }
474 if (hiChainConnectorCallback_ == nullptr) {
475 LOGE("HiChainConnector::onRequest hiChainConnectorCallback_ is nullptr.");
476 return nullptr;
477 }
478 nlohmann::json jsonObj;
479 int32_t pinCode = 0;
480 if (hiChainConnectorCallback_->GetPinCode(pinCode) == ERR_DM_FAILED) {
481 jsonObj[FIELD_CONFIRMATION] = REQUEST_REJECTED;
482 } else {
483 jsonObj[FIELD_CONFIRMATION] = REQUEST_ACCEPTED;
484 }
485 jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode).c_str();
486 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
487 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
488 jsonObj[FIELD_DEVICE_ID] = localDeviceId;
489
490 std::string jsonStr = jsonObj.dump();
491 char *buffer = strdup(jsonStr.c_str());
492 return buffer;
493 }
494
GenRequestId()495 int64_t HiChainConnector::GenRequestId()
496 {
497 return GenRandLongLong(MIN_REQUEST_ID, MAX_REQUEST_ID);
498 }
499
GetConnectPara(std::string deviceId, std::string reqDeviceId)500 std::string HiChainConnector::GetConnectPara(std::string deviceId, std::string reqDeviceId)
501 {
502 LOGI("HiChainConnector::GetConnectPara get addrInfo");
503 if (hiChainConnectorCallback_ == nullptr) {
504 LOGE("HiChainConnector::GetConnectPara hiChainConnectorCallback_ is nullptr.");
505 return "";
506 }
507 std::string connectAddr = hiChainConnectorCallback_->GetConnectAddr(deviceId);
508 nlohmann::json jsonObject = nlohmann::json::parse(connectAddr, nullptr, false);
509 if (jsonObject.is_discarded()) {
510 LOGE("DecodeRequestAuth jsonStr error");
511 return connectAddr;
512 }
513 jsonObject[DEVICE_ID] = reqDeviceId;
514
515 return jsonObject.dump();
516 }
517
GetRelatedGroups(const std::string &deviceId, std::vector<GroupInfo> &groupList)518 int32_t HiChainConnector::GetRelatedGroups(const std::string &deviceId, std::vector<GroupInfo> &groupList)
519 {
520 return GetRelatedGroupsCommon(deviceId, DM_PKG_NAME, groupList);
521 }
522
GetRelatedGroupsExt(const std::string &deviceId, std::vector<GroupInfo> &groupList)523 int32_t HiChainConnector::GetRelatedGroupsExt(const std::string &deviceId, std::vector<GroupInfo> &groupList)
524 {
525 return GetRelatedGroupsCommon(deviceId, DM_PKG_NAME_EXT, groupList);
526 }
527
GetSyncGroupList(std::vector<GroupInfo> &groupList, std::vector<std::string> &syncGroupList)528 int32_t HiChainConnector::GetSyncGroupList(std::vector<GroupInfo> &groupList, std::vector<std::string> &syncGroupList)
529 {
530 if (groupList.empty()) {
531 LOGE("groupList is empty.");
532 return ERR_DM_FAILED;
533 }
534 for (auto group : groupList) {
535 if (IsGroupInfoInvalid(group)) {
536 continue;
537 }
538 syncGroupList.push_back(group.groupId);
539 }
540 return DM_OK;
541 }
542
IsDevicesInP2PGroup(const std::string &hostDevice, const std::string &peerDevice)543 bool HiChainConnector::IsDevicesInP2PGroup(const std::string &hostDevice, const std::string &peerDevice)
544 {
545 LOGI("HiChainConnector::IsDevicesInP2PGroup");
546 std::vector<GroupInfo> hostGroupInfoList;
547 GetRelatedGroups(hostDevice, hostGroupInfoList);
548 std::vector<GroupInfo> peerGroupInfoList;
549 GetRelatedGroups(peerDevice, peerGroupInfoList);
550 for (const auto &hostGroupInfo : hostGroupInfoList) {
551 if (hostGroupInfo.groupType != GROUP_TYPE_PEER_TO_PEER_GROUP) {
552 continue;
553 }
554 for (const auto &peerGroupInfo : peerGroupInfoList) {
555 if (peerGroupInfo.groupType != GROUP_TYPE_PEER_TO_PEER_GROUP) {
556 continue;
557 }
558 if (hostGroupInfo.groupId == peerGroupInfo.groupId && hostGroupInfo.groupName == peerGroupInfo.groupName) {
559 LOGE("these are authenticated");
560 return true;
561 }
562 }
563 }
564 return false;
565 }
566
IsGroupInfoInvalid(GroupInfo &group)567 bool HiChainConnector::IsGroupInfoInvalid(GroupInfo &group)
568 {
569 if (group.groupType == GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP || group.groupVisibility == GROUP_VISIBILITY_PUBLIC ||
570 group.groupOwner != std::string(DM_PKG_NAME)) {
571 return true;
572 }
573 return false;
574 }
575
SyncGroups(std::string deviceId, std::vector<std::string> &remoteGroupIdList)576 int32_t HiChainConnector::SyncGroups(std::string deviceId, std::vector<std::string> &remoteGroupIdList)
577 {
578 std::vector<GroupInfo> groupInfoList;
579 GetRelatedGroups(deviceId, groupInfoList);
580 for (auto &groupInfo : groupInfoList) {
581 if (IsGroupInfoInvalid(groupInfo)) {
582 continue;
583 }
584 auto iter = std::find(remoteGroupIdList.begin(), remoteGroupIdList.end(), groupInfo.groupId);
585 if (iter == remoteGroupIdList.end()) {
586 (void)DelMemberFromGroup(groupInfo.groupId, deviceId);
587 }
588 }
589 return DM_OK;
590 }
591
DelMemberFromGroup(const std::string &groupId, const std::string &deviceId)592 int32_t HiChainConnector::DelMemberFromGroup(const std::string &groupId, const std::string &deviceId)
593 {
594 int64_t requestId = GenRequestId();
595 LOGI("Start to delete member from group, requestId %{public}" PRId64", deviceId %{public}s, groupId %{public}s",
596 requestId, GetAnonyString(deviceId).c_str(), GetAnonyString(groupId).c_str());
597 nlohmann::json jsonObj;
598 jsonObj[FIELD_GROUP_ID] = groupId;
599 jsonObj[FIELD_DELETE_ID] = deviceId;
600 std::string deleteParams = jsonObj.dump();
601 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
602 if (userId < 0) {
603 LOGE("get current process account user id failed");
604 return ERR_DM_FAILED;
605 }
606 int32_t ret = deviceGroupManager_->deleteMemberFromGroup(userId, requestId, DM_PKG_NAME, deleteParams.c_str());
607 if (ret != 0) {
608 LOGE("[HICHAIN]fail to delete member from group with ret:%{public}d.", ret);
609 return ret;
610 }
611 return DM_OK;
612 }
613
DeleteGroup(std::string &groupId)614 int32_t HiChainConnector::DeleteGroup(std::string &groupId)
615 {
616 int64_t requestId = GenRequestId();
617 nlohmann::json jsonObj;
618 jsonObj[FIELD_GROUP_ID] = groupId;
619 std::string disbandParams = jsonObj.dump();
620 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
621 if (userId < 0) {
622 LOGE("get current process account user id failed");
623 return ERR_DM_FAILED;
624 }
625
626 int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME, disbandParams.c_str());
627 if (ret != 0) {
628 LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
629 return ERR_DM_FAILED;
630 }
631 return DM_OK;
632 }
633
DeleteGroupExt(std::string &groupId)634 int32_t HiChainConnector::DeleteGroupExt(std::string &groupId)
635 {
636 int64_t requestId = GenRequestId();
637 nlohmann::json jsonObj;
638 jsonObj[FIELD_GROUP_ID] = groupId;
639 std::string disbandParams = jsonObj.dump();
640 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
641 if (userId < 0) {
642 LOGE("get current process account user id failed");
643 return ERR_DM_FAILED;
644 }
645
646 int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME_EXT, disbandParams.c_str());
647 if (ret != 0) {
648 LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
649 return ERR_DM_FAILED;
650 }
651 return DM_OK;
652 }
653
DeleteGroup(const int32_t userId, std::string &groupId)654 int32_t HiChainConnector::DeleteGroup(const int32_t userId, std::string &groupId)
655 {
656 int64_t requestId = GenRequestId();
657 nlohmann::json jsonObj;
658 jsonObj[FIELD_GROUP_ID] = groupId;
659 std::string disbandParams = jsonObj.dump();
660 int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME, disbandParams.c_str());
661 if (ret != 0) {
662 LOGE("[HICHAIN]fail to delete group failed, ret: %{public}d.", ret);
663 return ERR_DM_FAILED;
664 }
665 return DM_OK;
666 }
667
DeleteGroup(int64_t requestId_, const std::string &userId, const int32_t authType)668 int32_t HiChainConnector::DeleteGroup(int64_t requestId_, const std::string &userId, const int32_t authType)
669 {
670 networkStyle_ = CREDENTIAL_NETWORK;
671 nlohmann::json jsonObj;
672 jsonObj[FIELD_GROUP_TYPE] = authType;
673 std::string queryParams = jsonObj.dump();
674 std::vector<GroupInfo> groupList;
675 if (!GetGroupInfo(queryParams, groupList)) {
676 LOGE("failed to get device join groups");
677 return ERR_DM_FAILED;
678 }
679 LOGI("HiChainConnector::DeleteGroup groupList count = %{public}zu", groupList.size());
680 bool userIsExist = false;
681 std::string groupId = "";
682 for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
683 if (iter->userId == userId) {
684 userIsExist = true;
685 groupId = iter->groupId;
686 break;
687 }
688 }
689 if (!userIsExist) {
690 LOGE("input userId is exist in groupList!");
691 return ERR_DM_FAILED;
692 }
693 jsonObj[FIELD_GROUP_ID] = groupId;
694 std::string disbandParams = jsonObj.dump();
695 g_deleteGroupFlag = false;
696 int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
697 if (osAccountUserId < 0) {
698 LOGE("get current process account user id failed");
699 return ERR_DM_FAILED;
700 }
701 int32_t ret = deviceGroupManager_->deleteGroup(osAccountUserId, requestId_, DM_PKG_NAME,
702 disbandParams.c_str());
703 if (ret != 0) {
704 LOGE("[HICHAIN]fail to delete hichain group with ret:%{public}d.", ret);
705 return ERR_DM_FAILED;
706 }
707 int32_t nTickTimes = 0;
708 while (!g_deleteGroupFlag) {
709 usleep(DELAY_TIME_MS);
710 if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
711 LOGE("failed to delete group because timeout!");
712 return ERR_DM_FAILED;
713 }
714 }
715 return DM_OK;
716 }
717
DeleteTimeOutGroup(const char* deviceId)718 int32_t HiChainConnector::DeleteTimeOutGroup(const char* deviceId)
719 {
720 LOGI("HiChainConnector::DeleteTimeOutGroup start");
721 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
722 if (userId < 0) {
723 LOGE("get current process account user id failed");
724 return ERR_DM_FAILED;
725 }
726 std::vector<GroupInfo> peerGroupInfoList;
727 GetRelatedGroups(deviceId, peerGroupInfoList);
728 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
729 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
730 for (auto &group : peerGroupInfoList) {
731 if (!(deviceGroupManager_->isDeviceInGroup(userId, DM_PKG_NAME, group.groupId.c_str(), localDeviceId))) {
732 continue;
733 }
734 if ((!group.groupName.empty()) && (group.groupName[CHECK_AUTH_ALWAYS_POS] == AUTH_ALWAYS)) {
735 LOGI("HiChainConnector::DeleteTimeOutGroup always trusted group");
736 continue;
737 }
738 if (group.groupType == GROUP_TYPE_PEER_TO_PEER_GROUP) {
739 DeleteGroup(group.groupId);
740 }
741 }
742 return DM_OK;
743 }
744
DeleteRedundanceGroup(std::string &userId)745 void HiChainConnector::DeleteRedundanceGroup(std::string &userId)
746 {
747 int32_t nTickTimes = 0;
748 g_deleteGroupFlag = false;
749 DeleteGroup(userId);
750 while (!g_deleteGroupFlag) {
751 usleep(DELAY_TIME_MS);
752 if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
753 LOGE("failed to delete group because timeout!");
754 return;
755 }
756 }
757 }
758
DealRedundanceGroup(const std::string &userId, int32_t authType)759 void HiChainConnector::DealRedundanceGroup(const std::string &userId, int32_t authType)
760 {
761 g_groupIsRedundance = false;
762 std::vector<GroupInfo> groupList;
763 if (IsRedundanceGroup(userId, authType, groupList)) {
764 LOGI("HiChainConnector::CreateGroup IsRedundanceGroup");
765 g_groupIsRedundance = true;
766 for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
767 if (iter->userId != userId) {
768 DeleteRedundanceGroup(iter->userId);
769 }
770 }
771 g_groupIsRedundance = false;
772 }
773 }
774
CreateGroup(int64_t requestId, int32_t authType, const std::string &userId, nlohmann::json &jsonOutObj)775 int32_t HiChainConnector::CreateGroup(int64_t requestId, int32_t authType, const std::string &userId,
776 nlohmann::json &jsonOutObj)
777 {
778 LOGI("HiChainConnector::CreateGroup start.");
779 if (deviceGroupManager_ == nullptr) {
780 LOGE("HiChainConnector::CreateGroup group manager is null, requestId %{public}" PRId64, requestId);
781 return ERR_DM_INPUT_PARA_INVALID;
782 }
783 DealRedundanceGroup(userId, authType);
784 networkStyle_ = CREDENTIAL_NETWORK;
785 LOGI("HiChainConnector::CreateGroup requestId %{public}" PRId64, requestId);
786 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
787 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
788 std::string sLocalDeviceId = localDeviceId;
789 nlohmann::json jsonObj;
790 jsonObj[FIELD_GROUP_TYPE] = authType;
791 jsonObj[FIELD_USER_ID] = userId;
792 jsonObj[FIELD_CREDENTIAL] = jsonOutObj;
793 jsonObj[FIELD_DEVICE_ID] = sLocalDeviceId;
794 jsonObj[FIELD_USER_TYPE] = 0;
795 jsonObj[FIELD_GROUP_VISIBILITY] = GROUP_VISIBILITY_PUBLIC;
796 jsonObj[FIELD_EXPIRE_TIME] = FIELD_EXPIRE_TIME_VALUE;
797 g_createGroupFlag = false;
798 int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
799 if (osAccountUserId < 0) {
800 LOGE("get current process account user id failed");
801 return ERR_DM_FAILED;
802 }
803
804 int32_t ret = deviceGroupManager_->createGroup(osAccountUserId, requestId, DM_PKG_NAME, jsonObj.dump().c_str());
805 if (ret != DM_OK) {
806 LOGE("[HICHAIN]fail to create group with ret:%{public}d, requestId:%{public}" PRId64, ret, requestId);
807 return ERR_DM_CREATE_GROUP_FAILED;
808 }
809 int32_t nTickTimes = 0;
810 while (!g_createGroupFlag) {
811 usleep(DELAY_TIME_MS);
812 if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
813 LOGE("failed to create group because timeout!");
814 return ERR_DM_CREATE_GROUP_FAILED;
815 }
816 }
817 return DM_OK;
818 }
819
RegisterHiChainGroupCallback(const std::shared_ptr<IDmGroupResCallback> &callback)820 int32_t HiChainConnector::RegisterHiChainGroupCallback(const std::shared_ptr<IDmGroupResCallback> &callback)
821 {
822 hiChainResCallback_ = callback;
823 return DM_OK;
824 }
825
UnRegisterHiChainGroupCallback()826 int32_t HiChainConnector::UnRegisterHiChainGroupCallback()
827 {
828 hiChainResCallback_ = nullptr;
829 return DM_OK;
830 }
831
getRegisterInfo(const std::string &queryParams, std::string &returnJsonStr)832 int32_t HiChainConnector::getRegisterInfo(const std::string &queryParams, std::string &returnJsonStr)
833 {
834 if (deviceGroupManager_ == nullptr) {
835 LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
836 return ERR_DM_INPUT_PARA_INVALID;
837 }
838 char *credentialInfo = nullptr;
839 if (deviceGroupManager_->getRegisterInfo(queryParams.c_str(), &credentialInfo) != DM_OK) {
840 LOGE("[HICHAIN]fail to request hichain registerinfo.");
841 return ERR_DM_FAILED;
842 }
843
844 returnJsonStr = credentialInfo;
845 deviceGroupManager_->destroyInfo(&credentialInfo);
846 LOGI("request hichain device registerinfo successfully.");
847 return DM_OK;
848 }
849
GetGroupId(const std::string &userId, const int32_t groupType, std::string &groupId)850 int32_t HiChainConnector::GetGroupId(const std::string &userId, const int32_t groupType, std::string &groupId)
851 {
852 nlohmann::json jsonObjGroup;
853 jsonObjGroup[FIELD_GROUP_TYPE] = groupType;
854 std::string queryParams = jsonObjGroup.dump();
855 std::vector<GroupInfo> groupList;
856
857 if (!GetGroupInfo(queryParams.c_str(), groupList)) {
858 LOGE("failed to get device join groups");
859 return ERR_DM_FAILED;
860 }
861 for (auto &groupinfo : groupList) {
862 LOGI("groupinfo.groupId:%{public}s", GetAnonyString(groupinfo.groupId).c_str());
863 if (groupinfo.userId == userId) {
864 groupId = groupinfo.groupId;
865 return DM_OK;
866 }
867 }
868 return ERR_DM_FAILED;
869 }
870
ParseRemoteCredential(const int32_t groupType, const std::string &userId, const nlohmann::json &jsonDeviceList, std::string ¶ms, int32_t &osAccountUserId)871 int32_t HiChainConnector::ParseRemoteCredential(const int32_t groupType, const std::string &userId,
872 const nlohmann::json &jsonDeviceList, std::string ¶ms, int32_t &osAccountUserId)
873 {
874 if (userId.empty() || !jsonDeviceList.contains(FIELD_DEVICE_LIST)) {
875 LOGE("userId or deviceList is empty");
876 return ERR_DM_INPUT_PARA_INVALID;
877 }
878 std::string groupId;
879 if (GetGroupId(userId, groupType, groupId) != DM_OK) {
880 LOGE("failed to get groupid");
881 return ERR_DM_FAILED;
882 }
883 nlohmann::json jsonObj;
884 jsonObj[FIELD_GROUP_ID] = groupId;
885 jsonObj[FIELD_GROUP_TYPE] = groupType;
886 jsonObj[FIELD_DEVICE_LIST] = jsonDeviceList[FIELD_DEVICE_LIST];
887 params = jsonObj.dump();
888 osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
889 if (osAccountUserId < 0) {
890 LOGE("get current process account user id failed");
891 return ERR_DM_FAILED;
892 }
893 return DM_OK;
894 }
895
addMultiMembers(const int32_t groupType, const std::string &userId, const nlohmann::json &jsonDeviceList)896 int32_t HiChainConnector::addMultiMembers(const int32_t groupType, const std::string &userId,
897 const nlohmann::json &jsonDeviceList)
898 {
899 if (deviceGroupManager_ == nullptr) {
900 LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
901 return ERR_DM_INPUT_PARA_INVALID;
902 }
903 std::string addParams;
904 int32_t osAccountUserId = 0;
905 if (ParseRemoteCredential(groupType, userId, jsonDeviceList, addParams, osAccountUserId) != DM_OK) {
906 LOGE("addMultiMembers ParseRemoteCredential failed!");
907 return ERR_DM_FAILED;
908 }
909
910 int32_t ret = deviceGroupManager_->addMultiMembersToGroup(osAccountUserId, DM_PKG_NAME, addParams.c_str());
911 if (ret != DM_OK) {
912 LOGE("[HICHAIN]fail to add member to hichain group with ret:%{public}d.", ret);
913 return ERR_DM_ADD_GROUP_FAILED;
914 }
915 return DM_OK;
916 }
917
GetJsonStr(const nlohmann::json &jsonObj, const std::string &key)918 std::string HiChainConnector::GetJsonStr(const nlohmann::json &jsonObj, const std::string &key)
919 {
920 if (!IsString(jsonObj, key)) {
921 LOGE("User string key not exist!");
922 return "";
923 }
924 return jsonObj[key].get<std::string>();
925 }
926
GetJsonInt(const nlohmann::json &jsonObj, const std::string &key)927 int32_t HiChainConnector::GetJsonInt(const nlohmann::json &jsonObj, const std::string &key)
928 {
929 if (!IsInt32(jsonObj, key)) {
930 LOGE("User string key not exist!");
931 return ERR_DM_FAILED;
932 }
933 return jsonObj[key].get<int32_t>();
934 }
935
GetGroupIdExt(const std::string &userId, const int32_t groupType, std::string &groupId, std::string &groupOwner)936 int32_t HiChainConnector::GetGroupIdExt(const std::string &userId, const int32_t groupType,
937 std::string &groupId, std::string &groupOwner)
938 {
939 nlohmann::json jsonObjGroup;
940 jsonObjGroup[FIELD_GROUP_TYPE] = groupType;
941 std::string queryParams = jsonObjGroup.dump();
942 std::vector<GroupInfo> groupList;
943
944 if (!GetGroupInfo(queryParams.c_str(), groupList)) {
945 LOGE("failed to get device join groups");
946 return ERR_DM_FAILED;
947 }
948 for (auto &groupinfo : groupList) {
949 LOGI("groupinfo.groupId:%{public}s", GetAnonyString(groupinfo.groupId).c_str());
950 if (groupinfo.userId == userId) {
951 groupId = groupinfo.groupId;
952 groupOwner = groupinfo.groupOwner;
953 return DM_OK;
954 }
955 }
956 return ERR_DM_FAILED;
957 }
958
ParseRemoteCredentialExt(const std::string &credentialInfo, std::string ¶ms, std::string &groupOwner)959 int32_t HiChainConnector::ParseRemoteCredentialExt(const std::string &credentialInfo, std::string ¶ms,
960 std::string &groupOwner)
961 {
962 LOGI("ParseRemoteCredentialExt start.");
963 nlohmann::json jsonObject = nlohmann::json::parse(credentialInfo, nullptr, false);
964 if (jsonObject.is_discarded()) {
965 LOGE("CredentialInfo string not a json type.");
966 return ERR_DM_FAILED;
967 }
968 nlohmann::json jsonObj;
969 int32_t groupType = 0;
970 std::string userId = "";
971 int32_t authType = GetJsonInt(jsonObject, AUTH_TYPE);
972 if (authType == SAME_ACCOUNT) {
973 groupType = IDENTICAL_ACCOUNT_GROUP;
974 userId = GetJsonStr(jsonObject, FIELD_USER_ID);
975 } else {
976 LOGE("Failed to get userId.");
977 return ERR_DM_FAILED;
978 }
979 std::string groupId = "";
980 if (GetGroupIdExt(userId, groupType, groupId, groupOwner) != DM_OK) {
981 LOGE("Failed to get groupid");
982 return ERR_DM_FAILED;
983 }
984 jsonObj[FIELD_GROUP_TYPE] = groupType;
985 jsonObj[FIELD_GROUP_ID] = groupId;
986 jsonObj[FIELD_USER_ID] = userId;
987 jsonObj[FIELD_CREDENTIAL_TYPE] = GetJsonInt(jsonObject, FIELD_CREDENTIAL_TYPE);
988 jsonObj[FIELD_OPERATION_CODE] = GetJsonInt(jsonObject, FIELD_OPERATION_CODE);
989 jsonObj[FIELD_META_NODE_TYPE] = GetJsonStr(jsonObject, FIELD_TYPE);
990 if (!jsonObject.contains(FIELD_DEVICE_LIST)) {
991 LOGE("Credentaildata or authType string key not exist!");
992 return ERR_DM_FAILED;
993 }
994 jsonObj[FIELD_DEVICE_LIST] = jsonObject[FIELD_DEVICE_LIST];
995 params = jsonObj.dump();
996 return DM_OK;
997 }
998
addMultiMembersExt(const std::string &credentialInfo)999 int32_t HiChainConnector::addMultiMembersExt(const std::string &credentialInfo)
1000 {
1001 if (deviceGroupManager_ == nullptr) {
1002 LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
1003 return ERR_DM_INPUT_PARA_INVALID;
1004 }
1005 std::string addParams = "";
1006 std::string groupOwner = "";
1007 if (ParseRemoteCredentialExt(credentialInfo, addParams, groupOwner) != DM_OK) {
1008 LOGE("AddMultiMembers ParseRemoteCredentialExt failed!");
1009 return ERR_DM_FAILED;
1010 }
1011 int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
1012 if (osAccountUserId < 0) {
1013 LOGE("Get current process account user id failed");
1014 return ERR_DM_FAILED;
1015 }
1016 int32_t ret = deviceGroupManager_->addMultiMembersToGroup(osAccountUserId, groupOwner.c_str(), addParams.c_str());
1017 if (ret != DM_OK) {
1018 LOGE("[HICHAIN]fail to add member to hichain group with ret:%{public}d.", ret);
1019 return ret;
1020 }
1021 return DM_OK;
1022 }
1023
deleteMultiMembers(const int32_t groupType, const std::string &userId, const nlohmann::json &jsonDeviceList)1024 int32_t HiChainConnector::deleteMultiMembers(const int32_t groupType, const std::string &userId,
1025 const nlohmann::json &jsonDeviceList)
1026 {
1027 if (deviceGroupManager_ == nullptr) {
1028 LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
1029 return ERR_DM_INPUT_PARA_INVALID;
1030 }
1031
1032 std::string deleteParams;
1033 int32_t osAccountUserId = 0;
1034 if (ParseRemoteCredential(groupType, userId, jsonDeviceList, deleteParams, osAccountUserId) != DM_OK) {
1035 LOGE("deleteMultiMembers ParseRemoteCredential failed!");
1036 return ERR_DM_FAILED;
1037 }
1038
1039 int32_t ret = deviceGroupManager_->delMultiMembersFromGroup(osAccountUserId, DM_PKG_NAME, deleteParams.c_str());
1040 if (ret != DM_OK) {
1041 LOGE("[HICHAIN]fail to delete member from hichain group with ret:%{public}d.", ret);
1042 return ret;
1043 }
1044 return DM_OK;
1045 }
1046
GetTrustedDevices(const std::string &localDeviceUdid)1047 std::vector<std::string> HiChainConnector::GetTrustedDevices(const std::string &localDeviceUdid)
1048 {
1049 LOGI("get localDeviceUdid: %{public}s trusted devices.", GetAnonyString(localDeviceUdid).c_str());
1050 std::vector<GroupInfo> groups;
1051 int32_t ret = GetRelatedGroups(localDeviceUdid, groups);
1052 if (ret != DM_OK) {
1053 LOGE("failed to get groupInfo, ret: %{public}d", ret);
1054 return {};
1055 }
1056
1057 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
1058 if (userId < 0) {
1059 LOGE("get current process account user id failed");
1060 return {};
1061 }
1062 std::vector<std::string> trustedDevices;
1063 for (const auto &group : groups) {
1064 char *devicesJson = nullptr;
1065 uint32_t devNum = 0;
1066 ret = deviceGroupManager_->getTrustedDevices(userId, DM_PKG_NAME, group.groupId.c_str(),
1067 &devicesJson, &devNum);
1068 if (ret != 0 || devicesJson == nullptr) {
1069 LOGE("[HICHAIN]failed to get trusted devicesJson, ret: %{public}d", ret);
1070 return {};
1071 }
1072 GetTrustedDevicesUdid(devicesJson, trustedDevices);
1073 deviceGroupManager_->destroyInfo(&devicesJson);
1074 }
1075 return trustedDevices;
1076 }
1077
GetTrustedDevicesUdid(const char* jsonStr, std::vector<std::string> &udidList)1078 int32_t HiChainConnector::GetTrustedDevicesUdid(const char* jsonStr, std::vector<std::string> &udidList)
1079 {
1080 nlohmann::json jsonObject = nlohmann::json::parse(jsonStr, nullptr, false);
1081 if (jsonObject.is_discarded()) {
1082 LOGE("credentialInfo string not a json type.");
1083 return ERR_DM_FAILED;
1084 }
1085 for (nlohmann::json::iterator it1 = jsonObject.begin(); it1 != jsonObject.end(); it1++) {
1086 if (!IsString((*it1), FIELD_AUTH_ID)) {
1087 continue;
1088 }
1089 std::string udid = (*it1)[FIELD_AUTH_ID];
1090 udidList.push_back(udid);
1091 }
1092 return DM_OK;
1093 }
1094
DeleteAllGroup(int32_t userId)1095 void HiChainConnector::DeleteAllGroup(int32_t userId)
1096 {
1097 LOGI("HiChainConnector::DeleteAllGroup");
1098 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
1099 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
1100 std::string localUdid = static_cast<std::string>(localDeviceId);
1101 std::vector<GroupInfo> groupList;
1102 GetRelatedGroups(localUdid, groupList);
1103 for (auto &iter : groupList) {
1104 if (DeleteGroup(iter.groupId) != DM_OK) {
1105 LOGE("Delete groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1106 }
1107 }
1108 std::vector<GroupInfo> groupListExt;
1109 GetRelatedGroupsExt(localUdid, groupListExt);
1110 for (auto &iter : groupListExt) {
1111 if (DeleteGroupExt(iter.groupId) != DM_OK) {
1112 LOGE("DeleteGroupExt groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1113 }
1114 }
1115 }
1116
GetRelatedGroupsCommon(const std::string &deviceId, const char* pkgName, std::vector<GroupInfo> &groupList)1117 int32_t HiChainConnector::GetRelatedGroupsCommon(const std::string &deviceId, const char* pkgName,
1118 std::vector<GroupInfo> &groupList)
1119 {
1120 LOGI("HiChainConnector::GetRelatedGroupsCommon Start to get local related groups.");
1121 uint32_t groupNum = 0;
1122 char *returnGroups = nullptr;
1123 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
1124 if (userId < 0) {
1125 LOGE("get current process account user id failed");
1126 return ERR_DM_FAILED;
1127 }
1128 int32_t ret =
1129 deviceGroupManager_->getRelatedGroups(userId, pkgName, deviceId.c_str(), &returnGroups, &groupNum);
1130 if (ret != 0) {
1131 LOGE("[HICHAIN] fail to get related groups with ret:%{public}d.", ret);
1132 return ERR_DM_FAILED;
1133 }
1134 if (returnGroups == nullptr) {
1135 LOGE("[HICHAIN] return related goups point is nullptr");
1136 return ERR_DM_FAILED;
1137 }
1138 if (groupNum == 0) {
1139 LOGE("[HICHAIN]return related goups number is zero.");
1140 return ERR_DM_FAILED;
1141 }
1142 std::string relatedGroups = std::string(returnGroups);
1143 nlohmann::json jsonObject = nlohmann::json::parse(relatedGroups, nullptr, false);
1144 if (jsonObject.is_discarded()) {
1145 LOGE("returnGroups parse error");
1146 return ERR_DM_FAILED;
1147 }
1148 if (!jsonObject.is_array()) {
1149 LOGE("jsonObject is not an array.");
1150 return ERR_DM_FAILED;
1151 }
1152 std::vector<GroupInfo> groupInfos = jsonObject.get<std::vector<GroupInfo>>();
1153 if (groupInfos.empty()) {
1154 LOGE("HiChainConnector::GetRelatedGroups group failed, groupInfos is empty.");
1155 return ERR_DM_FAILED;
1156 }
1157 groupList = groupInfos;
1158 return DM_OK;
1159 }
1160
DeleteAllGroupByUdid(const std::string &udid)1161 void HiChainConnector::DeleteAllGroupByUdid(const std::string &udid)
1162 {
1163 LOGI("HiChainConnector::DeleteAllGroupByUdid %{public}s.", GetAnonyString(udid).c_str());
1164 std::vector<GroupInfo> groupList;
1165 GetRelatedGroups(udid, groupList);
1166 for (auto &iter : groupList) {
1167 if (DeleteGroup(iter.groupId) != DM_OK) {
1168 LOGE("Delete groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1169 }
1170 }
1171 std::vector<GroupInfo> groupListExt;
1172 GetRelatedGroupsExt(udid, groupListExt);
1173 for (auto &iter : groupListExt) {
1174 if (DeleteGroupExt(iter.groupId) != DM_OK) {
1175 LOGE("DeleteGroupExt groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1176 }
1177 }
1178 }
1179
DeleteP2PGroup(int32_t switchUserId)1180 void HiChainConnector::DeleteP2PGroup(int32_t switchUserId)
1181 {
1182 LOGI("switchuserId: %{public}d", switchUserId);
1183 nlohmann::json jsonObj;
1184 jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
1185 std::string queryParams = jsonObj.dump();
1186 std::vector<GroupInfo> groupList;
1187
1188 if (!GetGroupInfo(switchUserId, queryParams, groupList)) {
1189 LOGE("failed to get the switch user id groups");
1190 return;
1191 }
1192 for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
1193 if (DeleteGroup(switchUserId, iter->groupId) != DM_OK) {
1194 LOGE("failed to delete the old user id group %{public}s", GetAnonyString(iter->groupId).c_str());
1195 }
1196 }
1197
1198 int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
1199 LOGI("userId: %{public}d", userId);
1200 if (!GetGroupInfo(userId, queryParams, groupList)) {
1201 LOGE("failed to get the user id groups");
1202 return;
1203 }
1204 for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
1205 if (DeleteGroup(userId, iter->groupId) != DM_OK) {
1206 LOGE("failed to delete the user id group %{public}s", GetAnonyString(iter->groupId).c_str());
1207 }
1208 }
1209 }
1210
DeleteGroupByACL(std::vector<std::pair<int32_t, std::string>> &delACLInfoVec, std::vector<int32_t> &userIdVec)1211 int32_t HiChainConnector::DeleteGroupByACL(std::vector<std::pair<int32_t, std::string>> &delACLInfoVec,
1212 std::vector<int32_t> &userIdVec)
1213 {
1214 if (delACLInfoVec.size() == 0) {
1215 LOGI("delACLInfoVec is empty");
1216 return DM_OK;
1217 }
1218 if (userIdVec.size() == 0) {
1219 LOGI("userIdVec is empty");
1220 return DM_OK;
1221 }
1222 nlohmann::json jsonObj;
1223 jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
1224 std::string queryParams = jsonObj.dump();
1225 for (int32_t userId : userIdVec) {
1226 std::vector<GroupInfo> groupList;
1227 if (!GetGroupInfo(userId, queryParams, groupList)) {
1228 continue;
1229 }
1230 for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
1231 if (!IsNeedDelete(iter->groupName, userId, delACLInfoVec)) {
1232 continue;
1233 }
1234 if (DeleteGroup(userId, iter->groupId) != DM_OK) {
1235 LOGE("failed to delete group %{public}s", GetAnonyString(iter->groupId).c_str());
1236 }
1237 }
1238 }
1239 return DM_OK;
1240 }
1241
IsNeedDelete(std::string &groupName, int32_t userId, std::vector<std::pair<int32_t, std::string>> &delACLInfoVec)1242 bool HiChainConnector::IsNeedDelete(std::string &groupName, int32_t userId,
1243 std::vector<std::pair<int32_t, std::string>> &delACLInfoVec)
1244 {
1245 if (delACLInfoVec.size() == 0 || groupName.empty()) {
1246 LOGI("delACLInfoVec or groupName is empty");
1247 return false;
1248 }
1249 for (auto item : delACLInfoVec) {
1250 uint32_t interceptLength = item.second.size() / DEVICE_ID_HALF;
1251 std::string interceptUdid = item.second.substr(0, interceptLength);
1252 if (groupName.find(interceptUdid) != std::string::npos && userId == item.first) {
1253 return true;
1254 }
1255 }
1256 return false;
1257 }
1258 } // namespace DistributedHardware
1259 } // namespace OHOS