1 /*
2 * Copyright (C) 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 "compatible_bind_sub_session.h"
17
18 #include "callback_manager.h"
19 #include "channel_manager.h"
20 #include "compatible_bind_sub_session_common.h"
21 #include "compatible_bind_sub_session_util.h"
22 #include "das_module_defines.h"
23 #include "dev_auth_module_manager.h"
24 #include "group_operation_common.h"
25 #include "hc_dev_info.h"
26 #include "hc_log.h"
27 #include "hc_time.h"
28 #include "hc_types.h"
29 #include "hitrace_adapter.h"
30 #include "performance_dumper.h"
31 #include "hisysevent_adapter.h"
32
CheckInvitePeer(const CJson * jsonParams)33 static int32_t CheckInvitePeer(const CJson *jsonParams)
34 {
35 const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
36 if (groupId == NULL) {
37 LOGE("Failed to get groupId from jsonParams!");
38 return HC_ERR_JSON_GET;
39 }
40 const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
41 if (appId == NULL) {
42 LOGE("Failed to get appId from jsonParams!");
43 return HC_ERR_JSON_GET;
44 }
45 int32_t osAccountId;
46 if (GetIntFromJson(jsonParams, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
47 LOGE("Failed to get osAccountId from jsonParams!");
48 return HC_ERR_JSON_GET;
49 }
50
51 uint32_t groupType = PEER_TO_PEER_GROUP;
52 int32_t result;
53 if (((result = CheckGroupExist(osAccountId, groupId)) != HC_SUCCESS) ||
54 ((result = GetGroupTypeFromDb(osAccountId, groupId, &groupType)) != HC_SUCCESS) ||
55 ((result = AssertGroupTypeMatch(groupType, PEER_TO_PEER_GROUP)) != HC_SUCCESS) ||
56 ((result = CheckPermForGroup(osAccountId, MEMBER_INVITE, appId, groupId)) != HC_SUCCESS) ||
57 ((result = CheckDeviceNumLimit(osAccountId, groupId, NULL)) != HC_SUCCESS)) {
58 return result;
59 }
60 return HC_SUCCESS;
61 }
62
CheckJoinPeer(const CJson * jsonParams)63 static int32_t CheckJoinPeer(const CJson *jsonParams)
64 {
65 int32_t groupType = PEER_TO_PEER_GROUP;
66 if (GetIntFromJson(jsonParams, FIELD_GROUP_TYPE, &groupType) != HC_SUCCESS) {
67 LOGE("Failed to get groupType from jsonParams!");
68 return HC_ERR_JSON_GET;
69 }
70 return AssertGroupTypeMatch(groupType, PEER_TO_PEER_GROUP);
71 }
72
CheckClientStatus(int operationCode,const CJson * jsonParams)73 static int32_t CheckClientStatus(int operationCode, const CJson *jsonParams)
74 {
75 switch (operationCode) {
76 case MEMBER_INVITE:
77 return CheckInvitePeer(jsonParams);
78 case MEMBER_JOIN:
79 return CheckJoinPeer(jsonParams);
80 default:
81 LOGE("Invalid operation!");
82 return HC_ERR_CASE;
83 }
84 }
85
GetDuplicateAppId(const CJson * params,char ** returnAppId)86 static int32_t GetDuplicateAppId(const CJson *params, char **returnAppId)
87 {
88 const char *appId = GetStringFromJson(params, FIELD_APP_ID);
89 if (appId == NULL) {
90 LOGE("Failed to get appId from json!");
91 return HC_ERR_JSON_GET;
92 }
93 uint32_t appIdLen = HcStrlen(appId);
94 *returnAppId = (char *)HcMalloc(appIdLen + 1, 0);
95 if (*returnAppId == NULL) {
96 LOGE("Failed to allocate return appId memory!");
97 return HC_ERR_ALLOC_MEMORY;
98 }
99 if (memcpy_s(*returnAppId, appIdLen + 1, appId, appIdLen) != EOK) {
100 LOGE("Failed to copy appId!");
101 HcFree(*returnAppId);
102 *returnAppId = NULL;
103 return HC_ERR_MEMORY_COPY;
104 }
105 return HC_SUCCESS;
106 }
107
CreateBaseBindSubSession(int32_t sessionType,int32_t opCode,const CJson * params,const DeviceAuthCallback * callback,CompatibleBaseSubSession ** session)108 static int32_t CreateBaseBindSubSession(int32_t sessionType, int32_t opCode, const CJson *params,
109 const DeviceAuthCallback *callback, CompatibleBaseSubSession **session)
110 {
111 int64_t reqId = DEFAULT_REQUEST_ID;
112 if (GetInt64FromJson(params, FIELD_REQUEST_ID, &reqId) != HC_SUCCESS) {
113 LOGE("Failed to get requestId from params!");
114 return HC_ERR_JSON_GET;
115 }
116
117 int32_t osAccountId = 0;
118 if (GetIntFromJson(params, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
119 LOGE("Failed to get osAccountId from params!");
120 return HC_ERR_JSON_GET;
121 }
122
123 CompatibleBindSubSession *subSession = (CompatibleBindSubSession *)HcMalloc(sizeof(CompatibleBindSubSession), 0);
124 if (subSession == NULL) {
125 LOGE("Failed to allocate session memory!");
126 return HC_ERR_ALLOC_MEMORY;
127 }
128
129 int32_t result = GetDuplicateAppId(params, &(subSession->base.appId));
130 if (result != HC_SUCCESS) {
131 LOGE("Failed to get appId!");
132 HcFree(subSession);
133 return result;
134 }
135 subSession->base.type = sessionType;
136 subSession->base.callback = callback;
137 subSession->base.curTaskId = 0;
138 subSession->base.status = STATUS_INITIAL;
139 subSession->params = NULL;
140 subSession->osAccountId = osAccountId;
141 subSession->opCode = opCode;
142 subSession->moduleType = DAS_MODULE;
143 subSession->reqId = reqId;
144 subSession->channelType = NO_CHANNEL;
145 subSession->channelId = DEFAULT_CHANNEL_ID;
146 *session = (CompatibleBaseSubSession *)subSession;
147 return HC_SUCCESS;
148 }
149
GenerateKeyPairIfNeeded(int32_t osAccountId,int isClient,int32_t opCode,CJson * jsonParams)150 static int32_t GenerateKeyPairIfNeeded(int32_t osAccountId, int isClient, int32_t opCode, CJson *jsonParams)
151 {
152 if (!IsCreateGroupNeeded(isClient, opCode)) {
153 LOGI("no need to generate local keypair.");
154 return HC_SUCCESS;
155 }
156 const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
157 if (groupId == NULL) {
158 LOGE("Failed to get groupId from jsonParams!");
159 return HC_ERR_JSON_GET;
160 }
161 DEV_AUTH_START_TRACE(TRACE_TAG_CREATE_KEY_PAIR);
162 int32_t result = ProcessKeyPair(osAccountId, CREATE_KEY_PAIR, jsonParams, groupId);
163 DEV_AUTH_FINISH_TRACE();
164 if (result != HC_SUCCESS) {
165 LOGE("Failed to create keypair!");
166 }
167 return result;
168 }
169
CheckServerStatusIfNotInvite(int32_t osAccountId,int operationCode,const CJson * jsonParams)170 static int32_t CheckServerStatusIfNotInvite(int32_t osAccountId, int operationCode, const CJson *jsonParams)
171 {
172 if (operationCode == MEMBER_INVITE) {
173 return HC_SUCCESS;
174 }
175 const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
176 if (groupId == NULL) {
177 LOGE("Failed to get groupId from jsonParams!");
178 return HC_ERR_JSON_GET;
179 }
180 const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
181 if (appId == NULL) {
182 LOGE("Failed to get appId from jsonParams!");
183 return HC_ERR_JSON_GET;
184 }
185 const char *peerUdid = GetStringFromJson(jsonParams, FIELD_CONN_DEVICE_ID);
186 if (peerUdid == NULL) {
187 LOGE("Failed to get peerUdid from jsonParams!");
188 return HC_ERR_JSON_GET;
189 }
190 int32_t result = CheckGroupExist(osAccountId, groupId);
191 if (result != HC_SUCCESS) {
192 return result;
193 }
194 if (operationCode == MEMBER_JOIN) {
195 /* The client sends a join request, which is equivalent to the server performing an invitation operation. */
196 result = CheckPermForGroup(osAccountId, MEMBER_INVITE, appId, groupId);
197 if (result != HC_SUCCESS) {
198 return result;
199 }
200 result = CheckDeviceNumLimit(osAccountId, groupId, peerUdid);
201 }
202 return result;
203 }
204
CheckAcceptRequest(const CJson * context)205 static int32_t CheckAcceptRequest(const CJson *context)
206 {
207 uint32_t confirmation = REQUEST_REJECTED;
208 (void)GetUnsignedIntFromJson(context, FIELD_CONFIRMATION, &confirmation);
209 if (confirmation != REQUEST_ACCEPTED) {
210 LOGE("The service rejects this request!");
211 return HC_ERR_REQ_REJECTED;
212 }
213 LOGI("The service accepts this request!");
214 return HC_SUCCESS;
215 }
216
GenerateServerBindParams(CompatibleBindSubSession * session,CJson * jsonParams)217 static int32_t GenerateServerBindParams(CompatibleBindSubSession *session, CJson *jsonParams)
218 {
219 int32_t res = CheckAcceptRequest(jsonParams);
220 if (res != HC_SUCCESS) {
221 return res;
222 }
223 res = CheckServerStatusIfNotInvite(session->osAccountId, session->opCode, jsonParams);
224 if (res != HC_SUCCESS) {
225 return res;
226 }
227 res = GenerateBaseBindParams(session->osAccountId, SERVER, jsonParams, session);
228 if (res != HC_SUCCESS) {
229 return res;
230 }
231 return GenerateKeyPairIfNeeded(session->osAccountId, SERVER, session->opCode, jsonParams);
232 }
233
CheckPeerStatus(const CJson * params,bool * isNeedInform)234 static int32_t CheckPeerStatus(const CJson *params, bool *isNeedInform)
235 {
236 int32_t errorCode = HC_SUCCESS;
237 if (GetIntFromJson(params, FIELD_GROUP_ERROR_MSG, &errorCode) == HC_SUCCESS) {
238 LOGE("An error occurs in the peer device! [ErrorCode]: %d", errorCode);
239 *isNeedInform = false;
240 return errorCode;
241 }
242 return HC_SUCCESS;
243 }
244
TryAddPeerUserTypeToParams(const CJson * jsonParams,CompatibleBindSubSession * session)245 static int32_t TryAddPeerUserTypeToParams(const CJson *jsonParams, CompatibleBindSubSession *session)
246 {
247 int32_t peerUserType = DEVICE_TYPE_ACCESSORY;
248 int32_t res = GetIntFromJson(jsonParams, FIELD_PEER_USER_TYPE, &peerUserType);
249 if (res == HC_SUCCESS && AddIntToJson(session->params, FIELD_PEER_USER_TYPE, peerUserType) != HC_SUCCESS) {
250 LOGE("Failed to add peerUserType to params!");
251 return HC_ERR_JSON_ADD;
252 }
253 return HC_SUCCESS;
254 }
255
InteractWithPeer(const CompatibleBindSubSession * session,CJson * sendData)256 static int32_t InteractWithPeer(const CompatibleBindSubSession *session, CJson *sendData)
257 {
258 int32_t res = AddInfoToBindData(false, session, sendData);
259 if (res != HC_SUCCESS) {
260 LOGE("Failed to generate sendData!");
261 return res;
262 }
263 return TransmitBindSessionData(session, sendData);
264 }
265
SendBindDataToPeer(CompatibleBindSubSession * session,CJson * out)266 static int32_t SendBindDataToPeer(CompatibleBindSubSession *session, CJson *out)
267 {
268 CJson *sendData = DetachItemFromJson(out, FIELD_SEND_TO_PEER);
269 if (sendData == NULL) {
270 LOGE("Failed to get sendToPeer from out!");
271 return HC_ERR_JSON_GET;
272 }
273 int32_t result = InteractWithPeer(session, sendData);
274 FreeJson(sendData);
275 return result;
276 }
277
ReportV1BindCallEvent(const CompatibleBindSubSession * session)278 static void ReportV1BindCallEvent(const CompatibleBindSubSession *session)
279 {
280 #ifdef DEV_AUTH_HIVIEW_ENABLE
281 DevAuthCallEvent eventData;
282 eventData.appId = session->base.appId;
283 eventData.funcName = ADD_MEMBER_EVENT;
284 eventData.osAccountId = session->osAccountId;
285 eventData.callResult = DEFAULT_CALL_RESULT;
286 eventData.processCode = PROCESS_BIND_V1;
287 eventData.credType = DEFAULT_CRED_TYPE;
288 eventData.groupType = PEER_TO_PEER_GROUP;
289 eventData.executionTime = GET_TOTAL_CONSUME_TIME_BY_REQ_ID(session->reqId);
290 eventData.extInfo = DEFAULT_EXT_INFO;
291 DEV_AUTH_REPORT_CALL_EVENT(eventData);
292 return;
293 #endif
294 (void)session;
295 return;
296 }
297
InformSelfBindSuccess(const char * peerAuthId,const char * peerUdid,const char * groupId,const CompatibleBindSubSession * session,CJson * out)298 static int32_t InformSelfBindSuccess(const char *peerAuthId, const char *peerUdid, const char *groupId,
299 const CompatibleBindSubSession *session, CJson *out)
300 {
301 uint8_t sessionKey[DEFAULT_RETURN_KEY_LENGTH] = { 0 };
302 if (GetByteFromJson(out, FIELD_SESSION_KEY, sessionKey, DEFAULT_RETURN_KEY_LENGTH) == HC_SUCCESS) {
303 UPDATE_PERFORM_DATA_BY_INPUT_INDEX(session->reqId, ON_SESSION_KEY_RETURN_TIME, HcGetCurTimeInMillis());
304 ProcessSessionKeyCallback(session->reqId, sessionKey, DEFAULT_RETURN_KEY_LENGTH, session->base.callback);
305 (void)memset_s(sessionKey, DEFAULT_RETURN_KEY_LENGTH, 0, DEFAULT_RETURN_KEY_LENGTH);
306 ClearSensitiveStringInJson(out, FIELD_SESSION_KEY);
307 }
308
309 char *jsonDataStr = NULL;
310 int32_t result = GenerateBindSuccessData(peerAuthId, peerUdid, groupId, &jsonDataStr);
311 if (result != HC_SUCCESS) {
312 LOGE("Failed to generate the data to be sent to the service!");
313 return result;
314 }
315 UPDATE_PERFORM_DATA_BY_INPUT_INDEX(session->reqId, ON_FINISH_TIME, HcGetCurTimeInMillis());
316 ProcessFinishCallback(session->reqId, session->opCode, jsonDataStr, session->base.callback);
317 FreeJsonString(jsonDataStr);
318 ReportV1BindCallEvent(session);
319 return HC_SUCCESS;
320 }
321
SetGroupId(const CJson * params,TrustedGroupEntry * groupParams)322 static int32_t SetGroupId(const CJson *params, TrustedGroupEntry *groupParams)
323 {
324 const char *groupId = GetStringFromJson(params, FIELD_GROUP_ID);
325 if (groupId == NULL) {
326 LOGE("Failed to get groupId from params!");
327 return HC_ERR_JSON_GET;
328 }
329 if (!StringSetPointer(&groupParams->id, groupId)) {
330 LOGE("Failed to copy groupId!");
331 return HC_ERR_MEMORY_COPY;
332 }
333 return HC_SUCCESS;
334 }
335
SetGroupName(const CJson * params,TrustedGroupEntry * groupParams)336 static int32_t SetGroupName(const CJson *params, TrustedGroupEntry *groupParams)
337 {
338 const char *groupName = GetStringFromJson(params, FIELD_GROUP_NAME);
339 if (groupName == NULL) {
340 LOGE("Failed to get groupName from params!");
341 return HC_ERR_JSON_GET;
342 }
343 if (!StringSetPointer(&groupParams->name, groupName)) {
344 LOGE("Failed to copy groupName!");
345 return HC_ERR_MEMORY_COPY;
346 }
347 return HC_SUCCESS;
348 }
349
SetGroupOwner(const char * ownerAppId,TrustedGroupEntry * groupParams)350 static int32_t SetGroupOwner(const char *ownerAppId, TrustedGroupEntry *groupParams)
351 {
352 HcString ownerName = CreateString();
353 if (!StringSetPointer(&ownerName, ownerAppId)) {
354 LOGE("Failed to copy groupOwner!");
355 DeleteString(&ownerName);
356 return HC_ERR_MEMORY_COPY;
357 }
358 if (groupParams->managers.pushBackT(&groupParams->managers, ownerName) == NULL) {
359 LOGE("Failed to push owner to vec!");
360 DeleteString(&ownerName);
361 return HC_ERR_MEMORY_COPY;
362 }
363 return HC_SUCCESS;
364 }
365
SetGroupType(TrustedGroupEntry * groupParams)366 static int32_t SetGroupType(TrustedGroupEntry *groupParams)
367 {
368 groupParams->type = PEER_TO_PEER_GROUP;
369 return HC_SUCCESS;
370 }
371
SetGroupVisibility(const CJson * params,TrustedGroupEntry * groupParams)372 static int32_t SetGroupVisibility(const CJson *params, TrustedGroupEntry *groupParams)
373 {
374 int32_t groupVisibility = GROUP_VISIBILITY_PUBLIC;
375 (void)GetIntFromJson(params, FIELD_GROUP_VISIBILITY, &groupVisibility);
376 groupParams->visibility = groupVisibility;
377 return HC_SUCCESS;
378 }
379
SetGroupExpireTime(const CJson * params,TrustedGroupEntry * groupParams)380 static int32_t SetGroupExpireTime(const CJson *params, TrustedGroupEntry *groupParams)
381 {
382 int32_t expireTime = DEFAULT_EXPIRE_TIME;
383 (void)GetIntFromJson(params, FIELD_EXPIRE_TIME, &expireTime);
384 groupParams->expireTime = expireTime;
385 return HC_SUCCESS;
386 }
387
GenerateGroupParams(const CompatibleBindSubSession * session,TrustedGroupEntry * groupParams)388 static int32_t GenerateGroupParams(const CompatibleBindSubSession *session, TrustedGroupEntry *groupParams)
389 {
390 int32_t result;
391 if (((result = SetGroupId(session->params, groupParams)) != HC_SUCCESS) ||
392 ((result = SetGroupName(session->params, groupParams)) != HC_SUCCESS) ||
393 ((result = SetGroupOwner(session->base.appId, groupParams)) != HC_SUCCESS) ||
394 ((result = SetGroupType(groupParams)) != HC_SUCCESS) ||
395 ((result = SetGroupVisibility(session->params, groupParams)) != HC_SUCCESS) ||
396 ((result = SetGroupExpireTime(session->params, groupParams)) != HC_SUCCESS)) {
397 return result;
398 }
399 return HC_SUCCESS;
400 }
401
AddGroupToDatabase(const CompatibleBindSubSession * session)402 static int32_t AddGroupToDatabase(const CompatibleBindSubSession *session)
403 {
404 TrustedGroupEntry *groupParams = CreateGroupEntry();
405 if (groupParams == NULL) {
406 LOGE("Failed to allocate groupParams memory!");
407 return HC_ERR_ALLOC_MEMORY;
408 }
409 int32_t result = GenerateGroupParams(session, groupParams);
410 if (result != HC_SUCCESS) {
411 LOGE("Failed to generate groupParams!");
412 DestroyGroupEntry(groupParams);
413 return result;
414 }
415 result = AddGroup(session->osAccountId, groupParams);
416 DestroyGroupEntry(groupParams);
417 if (result != HC_SUCCESS) {
418 LOGE("Failed to add the group to the database!");
419 return result;
420 }
421 return HC_SUCCESS;
422 }
423
GenerateDevAuthParams(const char * authId,const char * udid,const char * groupId,int userType,TrustedDeviceEntry * devAuthParams)424 static void GenerateDevAuthParams(const char *authId, const char *udid, const char *groupId,
425 int userType, TrustedDeviceEntry *devAuthParams)
426 {
427 devAuthParams->devType = userType;
428 devAuthParams->source = SELF_CREATED;
429 StringSetPointer(&(devAuthParams->authId), authId);
430 StringSetPointer(&(devAuthParams->udid), udid);
431 StringSetPointer(&(devAuthParams->groupId), groupId);
432 StringSetPointer(&(devAuthParams->serviceType), groupId);
433 }
434
AddTrustDevToDatabase(int32_t osAccountId,const char * authId,const char * udid,const char * groupId,int userType)435 static int32_t AddTrustDevToDatabase(int32_t osAccountId, const char *authId, const char *udid, const char *groupId,
436 int userType)
437 {
438 TrustedDeviceEntry *devAuthParams = CreateDeviceEntry();
439 if (devAuthParams == NULL) {
440 LOGE("Failed to allocate devAuthParams memory!");
441 return HC_ERR_ALLOC_MEMORY;
442 }
443 GenerateDevAuthParams(authId, udid, groupId, userType, devAuthParams);
444 int32_t result = AddTrustedDevice(osAccountId, devAuthParams);
445 DestroyDeviceEntry(devAuthParams);
446 if (result != HC_SUCCESS) {
447 LOGE("Failed to add the trusted devices to the database!");
448 return result;
449 }
450 return HC_SUCCESS;
451 }
452
AddGroupAndLocalDevIfNotExist(const char * groupId,const CompatibleBindSubSession * session)453 static int32_t AddGroupAndLocalDevIfNotExist(const char *groupId, const CompatibleBindSubSession *session)
454 {
455 if (IsGroupExistByGroupId(session->osAccountId, groupId)) {
456 return HC_SUCCESS;
457 }
458 char udid[INPUT_UDID_LEN] = { 0 };
459 int32_t result = HcGetUdid((uint8_t *)udid, INPUT_UDID_LEN);
460 if (result != HC_SUCCESS) {
461 LOGE("Failed to get local udid! res: %d", result);
462 return result;
463 }
464 result = AddGroupToDatabase(session);
465 if (result != HC_SUCCESS) {
466 return result;
467 }
468 const char *authId = GetStringFromJson(session->params, FIELD_AUTH_ID);
469 if (authId == NULL) {
470 LOGI("No authId is found. The default value is udid!");
471 authId = udid;
472 }
473 int32_t userType = DEVICE_TYPE_ACCESSORY;
474 (void)GetIntFromJson(session->params, FIELD_USER_TYPE, &userType);
475 return AddTrustDevToDatabase(session->osAccountId, authId, udid, groupId, userType);
476 }
477
AddPeerDevToGroup(const char * peerAuthId,const char * peerUdid,const char * groupId,const CompatibleBindSubSession * session)478 static int32_t AddPeerDevToGroup(const char *peerAuthId, const char *peerUdid,
479 const char *groupId, const CompatibleBindSubSession *session)
480 {
481 int32_t peerUserType = DEVICE_TYPE_ACCESSORY;
482 (void)GetIntFromJson(session->params, FIELD_PEER_USER_TYPE, &peerUserType);
483 int32_t result = AddTrustDevToDatabase(session->osAccountId, peerAuthId, peerUdid, groupId, peerUserType);
484 if (result != HC_SUCCESS) {
485 LOGE("Failed to add the peer trusted device information! RequestId: %" PRId64, session->reqId);
486 return result;
487 }
488 LOGI("The peer trusted device is added to the database successfully! RequestId: %" PRId64, session->reqId);
489 return HC_SUCCESS;
490 }
491
AddGroupAndDev(const char * peerAuthId,const char * peerUdid,const char * groupId,const CompatibleBindSubSession * session)492 static int32_t AddGroupAndDev(const char *peerAuthId, const char *peerUdid, const char *groupId,
493 const CompatibleBindSubSession *session)
494 {
495 int32_t result = AddGroupAndLocalDevIfNotExist(groupId, session);
496 if (result != HC_SUCCESS) {
497 return result;
498 }
499 result = AddPeerDevToGroup(peerAuthId, peerUdid, groupId, session);
500 if (result != HC_SUCCESS) {
501 return result;
502 }
503 return SaveOsAccountDb(session->osAccountId);
504 }
505
HandleBindSuccess(const char * peerAuthId,const char * peerUdid,const char * groupId,const CompatibleBindSubSession * session,CJson * out)506 static int32_t HandleBindSuccess(const char *peerAuthId, const char *peerUdid, const char *groupId,
507 const CompatibleBindSubSession *session, CJson *out)
508 {
509 DEV_AUTH_START_TRACE(TRACE_TAG_ADD_TRUSTED_DEVICE);
510 int32_t result = AddGroupAndDev(peerAuthId, peerUdid, groupId, session);
511 DEV_AUTH_FINISH_TRACE();
512 if (result != HC_SUCCESS) {
513 return result;
514 }
515 return InformSelfBindSuccess(peerAuthId, peerUdid, groupId, session, out);
516 }
517
OnBindFinish(const CompatibleBindSubSession * session,const CJson * jsonParams,CJson * out)518 static int32_t OnBindFinish(const CompatibleBindSubSession *session, const CJson *jsonParams, CJson *out)
519 {
520 const char *peerAuthId = GetStringFromJson(jsonParams, FIELD_PEER_DEVICE_ID);
521 if (peerAuthId == NULL) {
522 peerAuthId = GetStringFromJson(session->params, FIELD_PEER_AUTH_ID);
523 if (peerAuthId == NULL) {
524 LOGE("Failed to get peerAuthId from jsonParams and params!");
525 return HC_ERR_JSON_GET;
526 }
527 }
528 const char *peerUdid = GetStringFromJson(jsonParams, FIELD_CONN_DEVICE_ID);
529 if (peerUdid == NULL) {
530 peerUdid = GetStringFromJson(session->params, FIELD_PEER_UDID);
531 if (peerUdid == NULL) {
532 LOGE("Failed to get peerUdid from jsonParams and params!");
533 return HC_ERR_JSON_GET;
534 }
535 }
536 const char *groupId = GetStringFromJson(session->params, FIELD_GROUP_ID);
537 if (groupId == NULL) {
538 LOGE("Failed to get groupId from session params!");
539 return HC_ERR_JSON_GET;
540 }
541 return HandleBindSuccess(peerAuthId, peerUdid, groupId, session, out);
542 }
543
OnSessionFinish(const CompatibleBindSubSession * session,CJson * jsonParams,CJson * out)544 static int32_t OnSessionFinish(const CompatibleBindSubSession *session, CJson *jsonParams, CJson *out)
545 {
546 int32_t result;
547 CJson *sendData = GetObjFromJson(out, FIELD_SEND_TO_PEER);
548 /* The last packet may need to be sent. */
549 if (sendData != NULL) {
550 result = InteractWithPeer(session, sendData);
551 if (result != HC_SUCCESS) {
552 return result;
553 }
554 }
555 result = OnBindFinish(session, jsonParams, out);
556 if (result != HC_SUCCESS) {
557 LOGE("An error occurred when processing different end operations!");
558 return result;
559 }
560 LOGI("The session completed successfully! [ReqId]: %" PRId64, session->reqId);
561 NotifyBindResult((ChannelType)session->channelType, session->channelId);
562 CloseChannel((ChannelType)session->channelType, session->channelId);
563 return HC_SUCCESS;
564 }
565
InformPeerModuleError(CJson * out,const CompatibleBindSubSession * session)566 static void InformPeerModuleError(CJson *out, const CompatibleBindSubSession *session)
567 {
568 CJson *errorData = GetObjFromJson(out, FIELD_SEND_TO_PEER);
569 if (errorData == NULL) {
570 return;
571 }
572 if (AddStringToJson(errorData, FIELD_APP_ID, session->base.appId) != HC_SUCCESS) {
573 LOGE("Failed to add appId to errorData!");
574 return;
575 }
576 if (AddInt64StringToJson(errorData, FIELD_REQUEST_ID, session->reqId) != HC_SUCCESS) {
577 LOGE("Failed to add requestId to errorData!");
578 return;
579 }
580 if (AddInfoToBindData(false, session, errorData) != HC_SUCCESS) {
581 LOGE("Failed to add info to error data!");
582 return;
583 }
584 if (TransmitBindSessionData(session, errorData) != HC_SUCCESS) {
585 LOGE("An error occurred when notifying the peer service!");
586 } else {
587 LOGI("Succeeded in notifying the peer device that an error occurred at the local end!");
588 }
589 }
590
ProcessModule(const CompatibleBindSubSession * session,const CJson * in,CJson * out,int32_t * status)591 static int32_t ProcessModule(const CompatibleBindSubSession *session, const CJson *in, CJson *out, int32_t *status)
592 {
593 LOGI("Start to process module task! [ModuleType]: %d", session->moduleType);
594 DEV_AUTH_START_TRACE(TRACE_TAG_PROCESS_AUTH_TASK);
595 int32_t res = ProcessTask(session->base.curTaskId, in, out, status, session->moduleType);
596 DEV_AUTH_FINISH_TRACE();
597 if (res != HC_SUCCESS) {
598 LOGE("Failed to process module task! res: %d", res);
599 return res;
600 }
601 LOGI("Process module task successfully!");
602 return HC_SUCCESS;
603 }
604
ProcessBindTaskInner(CompatibleBindSubSession * session,CJson * in,int32_t * status,bool * isNeedInform)605 static int32_t ProcessBindTaskInner(CompatibleBindSubSession *session, CJson *in, int32_t *status, bool *isNeedInform)
606 {
607 int32_t result;
608 if (((result = CheckPeerStatus(in, isNeedInform)) != HC_SUCCESS) ||
609 ((result = TryAddPeerUserTypeToParams(in, session))) != HC_SUCCESS) {
610 return result;
611 }
612
613 CJson *out = CreateJson();
614 if (out == NULL) {
615 LOGE("Failed to allocate out memory!");
616 return HC_ERR_JSON_CREATE;
617 }
618 result = ProcessModule(session, in, out, status);
619 if (result != HC_SUCCESS) {
620 *isNeedInform = false;
621 InformPeerModuleError(out, session);
622 FreeJson(out);
623 return result;
624 }
625 if (*status == IGNORE_MSG) {
626 LOGI("The msg is ignored!");
627 } else if (*status == CONTINUE) {
628 DeleteAllItem(in);
629 result = SendBindDataToPeer(session, out);
630 } else {
631 DEV_AUTH_START_TRACE(TRACE_TAG_ON_SESSION_FINISH);
632 result = OnSessionFinish(session, in, out);
633 DEV_AUTH_FINISH_TRACE();
634 }
635 FreeJson(out);
636 return result;
637 }
638
ProcessBindTask(CompatibleBindSubSession * session,CJson * in,int32_t * status)639 static int32_t ProcessBindTask(CompatibleBindSubSession *session, CJson *in, int32_t *status)
640 {
641 bool isNeedInform = true;
642 int32_t result = ProcessBindTaskInner(session, in, status, &isNeedInform);
643 if (result != HC_SUCCESS) {
644 LOGE("Failed to process bind task!");
645 InformPeerGroupErrorIfNeeded(isNeedInform, result, session);
646 return result;
647 }
648 LOGI("Process bind session successfully! [ReqId]: %" PRId64, session->reqId);
649 if (*status == FINISH) {
650 return FINISH;
651 }
652 return HC_SUCCESS;
653 }
654
GenerateClientModuleParams(CompatibleBindSubSession * session,CJson * moduleParams)655 static int32_t GenerateClientModuleParams(CompatibleBindSubSession *session, CJson *moduleParams)
656 {
657 if (AddIntToJson(moduleParams, FIELD_OPERATION_CODE, OP_BIND) != HC_SUCCESS) {
658 LOGE("Failed to add operationCode to moduleParams!");
659 return HC_ERR_JSON_ADD;
660 }
661 return GenerateBaseModuleParams(true, session, moduleParams);
662 }
663
GetClientModuleReturnData(CompatibleBindSubSession * session,CJson * out,int32_t * status)664 static int32_t GetClientModuleReturnData(CompatibleBindSubSession *session, CJson *out, int32_t *status)
665 {
666 CJson *moduleParams = CreateJson();
667 if (moduleParams == NULL) {
668 LOGE("Failed to allocate moduleParams memory!");
669 return HC_ERR_JSON_CREATE;
670 }
671
672 int32_t result = GenerateClientModuleParams(session, moduleParams);
673 if (result != HC_SUCCESS) {
674 LOGE("Failed to generate all params sent to the module!");
675 FreeJson(moduleParams);
676 return result;
677 }
678
679 result = CreateAndProcessBindTask(session, moduleParams, out, status);
680 FreeJson(moduleParams);
681 return result;
682 }
683
CreateAndProcessClientBindTask(CompatibleBindSubSession * session,CJson ** sendData,int32_t * status)684 static int32_t CreateAndProcessClientBindTask(CompatibleBindSubSession *session, CJson **sendData, int32_t *status)
685 {
686 CJson *out = CreateJson();
687 if (out == NULL) {
688 LOGE("Failed to allocate out memory!");
689 return HC_ERR_JSON_CREATE;
690 }
691 int32_t result = GetClientModuleReturnData(session, out, status);
692 if (result != HC_SUCCESS) {
693 FreeJson(out);
694 return result;
695 }
696
697 *sendData = DetachItemFromJson(out, FIELD_SEND_TO_PEER);
698 FreeJson(out);
699 if (*sendData == NULL) {
700 LOGE("Failed to get sendToPeer from out!");
701 return HC_ERR_JSON_GET;
702 }
703
704 result = AddInfoToBindData(false, session, *sendData);
705 if (result != HC_SUCCESS) {
706 LOGE("Failed to add information to sendData!");
707 FreeJson(*sendData);
708 *sendData = NULL;
709 }
710 return result;
711 }
712
AddConfirmationToParams(CJson * moduleParams)713 static int32_t AddConfirmationToParams(CJson *moduleParams)
714 {
715 if (AddIntToJson(moduleParams, FIELD_CONFIRMATION, REQUEST_ACCEPTED) != HC_SUCCESS) {
716 LOGE("Failed to add confirmation to moduleParams!");
717 return HC_ERR_JSON_ADD;
718 }
719 return HC_SUCCESS;
720 }
721
AddRecvModuleDataToParams(CJson * jsonParams,CJson * moduleParams)722 static int32_t AddRecvModuleDataToParams(CJson *jsonParams, CJson *moduleParams)
723 {
724 int32_t message = ERR_MESSAGE;
725 if (GetIntFromJson(jsonParams, FIELD_MESSAGE, &message) != HC_SUCCESS) {
726 LOGE("Failed to get message from in!");
727 return HC_ERR_JSON_GET;
728 }
729 int32_t authForm = AUTH_FORM_INVALID_TYPE;
730 (void)GetIntFromJson(jsonParams, FIELD_AUTH_FORM, &authForm);
731 CJson *payload = GetObjFromJson(jsonParams, FIELD_PAYLOAD);
732 if (payload == NULL) {
733 LOGE("Failed to get payload from in!");
734 return HC_ERR_JSON_GET;
735 }
736 if (AddIntToJson(moduleParams, FIELD_MESSAGE, message) != HC_SUCCESS) {
737 LOGE("Failed to add message to moduleParams!");
738 return HC_ERR_JSON_ADD;
739 }
740 if (AddIntToJson(moduleParams, FIELD_AUTH_FORM, authForm) != HC_SUCCESS) {
741 LOGE("Failed to add authForm to moduleParams!");
742 return HC_ERR_JSON_ADD;
743 }
744 if (AddObjToJson(moduleParams, FIELD_PAYLOAD, payload) != HC_SUCCESS) {
745 LOGE("Failed to add payload to moduleParams!");
746 return HC_ERR_JSON_ADD;
747 }
748 return HC_SUCCESS;
749 }
750
GenerateServerModuleParams(CompatibleBindSubSession * session,CJson * jsonParams,CJson * moduleParams)751 static int32_t GenerateServerModuleParams(CompatibleBindSubSession *session, CJson *jsonParams, CJson *moduleParams)
752 {
753 int32_t result;
754 if (((result = GenerateBaseModuleParams(false, session, moduleParams)) != HC_SUCCESS) ||
755 ((result = AddConfirmationToParams(moduleParams)) != HC_SUCCESS) ||
756 ((result = AddRecvModuleDataToParams(jsonParams, moduleParams)) != HC_SUCCESS)) {
757 return result;
758 }
759 return HC_SUCCESS;
760 }
761
GetServerModuleReturnData(CompatibleBindSubSession * session,CJson * jsonParams,CJson * out,bool * isNeedInform,int32_t * status)762 static int32_t GetServerModuleReturnData(CompatibleBindSubSession *session, CJson *jsonParams, CJson *out,
763 bool *isNeedInform, int32_t *status)
764 {
765 CJson *moduleParams = CreateJson();
766 if (moduleParams == NULL) {
767 LOGE("Failed to allocate moduleParams memory!");
768 return HC_ERR_JSON_CREATE;
769 }
770
771 int32_t result = GenerateServerModuleParams(session, jsonParams, moduleParams);
772 if (result != HC_SUCCESS) {
773 LOGE("Failed to generate all params sent to the module!");
774 FreeJson(moduleParams);
775 return result;
776 }
777 /* Release the memory in advance to reduce the memory usage. */
778 DeleteAllItem(jsonParams);
779
780 result = CreateAndProcessBindTask(session, moduleParams, out, status);
781 FreeJson(moduleParams);
782 if (result != HC_SUCCESS) {
783 *isNeedInform = false;
784 InformPeerModuleError(out, session);
785 }
786 return result;
787 }
788
PrepareServerData(CompatibleBindSubSession * session,CJson * jsonParams,CJson ** sendData,bool * isNeedInform,int32_t * status)789 static int32_t PrepareServerData(CompatibleBindSubSession *session, CJson *jsonParams, CJson **sendData,
790 bool *isNeedInform, int32_t *status)
791 {
792 CJson *out = CreateJson();
793 if (out == NULL) {
794 LOGE("Failed to allocate out memory!");
795 return HC_ERR_JSON_CREATE;
796 }
797
798 int32_t result = GetServerModuleReturnData(session, jsonParams, out, isNeedInform, status);
799 if (result != HC_SUCCESS) {
800 FreeJson(out);
801 return result;
802 }
803
804 *sendData = DetachItemFromJson(out, FIELD_SEND_TO_PEER);
805 FreeJson(out);
806 if (*sendData == NULL) {
807 LOGE("Failed to get sendToPeer from out!");
808 return HC_ERR_JSON_GET;
809 }
810
811 result = AddInfoToBindData((session->opCode == MEMBER_JOIN), session, *sendData);
812 if (result != HC_SUCCESS) {
813 LOGE("Failed to add information to sendData!");
814 FreeJson(*sendData);
815 *sendData = NULL;
816 }
817 return result;
818 }
819
PrepareAndSendServerData(CompatibleBindSubSession * session,CJson * jsonParams,bool * isNeedInform,int32_t * status)820 static int32_t PrepareAndSendServerData(CompatibleBindSubSession *session, CJson *jsonParams,
821 bool *isNeedInform, int32_t *status)
822 {
823 CJson *sendData = NULL;
824 int32_t result = PrepareServerData(session, jsonParams, &sendData, isNeedInform, status);
825 if (result != HC_SUCCESS) {
826 return result;
827 }
828
829 result = TransmitBindSessionData(session, sendData);
830 FreeJson(sendData);
831 return result;
832 }
833
InitChannel(const CJson * params,CompatibleBindSubSession * session)834 static int32_t InitChannel(const CJson *params, CompatibleBindSubSession *session)
835 {
836 if (GetByteFromJson(params, FIELD_CHANNEL_ID, (uint8_t *)&session->channelId, sizeof(int64_t)) != HC_SUCCESS) {
837 LOGE("Failed to get channelId!");
838 return HC_ERR_JSON_GET;
839 }
840 if (GetIntFromJson(params, FIELD_CHANNEL_TYPE, &session->channelType) != HC_SUCCESS) {
841 LOGE("Failed to get channel type!");
842 return HC_ERR_JSON_GET;
843 }
844 return HC_SUCCESS;
845 }
846
CreateClientBindSubSession(CJson * jsonParams,const DeviceAuthCallback * callback,CompatibleBaseSubSession ** session)847 int32_t CreateClientBindSubSession(CJson *jsonParams, const DeviceAuthCallback *callback,
848 CompatibleBaseSubSession **session)
849 {
850 int64_t requestId = DEFAULT_REQUEST_ID;
851 if (GetInt64FromJson(jsonParams, FIELD_REQUEST_ID, &requestId) != HC_SUCCESS) {
852 LOGE("Failed to get requestId from params!");
853 return HC_ERR_JSON_GET;
854 }
855
856 int32_t opCode = MEMBER_INVITE;
857 if (GetIntFromJson(jsonParams, FIELD_OPERATION_CODE, &opCode) != HC_SUCCESS) {
858 LOGE("Failed to get opCode from params!");
859 return HC_ERR_JSON_GET;
860 }
861
862 int32_t result = CheckClientStatus(opCode, jsonParams);
863 if (result != HC_SUCCESS) {
864 LOGE("Failed to check client status!");
865 return result;
866 }
867
868 result = CreateBaseBindSubSession(TYPE_CLIENT_BIND_SUB_SESSION, opCode, jsonParams, callback, session);
869 if (result != HC_SUCCESS) {
870 return result;
871 }
872
873 CompatibleBindSubSession *subSession = (CompatibleBindSubSession *)(*session);
874 result = GenerateKeyPairIfNeeded(subSession->osAccountId, CLIENT, opCode, jsonParams);
875 if (result != HC_SUCCESS) {
876 DestroyCompatibleBindSubSession(*session);
877 *session = NULL;
878 return result;
879 }
880 result = InitChannel(jsonParams, subSession);
881 if (result != HC_SUCCESS) {
882 DestroyCompatibleBindSubSession(*session);
883 *session = NULL;
884 return result;
885 }
886 result = GenerateBaseBindParams(subSession->osAccountId, CLIENT, jsonParams, subSession);
887 if (result != HC_SUCCESS) {
888 DestroyCompatibleBindSubSession(*session);
889 *session = NULL;
890 }
891 return result;
892 }
893
CreateServerBindSubSession(CJson * jsonParams,const DeviceAuthCallback * callback,CompatibleBaseSubSession ** session)894 int32_t CreateServerBindSubSession(CJson *jsonParams, const DeviceAuthCallback *callback,
895 CompatibleBaseSubSession **session)
896 {
897 int64_t reqId = DEFAULT_REQUEST_ID;
898 if (GetInt64FromJson(jsonParams, FIELD_REQUEST_ID, &reqId) != HC_SUCCESS) {
899 LOGE("Failed to get requestId from params!");
900 return HC_ERR_JSON_GET;
901 }
902 int32_t opCode = MEMBER_INVITE;
903 if (GetIntFromJson(jsonParams, FIELD_GROUP_OP, &opCode) != HC_SUCCESS) {
904 LOGE("Failed to get operation code from params!");
905 return HC_ERR_JSON_GET;
906 }
907 int32_t result = CreateBaseBindSubSession(TYPE_SERVER_BIND_SUB_SESSION, opCode, jsonParams, callback, session);
908 if (result != HC_SUCCESS) {
909 InformPeerProcessError(reqId, jsonParams, callback, result);
910 return result;
911 }
912 CompatibleBindSubSession *subSession = (CompatibleBindSubSession *)(*session);
913 result = InitChannel(jsonParams, subSession);
914 if (result != HC_SUCCESS) {
915 InformPeerGroupErrorIfNeeded(true, result, subSession);
916 DestroyCompatibleBindSubSession(*session);
917 *session = NULL;
918 return result;
919 }
920 result = GenerateServerBindParams(subSession, jsonParams);
921 if (result != HC_SUCCESS) {
922 InformPeerGroupErrorIfNeeded(true, result, subSession);
923 DestroyCompatibleBindSubSession(*session);
924 *session = NULL;
925 }
926 return result;
927 }
928
ProcessClientBindSubSession(CompatibleBaseSubSession * session,CJson * in,CJson ** out,int32_t * status)929 int32_t ProcessClientBindSubSession(CompatibleBaseSubSession *session, CJson *in, CJson **out, int32_t *status)
930 {
931 CompatibleBindSubSession *subSession = (CompatibleBindSubSession *)session;
932 if (session->status == STATUS_PROCESSING) {
933 return ProcessBindTask(subSession, in, status);
934 } else {
935 session->status = STATUS_PROCESSING;
936 return CreateAndProcessClientBindTask(subSession, out, status);
937 }
938 }
939
ProcessServerBindSubSession(CompatibleBaseSubSession * session,CJson * in,int32_t * status)940 int32_t ProcessServerBindSubSession(CompatibleBaseSubSession *session, CJson *in, int32_t *status)
941 {
942 CompatibleBindSubSession *subSession = (CompatibleBindSubSession *)session;
943 if (session->status == STATUS_PROCESSING) {
944 return ProcessBindTask(subSession, in, status);
945 } else {
946 session->status = STATUS_PROCESSING;
947 bool isNeedInform = true;
948 int32_t result = PrepareAndSendServerData(subSession, in, &isNeedInform, status);
949 if (result != HC_SUCCESS) {
950 InformPeerGroupErrorIfNeeded(isNeedInform, result, subSession);
951 }
952 return result;
953 }
954 }
955
DestroyCompatibleBindSubSession(CompatibleBaseSubSession * session)956 void DestroyCompatibleBindSubSession(CompatibleBaseSubSession *session)
957 {
958 if (session == NULL) {
959 return;
960 }
961 CompatibleBindSubSession *realSession = (CompatibleBindSubSession *)session;
962 DestroyTask(realSession->base.curTaskId, realSession->moduleType);
963 HcFree(realSession->base.appId);
964 realSession->base.appId = NULL;
965 FreeJson(realSession->params);
966 realSession->params = NULL;
967 HcFree(realSession);
968 }