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