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