• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }