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