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 ¶ms, 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