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