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 &params, int32_t &osAccountUserId)871 int32_t HiChainConnector::ParseRemoteCredential(const int32_t groupType, const std::string &userId,
872     const nlohmann::json &jsonDeviceList, std::string &params, 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 &params, std::string &groupOwner)959 int32_t HiChainConnector::ParseRemoteCredentialExt(const std::string &credentialInfo, std::string &params,
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