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