• 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 "dev_session_fwk.h"
17 
18 #include <inttypes.h>
19 #include <time.h>
20 #include "alg_loader.h"
21 #include "callback_manager.h"
22 #include "channel_manager.h"
23 #include "identity_common.h"
24 #include "common_defs.h"
25 #include "compatible_sub_session.h"
26 #include "compatible_bind_sub_session_util.h"
27 #include "compatible_auth_sub_session_util.h"
28 #include "group_data_manager.h"
29 #include "dev_session_v2.h"
30 #include "hc_dev_info.h"
31 #include "hc_log.h"
32 #include "hc_time.h"
33 #include "hc_types.h"
34 #include "performance_dumper.h"
35 #include "hisysevent_adapter.h"
36 
StartV1Session(SessionImpl * impl,CJson ** sendMsg)37 static int32_t StartV1Session(SessionImpl *impl, CJson **sendMsg)
38 {
39     bool isBind = true;
40     bool isDeviceLevel = false;
41     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
42     (void)GetBoolFromJson(impl->context, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
43     SubSessionTypeValue subSessionType = isBind ? TYPE_CLIENT_BIND_SUB_SESSION : TYPE_CLIENT_AUTH_SUB_SESSION;
44     int32_t res = CreateCompatibleSubSession(subSessionType, impl->context, &impl->base.callback,
45         &impl->compatibleSubSession);
46     if (res != HC_SUCCESS) {
47         if (isDeviceLevel && res == HC_ERR_NO_CANDIDATE_GROUP) {
48             LOGI("create compatibleSubSession fail. no candidate group");
49         } else {
50             LOGE("create compatibleSubSession fail. [Res]: %" LOG_PUB "d", res);
51         }
52         return res;
53     }
54     int32_t status;
55     res = ProcessCompatibleSubSession(impl->compatibleSubSession, impl->context, sendMsg, &status);
56     if (res != HC_SUCCESS) {
57         LOGE("process compatibleSubSession fail. [Res]: %" LOG_PUB "d", res);
58         DestroyCompatibleSubSession(impl->compatibleSubSession);
59         impl->compatibleSubSession = NULL;
60         return res;
61     }
62     return HC_SUCCESS;
63 }
64 
DestroySession(DevSession * self)65 static void DestroySession(DevSession *self)
66 {
67     if (self == NULL) {
68         LOGD("self is NULL.");
69         return;
70     }
71     SessionImpl *impl = (SessionImpl *)self;
72     HcFree(impl->base.appId);
73     FreeJson(impl->context);
74     ClearFreeUint8Buff(&impl->salt);
75     ClearFreeUint8Buff(&impl->sessionKey);
76     ClearIdentityInfoVec(&impl->credList);
77     DestroyEventList(&impl->eventList);
78     uint32_t index;
79     AuthSubSession **ptr;
80     FOR_EACH_HC_VECTOR(impl->authSubSessionList, index, ptr) {
81         AuthSubSession *authSubSesion = *ptr;
82         authSubSesion->destroy(authSubSesion);
83     }
84     DestroyAuthSubSessionList(&impl->authSubSessionList);
85     if (impl->expandSubSession != NULL) {
86         impl->expandSubSession->destroy(impl->expandSubSession);
87     }
88     if (impl->compatibleSubSession != NULL) {
89         DestroyCompatibleSubSession(impl->compatibleSubSession);
90         impl->compatibleSubSession = NULL;
91     }
92     HcFree(impl);
93 }
94 
DecodeEvent(const CJson * inputEvent)95 static int32_t DecodeEvent(const CJson *inputEvent)
96 {
97     if (inputEvent == NULL) {
98         return SESSION_UNKNOWN_EVENT;
99     }
100     int32_t eventType;
101     if (GetIntFromJson(inputEvent, FIELD_TYPE, &eventType) != HC_SUCCESS) {
102         LOGE("get eventType from inputEvent fail.");
103         return SESSION_UNKNOWN_EVENT;
104     }
105     if (START_EVENT <= eventType && eventType <= SESSION_UNKNOWN_EVENT) {
106         return eventType;
107     }
108     LOGE("unknown event.");
109     return SESSION_UNKNOWN_EVENT;
110 }
111 
PackSendMsg(SessionImpl * impl,CJson * sessionMsg,CJson * sendMsg)112 static int32_t PackSendMsg(SessionImpl *impl, CJson *sessionMsg, CJson *sendMsg)
113 {
114     if (AddInt64StringToJson(sendMsg, FIELD_REQUEST_ID, impl->base.id) != HC_SUCCESS) {
115         LOGE("add requestId to json fail!");
116         return HC_ERR_JSON_ADD;
117     }
118     if (AddStringToJson(sendMsg, FIELD_APP_ID, impl->base.appId) != HC_SUCCESS) {
119         LOGE("add appId to json fail.");
120         return HC_ERR_JSON_ADD;
121     }
122     if (AddObjToJson(sendMsg, FIELD_MSG, sessionMsg) != HC_SUCCESS) {
123         LOGE("add sessionMsg to json fail.");
124         return HC_ERR_JSON_ADD;
125     }
126     return HC_SUCCESS;
127 }
128 
SendJsonMsg(const SessionImpl * impl,const CJson * sendMsg)129 static int32_t SendJsonMsg(const SessionImpl *impl, const CJson *sendMsg)
130 {
131     char *sendMsgStr = PackJsonToString(sendMsg);
132     if (sendMsgStr == NULL) {
133         LOGE("convert sendMsg to sendMsgStr fail.");
134         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
135     }
136     UPDATE_PERFORM_DATA_BY_SELF_INDEX(impl->base.id, HcGetCurTimeInMillis());
137     int32_t res = HcSendMsg(impl->channelType, impl->base.id, impl->channelId, &impl->base.callback, sendMsgStr);
138     FreeJsonString(sendMsgStr);
139     return res;
140 }
141 
SendSessionMsg(SessionImpl * impl,CJson * sessionMsg)142 static int32_t SendSessionMsg(SessionImpl *impl, CJson *sessionMsg)
143 {
144     if (GetItemNum(sessionMsg) == 0) {
145         return HC_SUCCESS;
146     }
147     CJson *sendMsg = CreateJson();
148     if (sendMsg == NULL) {
149         LOGE("allocate sendMsg fail.");
150         return HC_ERR_ALLOC_MEMORY;
151     }
152     int32_t res = PackSendMsg(impl, sessionMsg, sendMsg);
153     if (res != HC_SUCCESS) {
154         LOGE("pack send msg fail.");
155         FreeJson(sendMsg);
156         return res;
157     }
158     res = SendJsonMsg(impl, sendMsg);
159     FreeJson(sendMsg);
160     return res;
161 }
162 
ProcEventList(SessionImpl * impl)163 static int32_t ProcEventList(SessionImpl *impl)
164 {
165     CJson *sessionMsg = CreateJsonArray();
166     if (sessionMsg == NULL) {
167         LOGE("allocate sessionMsg memory fail.");
168         return HC_ERR_ALLOC_MEMORY;
169     }
170     int32_t res = HC_ERR_CASE;
171     while (HC_VECTOR_SIZE(&impl->eventList) > 0) {
172         SessionEvent event;
173         HC_VECTOR_POPELEMENT(&impl->eventList, &event, 0);
174         res = SessionSwitchState(impl, &event, sessionMsg);
175         if (res != HC_SUCCESS) {
176             break;
177         }
178     }
179     if (res != HC_SUCCESS) {
180         (void)SendSessionMsg(impl, sessionMsg);
181         FreeJson(sessionMsg);
182         return res;
183     }
184     res = SendSessionMsg(impl, sessionMsg);
185     FreeJson(sessionMsg);
186     return res;
187 }
188 
AddSessionInfo(SessionImpl * impl,CJson * sendMsg)189 static int32_t AddSessionInfo(SessionImpl *impl, CJson *sendMsg)
190 {
191     if (AddIntToJson(sendMsg, FIELD_OP_CODE, impl->base.opCode) != HC_SUCCESS) {
192         LOGE("add opCode to json fail.");
193         return HC_ERR_JSON_ADD;
194     }
195     return HC_SUCCESS;
196 }
197 
StartV2Session(SessionImpl * impl,CJson * sendMsg)198 static int32_t StartV2Session(SessionImpl *impl, CJson *sendMsg)
199 {
200     CJson *sessionMsg = CreateJsonArray();
201     if (sessionMsg == NULL) {
202         LOGE("allocate sessionMsg fail.");
203         return HC_ERR_ALLOC_MEMORY;
204     }
205     SessionEvent startEvent = { START_EVENT, NULL };
206     int32_t res = SessionSwitchState(impl, &startEvent, sessionMsg);
207     if (res != HC_SUCCESS) {
208         FreeJson(sessionMsg);
209         return res;
210     }
211     res = PackSendMsg(impl, sessionMsg, sendMsg);
212     FreeJson(sessionMsg);
213     if (res != HC_SUCCESS) {
214         LOGE("pack send msg fail.");
215         return res;
216     }
217     return AddSessionInfo(impl, sendMsg);
218 }
219 
IsMetaNode(const CJson * context)220 static bool IsMetaNode(const CJson *context)
221 {
222     return GetStringFromJson(context, FIELD_META_NODE_TYPE) != NULL;
223 }
224 
225 #ifdef DEV_AUTH_HIVIEW_ENABLE
GetBizScene(bool isBind,bool isClient)226 static DevAuthBizScene GetBizScene(bool isBind, bool isClient)
227 {
228     if (isBind) {
229         if (isClient) {
230             return BIZ_SCENE_ADD_MEMBER_CLIENT;
231         } else {
232             return BIZ_SCENE_ADD_MEMBER_SERVER;
233         }
234     } else {
235         if (isClient) {
236             return BIZ_SCENE_AUTH_DEVICE_CLIENT;
237         } else {
238             return BIZ_SCENE_AUTH_DEVICE_SERVER;
239         }
240     }
241 }
242 #endif
243 
ReportBehaviorEvent(const SessionImpl * impl,bool isProcessEnd,bool isBehaviorEnd,int32_t res)244 static void ReportBehaviorEvent(const SessionImpl *impl, bool isProcessEnd, bool isBehaviorEnd, int32_t res)
245 {
246 #ifdef DEV_AUTH_HIVIEW_ENABLE
247     bool isBind = true;
248     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
249     char *funcName = isBind ? ADD_MEMBER_EVENT : AUTH_DEV_EVENT;
250     DevAuthBizScene scene = GetBizScene(isBind, impl->isClient);
251     DevAuthBehaviorEvent eventData = { 0 };
252     DevAuthBizState state = BIZ_STATE_PROCESS;
253     if (isBehaviorEnd) {
254         state = BIZ_STATE_END;
255     }
256     BuildBehaviorEventData(&eventData, funcName, scene, state, BIZ_STAGE_PROCESS);
257     char anonymousLocalUdid[ANONYMOUS_UDID_LEN + 1] = { 0 };
258     char anonymousPeerUdid[ANONYMOUS_UDID_LEN + 1] = { 0 };
259     if (isBind) {
260         eventData.hostPkg = ADD_MEMBER_HOST_PKG_NAME;
261         eventData.toCallPkg = ADD_MEMBER_TO_CALL_PKG_NAME;
262     } else {
263         eventData.hostPkg = AUTH_DEVICE_HOST_PKG_NAME;
264         char selfUdid[INPUT_UDID_LEN] = { 0 };
265         (void)HcGetUdid((uint8_t *)selfUdid, INPUT_UDID_LEN);
266         if (GetAnonymousString(selfUdid, anonymousLocalUdid, ANONYMOUS_UDID_LEN) == HC_SUCCESS) {
267             eventData.localUdid = anonymousLocalUdid;
268         }
269         const char *peerUdid = GetStringFromJson(impl->context, FIELD_PEER_CONN_DEVICE_ID);
270         if (GetAnonymousString(peerUdid, anonymousPeerUdid, ANONYMOUS_UDID_LEN) == HC_SUCCESS) {
271             eventData.peerUdid = anonymousPeerUdid;
272         }
273     }
274     char concurrentId[MAX_REQUEST_ID_LEN] = { 0 };
275     (void)sprintf_s(concurrentId, sizeof(concurrentId), "%" PRId64, impl->base.id);
276     eventData.concurrentId = concurrentId;
277     if (isProcessEnd || isBehaviorEnd) {
278         if (res == HC_SUCCESS) {
279             eventData.stageRes = STAGE_RES_SUCCESS;
280         } else {
281             eventData.stageRes = STAGE_RES_FAILED;
282             eventData.errorCode = res;
283         }
284     }
285     DevAuthReportBehaviorEvent(&eventData);
286 #else
287     (void)impl;
288     (void)isProcessEnd;
289     (void)isBehaviorEnd;
290     (void)res;
291 #endif
292 }
293 
ReportBindAndAuthCallEvent(const SessionImpl * impl,int32_t callResult,bool isV1Session)294 static void ReportBindAndAuthCallEvent(const SessionImpl *impl, int32_t callResult, bool isV1Session)
295 {
296 #ifdef DEV_AUTH_HIVIEW_ENABLE
297     DevAuthCallEvent eventData;
298     eventData.appId = impl->base.appId;
299     (void)GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &eventData.osAccountId);
300     eventData.callResult = callResult;
301     eventData.credType = DEFAULT_CRED_TYPE;
302     bool isBind = true;
303     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
304     if (isBind) {
305         eventData.funcName = ADD_MEMBER_EVENT;
306         eventData.processCode = isV1Session ? PROCESS_BIND_V1 : PROCESS_BIND_V2;
307         eventData.groupType = PEER_TO_PEER_GROUP;
308     } else {
309         eventData.funcName = AUTH_DEV_EVENT;
310         eventData.processCode = isV1Session ? PROCESS_AUTH_V1 : PROCESS_AUTH_V2;
311         eventData.groupType =
312             (impl->base.opCode == AUTH_FORM_ACCOUNT_UNRELATED) ? PEER_TO_PEER_GROUP : IDENTICAL_ACCOUNT_GROUP;
313     }
314     eventData.executionTime = GET_TOTAL_CONSUME_TIME_BY_REQ_ID(impl->base.id);
315     eventData.extInfo = DEFAULT_EXT_INFO;
316     DEV_AUTH_REPORT_CALL_EVENT(eventData);
317     return;
318 #endif
319     (void)impl;
320     (void)callResult;
321     (void)isV1Session;
322     return;
323 }
324 
ReportBindAndAuthFaultEvent(const SessionImpl * impl,int32_t errorCode,bool isV1Session)325 static void ReportBindAndAuthFaultEvent(const SessionImpl *impl, int32_t errorCode, bool isV1Session)
326 {
327 #ifdef DEV_AUTH_HIVIEW_ENABLE
328     DevAuthFaultEvent eventData;
329     eventData.appId = impl->base.appId;
330     eventData.reqId = impl->base.id;
331     eventData.errorCode = errorCode;
332     eventData.faultInfo = DEFAULT_FAULT_INFO;
333     bool isBind = true;
334     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
335     if (isBind) {
336         eventData.funcName = ADD_MEMBER_EVENT;
337         eventData.processCode = isV1Session ? PROCESS_BIND_V1 : PROCESS_BIND_V2;
338     } else {
339         eventData.funcName = AUTH_DEV_EVENT;
340         eventData.processCode = isV1Session ? PROCESS_AUTH_V1 : PROCESS_AUTH_V2;
341     }
342     DEV_AUTH_REPORT_FAULT_EVENT(eventData);
343     return;
344 #endif
345     (void)impl;
346     (void)errorCode;
347     (void)isV1Session;
348     return;
349 }
350 
OnDevSessionError(const SessionImpl * impl,int32_t errorCode,const char * errorReturn,bool isV1Session)351 static void OnDevSessionError(const SessionImpl *impl, int32_t errorCode, const char *errorReturn, bool isV1Session)
352 {
353     ReportBehaviorEvent(impl, false, true, errorCode);
354     ProcessErrorCallback(impl->base.id, impl->base.opCode, errorCode, errorReturn, &impl->base.callback);
355     CloseChannel(impl->channelType, impl->channelId);
356     ReportBindAndAuthFaultEvent(impl, errorCode, isV1Session);
357     ReportBindAndAuthCallEvent(impl, errorCode, isV1Session);
358 }
359 
StartSession(DevSession * self)360 static int32_t StartSession(DevSession *self)
361 {
362     if (self == NULL) {
363         LOGE("self is NULL.");
364         return HC_ERR_INVALID_PARAMS;
365     }
366     SessionImpl *impl = (SessionImpl *)self;
367     ReportBehaviorEvent(impl, false, false, HC_SUCCESS);
368     int32_t res;
369     do {
370         CJson *sendMsg = NULL;
371         /* auth with credentials directly no need to start the v1 session. */
372         bool isDirectAuth = false;
373         bool isDeviceLevel = false;
374         (void)GetBoolFromJson(impl->context, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
375         if (!isDirectAuth && !impl->isCredAuth) {
376             (void)GetBoolFromJson(impl->context, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
377             res = StartV1Session(impl, &sendMsg);
378             if ((res != HC_SUCCESS)
379                 && (res != HC_ERR_NO_CANDIDATE_GROUP || !isDeviceLevel)) {
380                 // if it's device level auth and no group founded,
381                 // we also need try auth with credentails directly.
382                 LOGE("start v1 session event fail.");
383                 break;
384             }
385         }
386         sendMsg = (sendMsg == NULL ? CreateJson() : sendMsg);
387         if (sendMsg == NULL) {
388             LOGE("allocate sendMsg fail.");
389             return HC_ERR_ALLOC_MEMORY;
390         }
391         if (IsSupportSessionV2() && !IsMetaNode(impl->context)) {
392             res = StartV2Session(impl, sendMsg);
393             if (res != HC_SUCCESS) {
394                 LOGE("start v2 session event fail.");
395                 FreeJson(sendMsg);
396                 break;
397             }
398         }
399         res = SendJsonMsg(impl, sendMsg);
400         FreeJson(sendMsg);
401         if (res != HC_SUCCESS) {
402             LOGE("send msg fail.");
403             break;
404         }
405     } while (0);
406     ReportBehaviorEvent(impl, true, false, res);
407     if (res != HC_SUCCESS) {
408         OnDevSessionError(impl, res, NULL, false);
409     }
410     return res;
411 }
412 
ParseAllRecvEvent(SessionImpl * impl,const CJson * receviedMsg)413 static int32_t ParseAllRecvEvent(SessionImpl *impl, const CJson *receviedMsg)
414 {
415     CJson *sessionMsg = GetObjFromJson(receviedMsg, FIELD_MSG);
416     if (sessionMsg == NULL) {
417         LOGE("get sessionMsg from receviedMsg fail.");
418         return HC_ERR_JSON_GET;
419     }
420     int32_t eventNum = GetItemNum(sessionMsg);
421     if (eventNum <= 0) {
422         LOGE("There are no events in the received session message.");
423         return HC_ERR_BAD_MESSAGE;
424     }
425     for (int32_t i = 0; i < eventNum; i++) {
426         CJson *inputEventJson = GetItemFromArray(sessionMsg, i);
427         if (inputEventJson == NULL) {
428             LOGE("get inputEventJson from sessionMsg fail.");
429             return HC_ERR_JSON_GET;
430         }
431         int32_t eventType = DecodeEvent(inputEventJson);
432         CJson *eventData = GetObjFromJson(inputEventJson, FIELD_DATA);
433         if (eventData == NULL) {
434             LOGE("get eventData fail.");
435             return HC_ERR_JSON_GET;
436         }
437         SessionEvent event = { eventType, eventData };
438         if (HC_VECTOR_PUSHBACK(&impl->eventList, &event) == NULL) {
439             LOGE("push event fail.");
440             return HC_ERR_ALLOC_MEMORY;
441         }
442         LOGI("push event success. [Type]: %" LOG_PUB "d", eventType);
443     }
444     return HC_SUCCESS;
445 }
446 
IsV1SessionMsg(const CJson * receviedMsg)447 static bool IsV1SessionMsg(const CJson *receviedMsg)
448 {
449     return (GetObjFromJson(receviedMsg, FIELD_MSG) == NULL);
450 }
451 
AddChannelInfoToParams(SessionImpl * impl,CJson * receviedMsg)452 static int32_t AddChannelInfoToParams(SessionImpl *impl, CJson *receviedMsg)
453 {
454     int32_t channelType;
455     if (GetIntFromJson(impl->context, FIELD_CHANNEL_TYPE, &channelType) != HC_SUCCESS) {
456         LOGE("get channelType from context fail.");
457         return HC_ERR_JSON_GET;
458     }
459     int64_t channelId;
460     if (GetByteFromJson(impl->context, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
461         LOGE("get channelId from context fail.");
462         return HC_ERR_JSON_GET;
463     }
464     if (AddIntToJson(receviedMsg, FIELD_CHANNEL_TYPE, channelType) != HC_SUCCESS) {
465         LOGE("add channelType to params fail.");
466         return HC_ERR_JSON_ADD;
467     }
468     if (AddByteToJson(receviedMsg, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
469         LOGE("add channelId to params fail.");
470         return HC_ERR_JSON_ADD;
471     }
472     return HC_SUCCESS;
473 }
474 
CombindServerBindParams(SessionImpl * impl,CJson * receviedMsg)475 static int32_t CombindServerBindParams(SessionImpl *impl, CJson *receviedMsg)
476 {
477     int32_t osAccountId;
478     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
479         LOGE("get osAccountId from context fail.");
480         return HC_ERR_JSON_GET;
481     }
482     if (AddIntToJson(receviedMsg, FIELD_OS_ACCOUNT_ID, osAccountId) != HC_SUCCESS) {
483         LOGE("add osAccountId to receviedMsg fail.");
484         return HC_ERR_JSON_ADD;
485     }
486     int32_t protocolExpandVal = INVALID_PROTOCOL_EXPAND_VALUE;
487     (void)GetIntFromJson(impl->context, FIELD_PROTOCOL_EXPAND, &protocolExpandVal);
488     if (AddIntToJson(receviedMsg, FIELD_PROTOCOL_EXPAND, protocolExpandVal) != HC_SUCCESS) {
489         LOGE("Failed to add protocol expand val to receviedMsg!");
490         return HC_ERR_JSON_ADD;
491     }
492     return CombineConfirmData(impl->opCode, impl->context, receviedMsg);
493 }
494 
CombindServerAuthParams(SessionImpl * impl,CJson * receviedMsg)495 static int32_t CombindServerAuthParams(SessionImpl *impl, CJson *receviedMsg)
496 {
497     if (AddInt64StringToJson(receviedMsg, FIELD_REQUEST_ID, impl->base.id) != HC_SUCCESS) {
498         LOGE("add requestId to receviedMsg fail.");
499         return HC_ERR_JSON_ADD;
500     }
501     if (AddIntToJson(receviedMsg, FIELD_OPERATION_CODE, AUTHENTICATE) != HC_SUCCESS) {
502         LOGE("add operationCode to receviedMsg fail.");
503         return HC_ERR_JSON_ADD;
504     }
505     return CombineAuthConfirmData(impl->context, receviedMsg);
506 }
507 
AddConfirmationToParams(const CJson * context,CJson * receviedMsg)508 static int32_t AddConfirmationToParams(const CJson *context, CJson *receviedMsg)
509 {
510     uint32_t confirmation = REQUEST_REJECTED;
511     (void)GetUnsignedIntFromJson(context, FIELD_CONFIRMATION, &confirmation);
512     if (AddIntToJson(receviedMsg, FIELD_CONFIRMATION, (int32_t)confirmation) != HC_SUCCESS) {
513         LOGE("add confirmation to receviedMsg fail.");
514         return HC_ERR_JSON_ADD;
515     }
516     return HC_SUCCESS;
517 }
518 
CombineServerParams(SessionImpl * impl,bool isBind,CJson * receviedMsg)519 static int32_t CombineServerParams(SessionImpl *impl, bool isBind, CJson *receviedMsg)
520 {
521     int32_t res = AddChannelInfoToParams(impl, receviedMsg);
522     if (res != HC_SUCCESS) {
523         return res;
524     }
525     res = AddConfirmationToParams(impl->context, receviedMsg);
526     if (res != HC_SUCCESS) {
527         return res;
528     }
529     return isBind ? CombindServerBindParams(impl, receviedMsg) : CombindServerAuthParams(impl, receviedMsg);
530 }
531 
InitServerV1Session(SessionImpl * impl,const CJson * receviedMsg)532 static int32_t InitServerV1Session(SessionImpl *impl, const CJson *receviedMsg)
533 {
534     bool isBind = true;
535     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
536     int32_t res = CombineServerParams(impl, isBind, (CJson *)receviedMsg);
537     if (res != HC_SUCCESS) {
538         return res;
539     }
540     SubSessionTypeValue subSessionType = isBind ? TYPE_SERVER_BIND_SUB_SESSION : TYPE_SERVER_AUTH_SUB_SESSION;
541     res = CreateCompatibleSubSession(subSessionType, (CJson *)receviedMsg, &impl->base.callback,
542         &impl->compatibleSubSession);
543     if (res != HC_SUCCESS) {
544         LOGE("create compatibleSubSession fail. [Res]: %" LOG_PUB "d", res);
545         return res;
546     }
547     return HC_SUCCESS;
548 }
549 
ProcV1SessionMsg(SessionImpl * impl,const CJson * receviedMsg,bool * isFinish)550 static int32_t ProcV1SessionMsg(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)
551 {
552     CJson *out = NULL;
553     int32_t status;
554     int32_t res = ProcessCompatibleSubSession(impl->compatibleSubSession, (CJson *)receviedMsg, &out, &status);
555     if (res != HC_SUCCESS) {
556         DestroyCompatibleSubSession(impl->compatibleSubSession);
557         impl->compatibleSubSession = NULL;
558         if (status == FINISH) {
559             LOGI("process compatibleSubSession finish.");
560             *isFinish = true;
561             return HC_SUCCESS;
562         } else {
563             LOGE("process compatibleSubSession fail. [Res]: %" LOG_PUB "d", res);
564             return res;
565         }
566     }
567     *isFinish = false;
568     return HC_SUCCESS;
569 }
570 
HasNextAuthGroup(const CJson * receviedMsg)571 static inline bool HasNextAuthGroup(const CJson *receviedMsg)
572 {
573     return GetStringFromJson(receviedMsg, FIELD_ALTERNATIVE) != NULL;
574 }
575 
GenerateErrorReturn(const CJson * receviedMsg,char ** errorReturn)576 static void GenerateErrorReturn(const CJson *receviedMsg, char **errorReturn)
577 {
578     const char *pkInfoStr = GetStringFromJson(receviedMsg, FIELD_AUTH_PK_INFO);
579     if (pkInfoStr == NULL) {
580         LOGI("receviedMsg without authPkInfo.");
581         return;
582     }
583     CJson *pkInfoJson = CreateJsonFromString(pkInfoStr);
584     if (pkInfoJson == NULL) {
585         LOGE("create json from string failed.");
586         return;
587     }
588 
589     const char *deviceId = GetStringFromJson(pkInfoJson, FIELD_DEVICE_ID);
590     if (deviceId == NULL) {
591         LOGI("receviedMsg without devcieId.");
592         FreeJson(pkInfoJson);
593         return;
594     }
595     CJson *message = CreateJson();
596     if (message == NULL) {
597         LOGE("create json failed.");
598         FreeJson(pkInfoJson);
599         return;
600     }
601     if (AddStringToJson(message, FIELD_AUTH_ID, deviceId) != HC_SUCCESS) {
602         LOGE("add string to json failed.");
603         FreeJson(message);
604         FreeJson(pkInfoJson);
605         return;
606     }
607 
608     *errorReturn = PackJsonToString(message);
609     if (*errorReturn == NULL) {
610         LOGE("Pack authId Json To String fail.");
611     }
612     FreeJson(message);
613     FreeJson(pkInfoJson);
614 }
615 
OnV1SessionError(SessionImpl * impl,int32_t errorCode,const CJson * receviedMsg)616 static void OnV1SessionError(SessionImpl *impl, int32_t errorCode, const CJson *receviedMsg)
617 {
618     bool isSingleCred = false;
619     (void)GetBoolFromJson(impl->context, FIELD_IS_SINGLE_CRED, &isSingleCred);
620     if (HasNextAuthGroup(receviedMsg) && !isSingleCred) {
621         return;
622     }
623     char *errorReturn = NULL;
624     GenerateErrorReturn(receviedMsg, &errorReturn);
625     OnDevSessionError(impl, errorCode, errorReturn, true);
626     FreeJsonString(errorReturn);
627 }
628 
ProcV1Session(SessionImpl * impl,const CJson * receviedMsg,bool * isFinish)629 static int32_t ProcV1Session(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)
630 {
631     ReportBehaviorEvent(impl, false, false, HC_SUCCESS);
632     int32_t res;
633     if (impl->compatibleSubSession == NULL) {
634         res = InitServerV1Session(impl, receviedMsg);
635         if (res != HC_SUCCESS) {
636             ReportBehaviorEvent(impl, true, false, res);
637             OnV1SessionError(impl, res, receviedMsg);
638             return res;
639         }
640     }
641     res = ProcV1SessionMsg(impl, receviedMsg, isFinish);
642     ReportBehaviorEvent(impl, true, false, res);
643     if (*isFinish) {
644         ReportBehaviorEvent(impl, false, true, HC_SUCCESS);
645     }
646     if (res != HC_SUCCESS) {
647         OnV1SessionError(impl, res, receviedMsg);
648     }
649     return res;
650 }
651 
GetSessionReturnData(const SessionImpl * impl)652 static char *GetSessionReturnData(const SessionImpl *impl)
653 {
654     CJson *returnData = CreateJson();
655     if (returnData == NULL) {
656         LOGW("allocate returnData memory fail.");
657         return NULL;
658     }
659     if (!impl->isCredAuth) {
660         const char *groupId = GetStringFromJson(impl->context, FIELD_GROUP_ID);
661         if (groupId == NULL) {
662             LOGW("get groupId from context fail.");
663             FreeJson(returnData);
664             return NULL;
665         }
666         if (AddStringToJson(returnData, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
667             LOGW("add groupId to returnData fail.");
668             FreeJson(returnData);
669             return NULL;
670         }
671     }
672     char *returnDataStr = PackJsonToString(returnData);
673     FreeJson(returnData);
674     if (returnDataStr == NULL) {
675         LOGW("pack returnData to returnDataStr fail.");
676     }
677     return returnDataStr;
678 }
679 
OnDevSessionFinish(const SessionImpl * impl)680 static void OnDevSessionFinish(const SessionImpl *impl)
681 {
682     ReportBehaviorEvent(impl, false, true, HC_SUCCESS);
683     UPDATE_PERFORM_DATA_BY_INPUT_INDEX(impl->base.id, ON_SESSION_KEY_RETURN_TIME, HcGetCurTimeInMillis());
684     ProcessSessionKeyCallback(impl->base.id, impl->sessionKey.val, impl->sessionKey.length, &impl->base.callback);
685 
686     char *returnData = GetSessionReturnData(impl);
687     UPDATE_PERFORM_DATA_BY_INPUT_INDEX(impl->base.id, ON_FINISH_TIME, HcGetCurTimeInMillis());
688     ProcessFinishCallback(impl->base.id, impl->base.opCode, returnData, &impl->base.callback);
689     FreeJsonString(returnData);
690 
691     bool isBind = true;
692     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
693     if (isBind) {
694         NotifyBindResult(impl->channelType, impl->channelId);
695     }
696     ReportBindAndAuthCallEvent(impl, HC_SUCCESS, false);
697     CloseChannel(impl->channelType, impl->channelId);
698 }
699 
ProcV2Session(SessionImpl * impl,const CJson * receviedMsg,bool * isFinish)700 static int32_t ProcV2Session(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)
701 {
702     ReportBehaviorEvent(impl, false, false, HC_SUCCESS);
703     if (impl->compatibleSubSession != NULL) {
704         DestroyCompatibleSubSession(impl->compatibleSubSession);
705         impl->compatibleSubSession = NULL;
706     }
707     int32_t res;
708     do {
709         res = ParseAllRecvEvent(impl, receviedMsg);
710         if (res != HC_SUCCESS) {
711             break;
712         }
713         res = ProcEventList(impl);
714     } while (0);
715     ReportBehaviorEvent(impl, true, false, res);
716     if (res != HC_SUCCESS) {
717         OnDevSessionError(impl, res, NULL, false);
718         return res;
719     }
720     if (impl->curState == SESSION_FINISH_STATE) {
721         *isFinish = true;
722         OnDevSessionFinish(impl);
723     } else {
724         *isFinish = false;
725     }
726     return HC_SUCCESS;
727 }
728 
ProcessSession(DevSession * self,const CJson * receviedMsg,bool * isFinish)729 static int32_t ProcessSession(DevSession *self, const CJson *receviedMsg, bool *isFinish)
730 {
731     if ((self == NULL) || (receviedMsg == NULL) || (isFinish == NULL)) {
732         LOGE("invalid params.");
733         return HC_ERR_INVALID_PARAMS;
734     }
735     SessionImpl *impl = (SessionImpl *)self;
736     if (!IsSupportSessionV2() || IsV1SessionMsg(receviedMsg)) {
737         return ProcV1Session(impl, receviedMsg, isFinish);
738     } else {
739         return ProcV2Session(impl, receviedMsg, isFinish);
740     }
741 }
742 
BuildDevSessionByContext(const CJson * context,SessionImpl * session)743 static int32_t BuildDevSessionByContext(const CJson *context, SessionImpl *session)
744 {
745     int32_t opCode;
746     if (GetIntFromJson(context, FIELD_OPERATION_CODE, &opCode) != HC_SUCCESS) {
747         LOGE("get opCode from context fail.");
748         return HC_ERR_JSON_GET;
749     }
750     int32_t channelType;
751     if (GetIntFromJson(context, FIELD_CHANNEL_TYPE, &channelType) != HC_SUCCESS) {
752         LOGE("get channelType from context fail.");
753         return HC_ERR_JSON_GET;
754     }
755     int64_t channelId;
756     if (GetByteFromJson(context, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
757         LOGE("get channelId from context fail.");
758         return HC_ERR_JSON_GET;
759     }
760     bool isClient;
761     if (GetBoolFromJson(context, FIELD_IS_CLIENT, &isClient) != HC_SUCCESS) {
762         LOGE("get isClient from context fail.");
763         return HC_ERR_JSON_GET;
764     }
765     bool isCredAuth = false;
766     (void)GetBoolFromJson(context, FIELD_IS_CRED_AUTH, &isCredAuth);
767     session->base.opCode = opCode;
768     session->channelType = channelType;
769     session->channelId = channelId;
770     session->isClient = isClient;
771     session->isCredAuth = isCredAuth;
772     return HC_SUCCESS;
773 }
774 
BuildDevSession(int64_t sessionId,const char * appId,SessionInitParams * params,SessionImpl * session)775 static int32_t BuildDevSession(int64_t sessionId, const char *appId, SessionInitParams *params, SessionImpl *session)
776 {
777     int32_t res = BuildDevSessionByContext(params->context, session);
778     if (res != HC_SUCCESS) {
779         return res;
780     }
781     res = DeepCopyString(appId, &session->base.appId);
782     if (res != HC_SUCCESS) {
783         LOGE("copy appId fail.");
784         return res;
785     }
786     CJson *copyContext = DuplicateJson(params->context);
787     if (copyContext == NULL) {
788         LOGE("copy context fail.");
789         HcFree(session->base.appId);
790         return HC_ERR_ALLOC_MEMORY;
791     }
792     session->base.id = sessionId;
793     session->base.start = StartSession;
794     session->base.process = ProcessSession;
795     session->base.destroy = DestroySession;
796     session->context = copyContext;
797     session->base.callback = params->callback;
798     session->curState = session->isClient ? INIT_CLIENT_STATE : INIT_SERVER_STATE;
799     session->restartState = session->curState;
800     session->credCurIndex = 0;
801     session->credTotalNum = 0;
802     session->credList = CreateIdentityInfoVec();
803     session->eventList = CreateEventList();
804     session->authSubSessionList = CreateAuthSubSessionList();
805     return HC_SUCCESS;
806 }
807 
CreateDevSession(int64_t sessionId,const char * appId,SessionInitParams * params,DevSession ** returnObj)808 int32_t CreateDevSession(int64_t sessionId, const char *appId, SessionInitParams *params, DevSession **returnObj)
809 {
810     if (appId == NULL || params == NULL || returnObj == NULL) {
811         LOGE("invalid params.");
812         return HC_ERR_INVALID_PARAMS;
813     }
814     SessionImpl *session = (SessionImpl *)HcMalloc(sizeof(SessionImpl), 0);
815     if (session == NULL) {
816         LOGE("allocate session memory fail.");
817         return HC_ERR_ALLOC_MEMORY;
818     }
819     int32_t res = BuildDevSession(sessionId, appId, params, session);
820     if (res != HC_SUCCESS) {
821         HcFree(session);
822         return res;
823     }
824     *returnObj = (DevSession *)session;
825     return HC_SUCCESS;
826 }
827