• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hichain_connector_callback.h"
30 #include "multiple_user_connector.h"
31 #include "nlohmann/json.hpp"
32 #include "parameter.h"
33 #include "unistd.h"
34 
35 namespace OHOS {
36 namespace DistributedHardware {
37 const int32_t PIN_CODE_NETWORK = 0;
38 const int32_t CREDENTIAL_NETWORK = 1;
39 const int32_t DELAY_TIME_MS = 10000; // 10ms
40 const int32_t FIELD_EXPIRE_TIME_VALUE = 7;
41 
42 constexpr const char* DEVICE_ID = "DEVICE_ID";
43 constexpr const char* FIELD_CREDENTIAL = "credential";
44 
from_json(const nlohmann::json & jsonObject,GroupInfo & groupInfo)45 void from_json(const nlohmann::json &jsonObject, GroupInfo &groupInfo)
46 {
47     if (jsonObject.find(FIELD_GROUP_NAME) != jsonObject.end()) {
48         groupInfo.groupName = jsonObject.at(FIELD_GROUP_NAME).get<std::string>();
49     }
50 
51     if (jsonObject.find(FIELD_GROUP_ID) != jsonObject.end()) {
52         groupInfo.groupId = jsonObject.at(FIELD_GROUP_ID).get<std::string>();
53     }
54 
55     if (jsonObject.find(FIELD_GROUP_OWNER) != jsonObject.end()) {
56         groupInfo.groupOwner = jsonObject.at(FIELD_GROUP_OWNER).get<std::string>();
57     }
58 
59     if (jsonObject.find(FIELD_GROUP_TYPE) != jsonObject.end()) {
60         groupInfo.groupType = jsonObject.at(FIELD_GROUP_TYPE).get<int32_t>();
61     }
62 
63     if (jsonObject.find(FIELD_GROUP_VISIBILITY) != jsonObject.end()) {
64         groupInfo.groupVisibility = jsonObject.at(FIELD_GROUP_VISIBILITY).get<int32_t>();
65     }
66 
67     if (jsonObject.find(FIELD_USER_ID) != jsonObject.end()) {
68         groupInfo.userId = jsonObject.at(FIELD_USER_ID).get<std::string>();
69     }
70 }
71 
72 std::shared_ptr<IHiChainConnectorCallback> HiChainConnector::hiChainConnectorCallback_ = nullptr;
73 std::shared_ptr<IDmGroupResCallback> HiChainConnector::hiChainResCallback_ = nullptr;
74 int32_t HiChainConnector::networkStyle_ = PIN_CODE_NETWORK;
75 bool g_createGroupFlag = false;
76 bool g_deleteGroupFlag = false;
77 bool g_groupIsRedundance = false;
78 
HiChainConnector()79 HiChainConnector::HiChainConnector()
80 {
81     LOGI("HiChainConnector::constructor");
82     deviceAuthCallback_ = {.onTransmit = nullptr,
83                            .onSessionKeyReturned = nullptr,
84                            .onFinish = HiChainConnector::onFinish,
85                            .onError = HiChainConnector::onError,
86                            .onRequest = HiChainConnector::onRequest};
87     InitDeviceAuthService();
88     deviceGroupManager_ = GetGmInstance();
89     if (deviceGroupManager_ == nullptr) {
90         LOGI("HiChainConnector::constructor, failed to init group manager!");
91         return;
92     }
93     deviceGroupManager_->regCallback(DM_PKG_NAME, &deviceAuthCallback_);
94     LOGI("HiChainConnector::constructor success.");
95 }
96 
~HiChainConnector()97 HiChainConnector::~HiChainConnector()
98 {
99     LOGI("HiChainConnector::destructor.");
100 }
101 
RegisterHiChainCallback(std::shared_ptr<IHiChainConnectorCallback> callback)102 int32_t HiChainConnector::RegisterHiChainCallback(std::shared_ptr<IHiChainConnectorCallback> callback)
103 {
104     hiChainConnectorCallback_ = callback;
105     return DM_OK;
106 }
107 
UnRegisterHiChainCallback()108 int32_t HiChainConnector::UnRegisterHiChainCallback()
109 {
110     hiChainConnectorCallback_ = nullptr;
111     return DM_OK;
112 }
113 
CreateGroup(int64_t requestId,const std::string & groupName)114 int32_t HiChainConnector::CreateGroup(int64_t requestId, const std::string &groupName)
115 {
116     if (deviceGroupManager_ == nullptr) {
117         LOGE("HiChainConnector::CreateGroup group manager is null, requestId %lld.", requestId);
118         return ERR_DM_INPUT_PARA_INVALID;
119     }
120     networkStyle_ = PIN_CODE_NETWORK;
121     GroupInfo groupInfo;
122     if (IsGroupCreated(groupName, groupInfo)) {
123         DeleteGroup(groupInfo.groupId);
124     }
125     LOGI("HiChainConnector::CreateGroup requestId %lld", requestId);
126     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
127     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
128     std::string sLocalDeviceId = localDeviceId;
129     nlohmann::json jsonObj;
130     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
131     jsonObj[FIELD_DEVICE_ID] = sLocalDeviceId;
132     jsonObj[FIELD_GROUP_NAME] = groupName;
133     jsonObj[FIELD_USER_TYPE] = 0;
134     jsonObj[FIELD_GROUP_VISIBILITY] = GROUP_VISIBILITY_PUBLIC;
135     jsonObj[FIELD_EXPIRE_TIME] = FIELD_EXPIRE_TIME_VALUE;
136     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
137     if (userId < 0) {
138         LOGE("get current process account user id failed");
139         return ERR_DM_FAILED;
140     }
141 
142     int32_t ret = deviceGroupManager_->createGroup(userId, requestId, DM_PKG_NAME, jsonObj.dump().c_str());
143     if (ret != 0) {
144         LOGE("Failed to start CreateGroup task, ret: %d, requestId %lld.", ret, requestId);
145         return ERR_DM_CREATE_GROUP_FAILED;
146     }
147     return DM_OK;
148 }
149 
IsGroupCreated(std::string groupName,GroupInfo & groupInfo)150 bool HiChainConnector::IsGroupCreated(std::string groupName, GroupInfo &groupInfo)
151 {
152     nlohmann::json jsonObj;
153     jsonObj[FIELD_GROUP_NAME] = groupName.c_str();
154     std::string queryParams = jsonObj.dump();
155     std::vector<GroupInfo> groupList;
156     if (GetGroupInfo(queryParams, groupList)) {
157         groupInfo = groupList[0];
158         return true;
159     }
160     return false;
161 }
162 
IsRedundanceGroup(const std::string & userId,int32_t authType,std::vector<GroupInfo> & groupList)163 bool HiChainConnector::IsRedundanceGroup(const std::string &userId, int32_t authType, std::vector<GroupInfo> &groupList)
164 {
165     nlohmann::json jsonObj;
166     jsonObj[FIELD_GROUP_TYPE] = authType;
167     std::string queryParams = jsonObj.dump();
168 
169     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
170     if (osAccountUserId < 0) {
171         LOGE("get current process account user id failed");
172         return ERR_DM_FAILED;
173     }
174     if (!GetGroupInfo(osAccountUserId, queryParams, groupList)) {
175         return false;
176     }
177     for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
178         if (iter->userId != userId) {
179             return true;
180         }
181     }
182     return false;
183 }
184 
GetGroupInfo(const std::string & queryParams,std::vector<GroupInfo> & groupList)185 bool HiChainConnector::GetGroupInfo(const std::string &queryParams, std::vector<GroupInfo> &groupList)
186 {
187     char *groupVec = nullptr;
188     uint32_t num = 0;
189     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
190     if (userId < 0) {
191         LOGE("get current process account user id failed");
192         return false;
193     }
194     int32_t ret = deviceGroupManager_->getGroupInfo(userId, DM_PKG_NAME, queryParams.c_str(), &groupVec, &num);
195     if (ret != 0) {
196         LOGE("HiChainConnector::GetGroupInfo failed, ret: %d.", ret);
197         return false;
198     }
199     if (groupVec == nullptr) {
200         LOGE("HiChainConnector::GetGroupInfo failed, returnGroups is nullptr");
201         return false;
202     }
203     if (num == 0) {
204         LOGE("HiChainConnector::GetGroupInfo group failed, groupNum is 0.");
205         return false;
206     }
207     LOGI("HiChainConnector::GetGroupInfo group(%s), groupNum(%u)", groupVec, num);
208     std::string relatedGroups = std::string(groupVec);
209     deviceGroupManager_->destroyInfo(&groupVec);
210     nlohmann::json jsonObject = nlohmann::json::parse(relatedGroups);
211     if (jsonObject.is_discarded()) {
212         LOGE("returnGroups parse error");
213         return false;
214     }
215     if (!jsonObject.is_array()) {
216         LOGE("json string is not array.");
217         return false;
218     }
219     std::vector<GroupInfo> groupInfos = jsonObject.get<std::vector<GroupInfo>>();
220     if (groupInfos.size() == 0) {
221         LOGE("HiChainConnector::GetGroupInfo group failed, groupInfos is empty.");
222         return false;
223     }
224     groupList = groupInfos;
225     return true;
226 }
227 
GetGroupInfo(const int32_t userId,const std::string & queryParams,std::vector<GroupInfo> & groupList)228 int32_t HiChainConnector::GetGroupInfo(const int32_t userId, const std::string &queryParams,
229     std::vector<GroupInfo> &groupList)
230 {
231     char *groupVec = nullptr;
232     uint32_t num = 0;
233     int32_t ret = deviceGroupManager_->getGroupInfo(userId, DM_PKG_NAME, queryParams.c_str(), &groupVec, &num);
234     if (ret != 0) {
235         LOGE("HiChainConnector::GetGroupInfo failed, ret: %d.", ret);
236         return false;
237     }
238     if (groupVec == nullptr) {
239         LOGE("HiChainConnector::GetGroupInfo failed, returnGroups is nullptr.");
240         return false;
241     }
242     if (num == 0) {
243         LOGE("HiChainConnector::GetGroupInfo group failed, groupNum is 0.");
244         return false;
245     }
246     LOGI("HiChainConnector::GetGroupInfo group(%s), groupNum(%ud)", groupVec, num);
247     std::string relatedGroups = std::string(groupVec);
248     deviceGroupManager_->destroyInfo(&groupVec);
249     nlohmann::json jsonObject = nlohmann::json::parse(relatedGroups);
250     if (jsonObject.is_discarded()) {
251         LOGE("returnGroups parse error");
252         return false;
253     }
254     if (!jsonObject.is_array()) {
255         LOGE("json string is not array.");
256         return false;
257     }
258     std::vector<GroupInfo> groupInfos = jsonObject.get<std::vector<GroupInfo>>();
259     if (groupInfos.size() == 0) {
260         LOGE("HiChainConnector::GetGroupInfo group failed, groupInfos is empty.");
261         return false;
262     }
263     groupList = groupInfos;
264     return true;
265 }
266 
AddMember(const std::string & deviceId,const std::string & connectInfo)267 int32_t HiChainConnector::AddMember(const std::string &deviceId, const std::string &connectInfo)
268 {
269     LOGI("HiChainConnector::AddMember");
270     if (deviceGroupManager_ == nullptr) {
271         LOGI("HiChainConnector::AddMember group manager is null.");
272         return ERR_DM_POINT_NULL;
273     }
274     nlohmann::json jsonObject = nlohmann::json::parse(connectInfo, nullptr, false);
275     if (jsonObject.is_discarded()) {
276         LOGE("DecodeRequestAuth jsonStr error");
277         return ERR_DM_FAILED;
278     }
279     if (!IsString(jsonObject, TAG_DEVICE_ID) || !IsInt32(jsonObject, PIN_CODE_KEY) ||
280         !IsString(jsonObject, TAG_GROUP_ID) || !IsInt64(jsonObject, TAG_REQUEST_ID) ||
281         !IsString(jsonObject, TAG_GROUP_NAME)) {
282         LOGE("HiChainConnector::AddMember err json string.");
283         return ERR_DM_FAILED;
284     }
285     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
286     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
287     std::string connectInfomation = GetConnectPara(deviceId, jsonObject[TAG_DEVICE_ID].get<std::string>());
288 
289     int32_t pinCode = jsonObject[PIN_CODE_KEY].get<int32_t>();
290     std::string groupId = jsonObject[TAG_GROUP_ID].get<std::string>();
291     nlohmann::json jsonObj;
292     jsonObj[FIELD_GROUP_ID] = groupId;
293     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
294     jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode).c_str();
295     jsonObj[FIELD_IS_ADMIN] = false;
296     jsonObj[FIELD_DEVICE_ID] = localDeviceId;
297     jsonObj[FIELD_GROUP_NAME] = jsonObject[TAG_GROUP_NAME].get<std::string>();
298     jsonObj[FIELD_CONNECT_PARAMS] = connectInfomation.c_str();
299     std::string tmpStr = jsonObj.dump();
300     int64_t requestId = jsonObject[TAG_REQUEST_ID].get<int64_t>();
301     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
302     if (userId < 0) {
303         LOGE("get current process account user id failed");
304         return ERR_DM_FAILED;
305     }
306     int32_t ret = deviceGroupManager_->addMemberToGroup(userId, requestId, DM_PKG_NAME, tmpStr.c_str());
307     if (ret != 0) {
308         LOGE("HiChainConnector::AddMember failed, ret: %d", ret);
309     }
310     LOGI("HiChainConnector::AddMember completed");
311     return ret;
312 }
313 
onFinish(int64_t requestId,int operationCode,const char * returnData)314 void HiChainConnector::onFinish(int64_t requestId, int operationCode, const char *returnData)
315 {
316     std::string data = "";
317     if (returnData != nullptr) {
318         data = std::string(returnData);
319     }
320     LOGI("HiChainConnector::onFinish reqId:%lld, operation:%d", requestId, operationCode);
321     if (operationCode == GroupOperationCode::MEMBER_JOIN) {
322         LOGI("Add Member To Group success");
323         SysEventWrite(std::string(ADD_HICHAIN_GROUP_SUCCESS), DM_HISYEVENT_BEHAVIOR,
324             std::string(ADD_HICHAIN_GROUP_SUCCESS_MSG));
325         if (hiChainConnectorCallback_ != nullptr) {
326             hiChainConnectorCallback_->OnMemberJoin(requestId, DM_OK);
327         }
328     }
329     if (operationCode == GroupOperationCode::GROUP_CREATE) {
330         LOGI("Create group success");
331         SysEventWrite(std::string(DM_CREATE_GROUP_SUCCESS), DM_HISYEVENT_BEHAVIOR,
332             std::string(DM_CREATE_GROUP_SUCCESS_MSG));
333         if (networkStyle_ == CREDENTIAL_NETWORK) {
334             if (hiChainResCallback_ != nullptr) {
335                 int32_t importAction = 0;
336                 hiChainResCallback_->OnGroupResult(requestId, importAction, data);
337                 g_createGroupFlag = true;
338             }
339         } else {
340             if (hiChainConnectorCallback_ != nullptr) {
341                 hiChainConnectorCallback_->OnMemberJoin(requestId, DM_OK);
342                 hiChainConnectorCallback_->OnGroupCreated(requestId, data);
343             }
344         }
345     }
346     if (operationCode == GroupOperationCode::MEMBER_DELETE) {
347         LOGI("Delete Member from group success");
348     }
349     if (operationCode == GroupOperationCode::GROUP_DISBAND) {
350         if (networkStyle_ == CREDENTIAL_NETWORK && hiChainResCallback_ != nullptr) {
351             if (!g_groupIsRedundance) {
352                 int32_t deleteAction = 1;
353                 hiChainResCallback_->OnGroupResult(requestId, deleteAction, data);
354             }
355             g_deleteGroupFlag = true;
356         }
357         LOGI("Disband group success");
358     }
359 }
360 
onError(int64_t requestId,int operationCode,int errorCode,const char * errorReturn)361 void HiChainConnector::onError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn)
362 {
363     std::string data = "";
364     if (errorReturn != nullptr) {
365         data = std::string(errorReturn);
366     }
367     LOGI("HichainAuthenCallBack::onError reqId:%lld, operation:%d, errorCode:%d.", requestId, operationCode, errorCode);
368     if (operationCode == GroupOperationCode::MEMBER_JOIN) {
369         LOGE("Add Member To Group failed");
370         SysEventWrite(std::string(ADD_HICHAIN_GROUP_FAILED), DM_HISYEVENT_BEHAVIOR,
371             std::string(ADD_HICHAIN_GROUP_FAILED_MSG));
372         if (hiChainConnectorCallback_ != nullptr) {
373             hiChainConnectorCallback_->OnMemberJoin(requestId, ERR_DM_FAILED);
374         }
375     }
376     if (operationCode == GroupOperationCode::GROUP_CREATE) {
377         LOGE("Create group failed");
378         SysEventWrite(std::string(DM_CREATE_GROUP_FAILED), DM_HISYEVENT_BEHAVIOR,
379             std::string(DM_CREATE_GROUP_FAILED_MSG));
380         if (networkStyle_ == CREDENTIAL_NETWORK) {
381             if (hiChainResCallback_ != nullptr) {
382                 int32_t importAction = 0;
383                 hiChainResCallback_->OnGroupResult(requestId, importAction, data);
384                 g_createGroupFlag = true;
385             }
386         } else {
387             if (hiChainConnectorCallback_ != nullptr) {
388                 hiChainConnectorCallback_->OnGroupCreated(requestId, "{}");
389             }
390         }
391     }
392     if (operationCode == GroupOperationCode::MEMBER_DELETE) {
393         LOGE("Delete Member from group failed");
394     }
395     if (operationCode == GroupOperationCode::GROUP_DISBAND) {
396         if (networkStyle_ == CREDENTIAL_NETWORK && hiChainResCallback_ != nullptr) {
397             if (!g_groupIsRedundance) {
398                 int32_t deleteAction = 1;
399                 hiChainResCallback_->OnGroupResult(requestId, deleteAction, data);
400             }
401             g_deleteGroupFlag = true;
402         }
403         LOGE("Disband group failed");
404     }
405 }
406 
onRequest(int64_t requestId,int operationCode,const char * reqParams)407 char *HiChainConnector::onRequest(int64_t requestId, int operationCode, const char *reqParams)
408 {
409     if (operationCode != GroupOperationCode::MEMBER_JOIN) {
410         LOGE("HiChainConnector::onRequest operationCode %d", operationCode);
411         return nullptr;
412     }
413     if (hiChainConnectorCallback_ == nullptr) {
414         LOGE("HiChainConnector::onRequest hiChainConnectorCallback_ is nullptr.");
415         return nullptr;
416     }
417     nlohmann::json jsonObj;
418     int32_t pinCode = hiChainConnectorCallback_->GetPinCode();
419     if (pinCode == ERR_DM_AUTH_NOT_START) {
420         jsonObj[FIELD_CONFIRMATION] = REQUEST_REJECTED;
421     } else {
422         jsonObj[FIELD_CONFIRMATION] = REQUEST_ACCEPTED;
423     }
424     jsonObj[FIELD_PIN_CODE] = std::to_string(pinCode).c_str();
425     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
426     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
427     jsonObj[FIELD_DEVICE_ID] = localDeviceId;
428 
429     std::string jsonStr = jsonObj.dump();
430     char *buffer = strdup(jsonStr.c_str());
431     return buffer;
432 }
433 
GenRequestId()434 int64_t HiChainConnector::GenRequestId()
435 {
436     return GenRandLongLong(MIN_REQUEST_ID, MAX_REQUEST_ID);
437 }
438 
GetConnectPara(std::string deviceId,std::string reqDeviceId)439 std::string HiChainConnector::GetConnectPara(std::string deviceId, std::string reqDeviceId)
440 {
441     LOGI("HiChainConnector::GetConnectPara get addrInfo");
442     if (hiChainConnectorCallback_ == nullptr) {
443         LOGE("HiChainConnector::GetConnectPara hiChainConnectorCallback_ is nullptr.");
444         return "";
445     }
446     std::string connectAddr = hiChainConnectorCallback_->GetConnectAddr(deviceId);
447     nlohmann::json jsonObject = nlohmann::json::parse(connectAddr, nullptr, false);
448     if (jsonObject.is_discarded()) {
449         LOGE("DecodeRequestAuth jsonStr error");
450         return connectAddr;
451     }
452     jsonObject[DEVICE_ID] = reqDeviceId;
453 
454     return jsonObject.dump();
455 }
456 
GetRelatedGroups(const std::string & deviceId,std::vector<GroupInfo> & groupList)457 int32_t HiChainConnector::GetRelatedGroups(const std::string &deviceId, std::vector<GroupInfo> &groupList)
458 {
459     LOGI("HiChainConnector::GetRelatedGroups Start to get local related groups.");
460     uint32_t groupNum = 0;
461     char *returnGroups = nullptr;
462     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
463     if (userId < 0) {
464         LOGE("get current process account user id failed");
465         return ERR_DM_FAILED;
466     }
467     int32_t ret =
468         deviceGroupManager_->getRelatedGroups(userId, DM_PKG_NAME, deviceId.c_str(), &returnGroups, &groupNum);
469     if (ret != 0) {
470         LOGE("HiChainConnector::GetRelatedGroups failed, ret: %d.", ret);
471         return ERR_DM_FAILED;
472     }
473     if (returnGroups == nullptr) {
474         LOGE("HiChainConnector::GetRelatedGroups failed, returnGroups is nullptr");
475         return ERR_DM_FAILED;
476     }
477     if (groupNum == 0) {
478         LOGE("HiChainConnector::GetRelatedGroups group failed, groupNum is 0.");
479         return ERR_DM_FAILED;
480     }
481     std::string relatedGroups = std::string(returnGroups);
482     nlohmann::json jsonObject = nlohmann::json::parse(relatedGroups);
483     if (jsonObject.is_discarded()) {
484         LOGE("returnGroups parse error");
485         return ERR_DM_FAILED;
486     }
487     if (!jsonObject.is_array()) {
488         LOGE("jsonObject is not an array.");
489         return ERR_DM_FAILED;
490     }
491     std::vector<GroupInfo> groupInfos = jsonObject.get<std::vector<GroupInfo>>();
492     if (groupInfos.empty()) {
493         LOGE("HiChainConnector::GetRelatedGroups group failed, groupInfos is empty.");
494         return ERR_DM_FAILED;
495     }
496     groupList = groupInfos;
497     return DM_OK;
498 }
499 
GetSyncGroupList(std::vector<GroupInfo> & groupList,std::vector<std::string> & syncGroupList)500 int32_t HiChainConnector::GetSyncGroupList(std::vector<GroupInfo> &groupList, std::vector<std::string> &syncGroupList)
501 {
502     if (groupList.empty()) {
503         LOGE("groupList is empty.");
504         return ERR_DM_FAILED;
505     }
506     for (auto group : groupList) {
507         if (IsGroupInfoInvalid(group)) {
508             continue;
509         }
510         syncGroupList.push_back(group.groupId);
511     }
512     return DM_OK;
513 }
514 
IsDevicesInGroup(const std::string & hostDevice,const std::string & peerDevice)515 bool HiChainConnector::IsDevicesInGroup(const std::string &hostDevice, const std::string &peerDevice)
516 {
517     LOGI("HiChainConnector::IsDevicesInGroup");
518     std::vector<GroupInfo> hostGroupInfoList;
519     GetRelatedGroups(hostDevice, hostGroupInfoList);
520     std::vector<GroupInfo> peerGroupInfoList;
521     GetRelatedGroups(peerDevice, peerGroupInfoList);
522     for (const auto &hostGroupInfo : hostGroupInfoList) {
523         for (const auto &peerGroupInfo : peerGroupInfoList) {
524             if (hostGroupInfo.groupId == peerGroupInfo.groupId && hostGroupInfo.groupName == peerGroupInfo.groupName) {
525                 LOGE("these are authenticated");
526                 return true;
527             }
528         }
529     }
530     return false;
531 }
532 
IsGroupInfoInvalid(GroupInfo & group)533 bool HiChainConnector::IsGroupInfoInvalid(GroupInfo &group)
534 {
535     if (group.groupType == GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP || group.groupVisibility == GROUP_VISIBILITY_PUBLIC ||
536         group.groupOwner != std::string(DM_PKG_NAME)) {
537         return true;
538     }
539     return false;
540 }
541 
SyncGroups(std::string deviceId,std::vector<std::string> & remoteGroupIdList)542 int32_t HiChainConnector::SyncGroups(std::string deviceId, std::vector<std::string> &remoteGroupIdList)
543 {
544     std::vector<GroupInfo> groupInfoList;
545     GetRelatedGroups(deviceId, groupInfoList);
546     for (auto &groupInfo : groupInfoList) {
547         if (IsGroupInfoInvalid(groupInfo)) {
548             continue;
549         }
550         auto iter = std::find(remoteGroupIdList.begin(), remoteGroupIdList.end(), groupInfo.groupId);
551         if (iter == remoteGroupIdList.end()) {
552             (void)DelMemberFromGroup(groupInfo.groupId, deviceId);
553         }
554     }
555     return DM_OK;
556 }
557 
DelMemberFromGroup(const std::string & groupId,const std::string & deviceId)558 int32_t HiChainConnector::DelMemberFromGroup(const std::string &groupId, const std::string &deviceId)
559 {
560     int64_t requestId = GenRequestId();
561     LOGI("Start to delete member from group, requestId %lld, deviceId %s, groupId %s", requestId,
562          GetAnonyString(deviceId).c_str(), GetAnonyString(groupId).c_str());
563     nlohmann::json jsonObj;
564     jsonObj[FIELD_GROUP_ID] = groupId;
565     jsonObj[FIELD_DELETE_ID] = deviceId;
566     std::string deleteParams = jsonObj.dump();
567     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
568     if (userId < 0) {
569         LOGE("get current process account user id failed");
570         return ERR_DM_FAILED;
571     }
572     int32_t ret = deviceGroupManager_->deleteMemberFromGroup(userId, requestId, DM_PKG_NAME, deleteParams.c_str());
573     if (ret != 0) {
574         LOGE("HiChainConnector::DelMemberFromGroup failed, ret: %d", ret);
575         return ret;
576     }
577     return DM_OK;
578 }
579 
DeleteGroup(std::string & groupId)580 int32_t HiChainConnector::DeleteGroup(std::string &groupId)
581 {
582     int64_t requestId = GenRequestId();
583     nlohmann::json jsonObj;
584     jsonObj[FIELD_GROUP_ID] = groupId;
585     std::string disbandParams = jsonObj.dump();
586     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
587     if (userId < 0) {
588         LOGE("get current process account user id failed");
589         return ERR_DM_FAILED;
590     }
591 
592     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME, disbandParams.c_str());
593     if (ret != 0) {
594         LOGE("HiChainConnector::DeleteGroup failed, ret: %d.", ret);
595         return ERR_DM_FAILED;
596     }
597     return DM_OK;
598 }
599 
DeleteGroup(const int32_t userId,std::string & groupId)600 int32_t HiChainConnector::DeleteGroup(const int32_t userId, std::string &groupId)
601 {
602     int64_t requestId = GenRequestId();
603     nlohmann::json jsonObj;
604     jsonObj[FIELD_GROUP_ID] = groupId;
605     std::string disbandParams = jsonObj.dump();
606     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME, disbandParams.c_str());
607     if (ret != 0) {
608         LOGE("HiChainConnector::DeleteGroup failed, ret: %d.", ret);
609         return ERR_DM_FAILED;
610     }
611     return DM_OK;
612 }
613 
DeleteGroup(int64_t requestId_,const std::string & userId,const int32_t authType)614 int32_t HiChainConnector::DeleteGroup(int64_t requestId_, const std::string &userId, const int32_t authType)
615 {
616     networkStyle_ = CREDENTIAL_NETWORK;
617     nlohmann::json jsonObj;
618     jsonObj[FIELD_GROUP_TYPE] = authType;
619     std::string queryParams = jsonObj.dump();
620     std::vector<GroupInfo> groupList;
621     if (!GetGroupInfo(queryParams, groupList)) {
622         LOGE("failed to get device join groups");
623         return ERR_DM_FAILED;
624     }
625     LOGI("HiChainConnector::DeleteGroup groupList count = %d", groupList.size());
626     bool userIsExist = false;
627     std::string groupId = "";
628     for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
629         if (iter->userId == userId) {
630             userIsExist = true;
631             groupId = iter->groupId;
632             break;
633         }
634     }
635     if (!userIsExist) {
636         LOGE("input userId is exist in groupList!");
637         return ERR_DM_FAILED;
638     }
639     jsonObj[FIELD_GROUP_ID] = groupId;
640     std::string disbandParams = jsonObj.dump();
641     g_deleteGroupFlag = false;
642     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
643     if (osAccountUserId < 0) {
644         LOGE("get current process account user id failed");
645         return ERR_DM_FAILED;
646     }
647     int32_t ret = deviceGroupManager_->deleteGroup(osAccountUserId, requestId_, DM_PKG_NAME,
648         disbandParams.c_str());
649     if (ret != 0) {
650         LOGE("HiChainConnector::DeleteGroup failed, ret: %d.", ret);
651         return ERR_DM_FAILED;
652     }
653     int32_t nTickTimes = 0;
654     while (!g_deleteGroupFlag) {
655         usleep(DELAY_TIME_MS);
656         if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
657             LOGE("failed to delete group because timeout!");
658             return ERR_DM_FAILED;
659         }
660     }
661     return DM_OK;
662 }
663 
DeleteTimeOutGroup(const char * deviceId)664 int32_t HiChainConnector::DeleteTimeOutGroup(const char* deviceId)
665 {
666     LOGI("HiChainConnector::DeleteTimeOutGroup start");
667     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
668     if (userId < 0) {
669         LOGE("get current process account user id failed");
670         return ERR_DM_FAILED;
671     }
672     std::vector<GroupInfo> peerGroupInfoList;
673     GetRelatedGroups(deviceId, peerGroupInfoList);
674     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
675     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
676     for (auto &group : peerGroupInfoList) {
677         if (!(deviceGroupManager_->isDeviceInGroup(userId, DM_PKG_NAME, group.groupId.c_str(), localDeviceId))) {
678             continue;
679         }
680         if (group.groupType == GROUP_TYPE_PEER_TO_PEER_GROUP) {
681             DeleteGroup(group.groupId);
682         }
683     }
684     return DM_OK;
685 }
686 
DeleteRedundanceGroup(std::string & userId)687 void HiChainConnector::DeleteRedundanceGroup(std::string &userId)
688 {
689     int32_t nTickTimes = 0;
690     g_deleteGroupFlag = false;
691     DeleteGroup(userId);
692     while (!g_deleteGroupFlag) {
693         usleep(DELAY_TIME_MS);
694         if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
695             LOGE("failed to delete group because timeout!");
696             return;
697         }
698     }
699 }
700 
DealRedundanceGroup(const std::string & userId,int32_t authType)701 void HiChainConnector::DealRedundanceGroup(const std::string &userId, int32_t authType)
702 {
703     g_groupIsRedundance = false;
704     std::vector<GroupInfo> groupList;
705     if (IsRedundanceGroup(userId, authType, groupList)) {
706         LOGI("HiChainConnector::CreateGroup IsRedundanceGroup");
707         g_groupIsRedundance = true;
708         for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
709             if (iter->userId != userId) {
710                 DeleteRedundanceGroup(iter->userId);
711             }
712         }
713         g_groupIsRedundance = false;
714     }
715 }
716 
CreateGroup(int64_t requestId,int32_t authType,const std::string & userId,nlohmann::json & jsonOutObj)717 int32_t HiChainConnector::CreateGroup(int64_t requestId, int32_t authType, const std::string &userId,
718     nlohmann::json &jsonOutObj)
719 {
720     if (deviceGroupManager_ == nullptr) {
721         LOGE("HiChainConnector::CreateGroup group manager is null, requestId %lld.", requestId);
722         return ERR_DM_INPUT_PARA_INVALID;
723     }
724     DealRedundanceGroup(userId, authType);
725     networkStyle_ = CREDENTIAL_NETWORK;
726     LOGI("HiChainConnector::CreateGroup requestId %lld", requestId);
727     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
728     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
729     std::string sLocalDeviceId = localDeviceId;
730     nlohmann::json jsonObj;
731     jsonObj[FIELD_GROUP_TYPE] = authType;
732     jsonObj[FIELD_USER_ID] = userId;
733     jsonObj[FIELD_CREDENTIAL] = jsonOutObj;
734     jsonObj[FIELD_DEVICE_ID] = sLocalDeviceId;
735     jsonObj[FIELD_USER_TYPE] = 0;
736     jsonObj[FIELD_GROUP_VISIBILITY] = GROUP_VISIBILITY_PUBLIC;
737     jsonObj[FIELD_EXPIRE_TIME] = FIELD_EXPIRE_TIME_VALUE;
738     g_createGroupFlag = false;
739     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
740     if (osAccountUserId < 0) {
741         LOGE("get current process account user id failed");
742         return ERR_DM_FAILED;
743     }
744     LOGI("[DM] createParams:%s", jsonObj.dump().c_str());
745     int32_t ret = deviceGroupManager_->createGroup(osAccountUserId, requestId, DM_PKG_NAME, jsonObj.dump().c_str());
746     if (ret != DM_OK) {
747         LOGE("Failed to start CreateGroup task, ret: %d, requestId %lld.", ret, requestId);
748         return ERR_DM_CREATE_GROUP_FAILED;
749     }
750     int32_t nTickTimes = 0;
751     while (!g_createGroupFlag) {
752         usleep(DELAY_TIME_MS);
753         if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
754             LOGE("failed to create group because timeout!");
755             return ERR_DM_FAILED;
756         }
757     }
758     return DM_OK;
759 }
760 
RegisterHiChainGroupCallback(const std::shared_ptr<IDmGroupResCallback> & callback)761 int32_t HiChainConnector::RegisterHiChainGroupCallback(const std::shared_ptr<IDmGroupResCallback> &callback)
762 {
763     hiChainResCallback_ = callback;
764     return DM_OK;
765 }
766 
UnRegisterHiChainGroupCallback()767 int32_t HiChainConnector::UnRegisterHiChainGroupCallback()
768 {
769     hiChainResCallback_ = nullptr;
770     return DM_OK;
771 }
772 
getRegisterInfo(const std::string & queryParams,std::string & returnJsonStr)773 int32_t HiChainConnector::getRegisterInfo(const std::string &queryParams, std::string &returnJsonStr)
774 {
775     if (deviceGroupManager_ == nullptr) {
776         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
777         return ERR_DM_INPUT_PARA_INVALID;
778     }
779     char *credentialInfo = nullptr;
780     if (deviceGroupManager_->getRegisterInfo(queryParams.c_str(), &credentialInfo) != DM_OK) {
781         LOGE("failed to request hichain registerinfo.");
782         return ERR_DM_FAILED;
783     }
784 
785     returnJsonStr = credentialInfo;
786     deviceGroupManager_->destroyInfo(&credentialInfo);
787     LOGI("request hichain device registerinfo successfully.");
788     return DM_OK;
789 }
790 
GetGroupId(const std::string & userId,const int32_t groupType,std::string & groupId)791 int32_t HiChainConnector::GetGroupId(const std::string &userId, const int32_t groupType, std::string &groupId)
792 {
793     nlohmann::json jsonObjGroup;
794     jsonObjGroup[FIELD_GROUP_TYPE] = groupType;
795     std::string queryParams = jsonObjGroup.dump();
796     std::vector<GroupInfo> groupList;
797 
798     if (!GetGroupInfo(queryParams.c_str(), groupList)) {
799         LOGE("failed to get device join groups");
800         return ERR_DM_FAILED;
801     }
802     for (auto &groupinfo : groupList) {
803         LOGI("groupinfo.groupId:%s", groupinfo.groupId.c_str());
804         if (groupinfo.userId == userId) {
805             groupId = groupinfo.groupId;
806             return DM_OK;
807         }
808     }
809     return ERR_DM_FAILED;
810 }
811 
ParseRemoteCredential(const int32_t groupType,const std::string & userId,const nlohmann::json & jsonDeviceList,std::string & params,int32_t & osAccountUserId)812 int32_t HiChainConnector::ParseRemoteCredential(const int32_t groupType, const std::string &userId,
813     const nlohmann::json &jsonDeviceList, std::string &params, int32_t &osAccountUserId)
814 {
815     if (userId.empty() || !jsonDeviceList.contains(FIELD_DEVICE_LIST)) {
816         LOGE("userId or deviceList is empty");
817         return ERR_DM_INPUT_PARA_INVALID;
818     }
819     std::string groupId;
820     if (GetGroupId(userId, groupType, groupId) != DM_OK) {
821         LOGE("failed to get groupid");
822         return ERR_DM_FAILED;
823     }
824     nlohmann::json jsonObj;
825     jsonObj[FIELD_GROUP_ID] = groupId;
826     jsonObj[FIELD_GROUP_TYPE] = groupType;
827     jsonObj[FIELD_DEVICE_LIST] = jsonDeviceList[FIELD_DEVICE_LIST];
828     params = jsonObj.dump();
829     osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
830     if (osAccountUserId < 0) {
831         LOGE("get current process account user id failed");
832         return ERR_DM_FAILED;
833     }
834     return DM_OK;
835 }
836 
addMultiMembers(const int32_t groupType,const std::string & userId,const nlohmann::json & jsonDeviceList)837 int32_t HiChainConnector::addMultiMembers(const int32_t groupType, const std::string &userId,
838     const nlohmann::json &jsonDeviceList)
839 {
840     if (deviceGroupManager_ == nullptr) {
841         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
842         return ERR_DM_INPUT_PARA_INVALID;
843     }
844     std::string addParams;
845     int32_t osAccountUserId = 0;
846     if (ParseRemoteCredential(groupType, userId, jsonDeviceList, addParams, osAccountUserId) != DM_OK) {
847         LOGE("addMultiMembers ParseRemoteCredential failed!");
848         return ERR_DM_FAILED;
849     }
850 
851     int32_t ret = deviceGroupManager_->addMultiMembersToGroup(osAccountUserId, DM_PKG_NAME, addParams.c_str());
852     if (ret!= DM_OK) {
853         LOGE("HiChainConnector::addMultiMemberstoGroup failure! ret = %d", ret);
854         return ret;
855     }
856     return DM_OK;
857 }
858 
deleteMultiMembers(const int32_t groupType,const std::string & userId,const nlohmann::json & jsonDeviceList)859 int32_t HiChainConnector::deleteMultiMembers(const int32_t groupType, const std::string &userId,
860     const nlohmann::json &jsonDeviceList)
861 {
862     if (deviceGroupManager_ == nullptr) {
863         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
864         return ERR_DM_INPUT_PARA_INVALID;
865     }
866 
867     std::string deleteParams;
868     int32_t osAccountUserId = 0;
869     if (ParseRemoteCredential(groupType, userId, jsonDeviceList, deleteParams, osAccountUserId) != DM_OK) {
870         LOGE("deleteMultiMembers ParseRemoteCredential failed!");
871         return ERR_DM_FAILED;
872     }
873 
874     int32_t ret = deviceGroupManager_->delMultiMembersFromGroup(osAccountUserId, DM_PKG_NAME, deleteParams.c_str());
875     if (ret != DM_OK) {
876         LOGE("HiChainConnector::deleteMultiMembers failure!, ret = %d", ret);
877         return ret;
878     }
879     return DM_OK;
880 }
881 } // namespace DistributedHardware
882 } // namespace OHOS