• 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 "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 
36 #define FIELD_MSG "msg"
37 #define FIELD_TYPE "type"
38 #define FIELD_DATA "data"
39 
StartV1Session(SessionImpl * impl,CJson ** sendMsg)40 static int32_t StartV1Session(SessionImpl *impl, CJson **sendMsg)
41 {
42     bool isBind = true;
43     bool isDeviceLevel = false;
44     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
45     (void)GetBoolFromJson(impl->context, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
46     SubSessionTypeValue subSessionType = isBind ? TYPE_CLIENT_BIND_SUB_SESSION : TYPE_CLIENT_AUTH_SUB_SESSION;
47     int32_t res = CreateCompatibleSubSession(subSessionType, impl->context, &impl->base.callback,
48         &impl->compatibleSubSession);
49     if (res != HC_SUCCESS) {
50         if (isDeviceLevel && res == HC_ERR_NO_CANDIDATE_GROUP) {
51             LOGI("create compatibleSubSession fail. no candidate group");
52         } else {
53             LOGE("create compatibleSubSession fail. [Res]: %d", res);
54         }
55         return res;
56     }
57     int32_t status;
58     res = ProcessCompatibleSubSession(impl->compatibleSubSession, impl->context, sendMsg, &status);
59     if (res != HC_SUCCESS) {
60         LOGE("process compatibleSubSession fail. [Res]: %d", res);
61         DestroyCompatibleSubSession(impl->compatibleSubSession);
62         impl->compatibleSubSession = NULL;
63         return res;
64     }
65     return HC_SUCCESS;
66 }
67 
DestroySession(DevSession * self)68 static void DestroySession(DevSession *self)
69 {
70     if (self == NULL) {
71         LOGD("self is NULL.");
72         return;
73     }
74     SessionImpl *impl = (SessionImpl *)self;
75     HcFree(impl->base.appId);
76     FreeJson(impl->context);
77     ClearFreeUint8Buff(&impl->salt);
78     ClearFreeUint8Buff(&impl->sessionKey);
79     ClearIdentityInfoVec(&impl->credList);
80     DestroyEventList(&impl->eventList);
81     uint32_t index;
82     AuthSubSession **ptr;
83     FOR_EACH_HC_VECTOR(impl->authSubSessionList, index, ptr) {
84         AuthSubSession *authSubSesion = *ptr;
85         authSubSesion->destroy(authSubSesion);
86     }
87     DestroyAuthSubSessionList(&impl->authSubSessionList);
88     if (impl->expandSubSession != NULL) {
89         impl->expandSubSession->destroy(impl->expandSubSession);
90     }
91     if (impl->compatibleSubSession != NULL) {
92         DestroyCompatibleSubSession(impl->compatibleSubSession);
93         impl->compatibleSubSession = NULL;
94     }
95     HcFree(impl);
96 }
97 
DecodeEvent(const CJson * inputEvent)98 static int32_t DecodeEvent(const CJson *inputEvent)
99 {
100     if (inputEvent == NULL) {
101         return SESSION_UNKNOWN_EVENT;
102     }
103     int32_t eventType;
104     if (GetIntFromJson(inputEvent, FIELD_TYPE, &eventType) != HC_SUCCESS) {
105         LOGE("get eventType from inputEvent fail.");
106         return SESSION_UNKNOWN_EVENT;
107     }
108     if (START_EVENT <= eventType && eventType <= SESSION_UNKNOWN_EVENT) {
109         return eventType;
110     }
111     LOGE("unknown event.");
112     return SESSION_UNKNOWN_EVENT;
113 }
114 
PackSendMsg(SessionImpl * impl,CJson * sessionMsg,CJson * sendMsg)115 static int32_t PackSendMsg(SessionImpl *impl, CJson *sessionMsg, CJson *sendMsg)
116 {
117     if (AddInt64StringToJson(sendMsg, FIELD_REQUEST_ID, impl->base.id) != HC_SUCCESS) {
118         LOGE("add requestId to json fail!");
119         return HC_ERR_JSON_ADD;
120     }
121     if (AddStringToJson(sendMsg, FIELD_APP_ID, impl->base.appId) != HC_SUCCESS) {
122         LOGE("add appId to json fail.");
123         return HC_ERR_JSON_ADD;
124     }
125     if (AddObjToJson(sendMsg, FIELD_MSG, sessionMsg) != HC_SUCCESS) {
126         LOGE("add sessionMsg to json fail.");
127         return HC_ERR_JSON_ADD;
128     }
129     return HC_SUCCESS;
130 }
131 
SendJsonMsg(const SessionImpl * impl,const CJson * sendMsg)132 static int32_t SendJsonMsg(const SessionImpl *impl, const CJson *sendMsg)
133 {
134     char *sendMsgStr = PackJsonToString(sendMsg);
135     if (sendMsgStr == NULL) {
136         LOGE("convert sendMsg to sendMsgStr fail.");
137         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
138     }
139     UPDATE_PERFORM_DATA_BY_SELF_INDEX(impl->base.id, HcGetCurTimeInMillis());
140     int32_t res = HcSendMsg(impl->channelType, impl->base.id, impl->channelId, &impl->base.callback, sendMsgStr);
141     FreeJsonString(sendMsgStr);
142     return res;
143 }
144 
SendSessionMsg(SessionImpl * impl,CJson * sessionMsg)145 static int32_t SendSessionMsg(SessionImpl *impl, CJson *sessionMsg)
146 {
147     if (GetItemNum(sessionMsg) == 0) {
148         return HC_SUCCESS;
149     }
150     CJson *sendMsg = CreateJson();
151     if (sendMsg == NULL) {
152         LOGE("allocate sendMsg fail.");
153         return HC_ERR_ALLOC_MEMORY;
154     }
155     int32_t res = PackSendMsg(impl, sessionMsg, sendMsg);
156     if (res != HC_SUCCESS) {
157         LOGE("pack send msg fail.");
158         FreeJson(sendMsg);
159         return res;
160     }
161     res = SendJsonMsg(impl, sendMsg);
162     FreeJson(sendMsg);
163     return res;
164 }
165 
ProcEventList(SessionImpl * impl)166 static int32_t ProcEventList(SessionImpl *impl)
167 {
168     CJson *sessionMsg = CreateJsonArray();
169     if (sessionMsg == NULL) {
170         LOGE("allocate sessionMsg memory fail.");
171         return HC_ERR_ALLOC_MEMORY;
172     }
173     int32_t res = HC_ERR_CASE;
174     while (HC_VECTOR_SIZE(&impl->eventList) > 0) {
175         SessionEvent event;
176         HC_VECTOR_POPELEMENT(&impl->eventList, &event, 0);
177         res = SessionSwitchState(impl, &event, sessionMsg);
178         if (res != HC_SUCCESS) {
179             break;
180         }
181     }
182     if (res != HC_SUCCESS) {
183         (void)SendSessionMsg(impl, sessionMsg);
184         FreeJson(sessionMsg);
185         return res;
186     }
187     res = SendSessionMsg(impl, sessionMsg);
188     FreeJson(sessionMsg);
189     return res;
190 }
191 
AddSessionInfo(SessionImpl * impl,CJson * sendMsg)192 static int32_t AddSessionInfo(SessionImpl *impl, CJson *sendMsg)
193 {
194     if (AddIntToJson(sendMsg, FIELD_OP_CODE, impl->base.opCode) != HC_SUCCESS) {
195         LOGE("add opCode to json fail.");
196         return HC_ERR_JSON_ADD;
197     }
198     return HC_SUCCESS;
199 }
200 
StartV2Session(SessionImpl * impl,CJson * sendMsg)201 static int32_t StartV2Session(SessionImpl *impl, CJson *sendMsg)
202 {
203     CJson *sessionMsg = CreateJsonArray();
204     if (sessionMsg == NULL) {
205         LOGE("allocate sessionMsg fail.");
206         return HC_ERR_ALLOC_MEMORY;
207     }
208     SessionEvent startEvent = { START_EVENT, NULL };
209     int32_t res = SessionSwitchState(impl, &startEvent, sessionMsg);
210     if (res != HC_SUCCESS) {
211         FreeJson(sessionMsg);
212         return res;
213     }
214     res = PackSendMsg(impl, sessionMsg, sendMsg);
215     FreeJson(sessionMsg);
216     if (res != HC_SUCCESS) {
217         LOGE("pack send msg fail.");
218         return res;
219     }
220     return AddSessionInfo(impl, sendMsg);
221 }
222 
IsMetaNode(const CJson * context)223 static bool IsMetaNode(const CJson *context)
224 {
225     return GetStringFromJson(context, FIELD_META_NODE_TYPE) != NULL;
226 }
227 
StartSession(DevSession * self)228 static int32_t StartSession(DevSession *self)
229 {
230     if (self == NULL) {
231         LOGE("self is NULL.");
232         return HC_ERR_INVALID_PARAMS;
233     }
234     SessionImpl *impl = (SessionImpl *)self;
235     int32_t res;
236     do {
237         CJson *sendMsg = NULL;
238         /* auth with credentials directly no need to start the v1 session. */
239         bool isDirectAuth = false;
240         bool isDeviceLevel = false;
241         (void)GetBoolFromJson(impl->context, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
242         if (!isDirectAuth) {
243             (void)GetBoolFromJson(impl->context, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
244             res = StartV1Session(impl, &sendMsg);
245             if ((res != HC_SUCCESS)
246                 && (res != HC_ERR_NO_CANDIDATE_GROUP || !isDeviceLevel)) {
247                 // if it's device level auth and no group founded,
248                 // we also need try auth with credentails directly.
249                 LOGE("start v1 session event fail.");
250                 break;
251             }
252         }
253         if (sendMsg == NULL && (sendMsg = CreateJson()) == NULL) {
254             LOGE("allocate sendMsg fail.");
255             return HC_ERR_ALLOC_MEMORY;
256         }
257         if (IsSupportSessionV2() && !IsMetaNode(impl->context)) {
258             res = StartV2Session(impl, sendMsg);
259             if (res != HC_SUCCESS) {
260                 LOGE("start v2 session event fail.");
261                 FreeJson(sendMsg);
262                 break;
263             }
264         }
265         res = SendJsonMsg(impl, sendMsg);
266         FreeJson(sendMsg);
267         if (res != HC_SUCCESS) {
268             LOGE("send msg fail.");
269             break;
270         }
271     } while (0);
272     if (res != HC_SUCCESS) {
273         ProcessErrorCallback(impl->base.id, impl->base.opCode, res, NULL, &impl->base.callback);
274     }
275     return res;
276 }
277 
ParseAllRecvEvent(SessionImpl * impl,const CJson * receviedMsg)278 static int32_t ParseAllRecvEvent(SessionImpl *impl, const CJson *receviedMsg)
279 {
280     CJson *sessionMsg = GetObjFromJson(receviedMsg, FIELD_MSG);
281     if (sessionMsg == NULL) {
282         LOGE("get sessionMsg from receviedMsg fail.");
283         return HC_ERR_JSON_GET;
284     }
285     int32_t eventNum = GetItemNum(sessionMsg);
286     if (eventNum <= 0) {
287         LOGE("There are no events in the received session message.");
288         return HC_ERR_BAD_MESSAGE;
289     }
290     for (int32_t i = 0; i < eventNum; i++) {
291         CJson *inputEventJson = GetItemFromArray(sessionMsg, i);
292         if (inputEventJson == NULL) {
293             LOGE("get inputEventJson from sessionMsg fail.");
294             return HC_ERR_JSON_GET;
295         }
296         int32_t eventType = DecodeEvent(inputEventJson);
297         CJson *eventData = GetObjFromJson(inputEventJson, FIELD_DATA);
298         if (eventData == NULL) {
299             LOGE("get eventData fail.");
300             return HC_ERR_JSON_GET;
301         }
302         SessionEvent event = { eventType, eventData };
303         if (HC_VECTOR_PUSHBACK(&impl->eventList, &event) == NULL) {
304             LOGE("push event fail.");
305             return HC_ERR_ALLOC_MEMORY;
306         }
307         LOGI("push event success. [Type]: %d", eventType);
308     }
309     return HC_SUCCESS;
310 }
311 
IsV1SessionMsg(const CJson * receviedMsg)312 static bool IsV1SessionMsg(const CJson *receviedMsg)
313 {
314     return (GetObjFromJson(receviedMsg, FIELD_MSG) == NULL);
315 }
316 
AddChannelInfoToParams(SessionImpl * impl,CJson * receviedMsg)317 static int32_t AddChannelInfoToParams(SessionImpl *impl, CJson *receviedMsg)
318 {
319     int32_t channelType;
320     if (GetIntFromJson(impl->context, FIELD_CHANNEL_TYPE, &channelType) != HC_SUCCESS) {
321         LOGE("get channelType from context fail.");
322         return HC_ERR_JSON_GET;
323     }
324     int64_t channelId;
325     if (GetByteFromJson(impl->context, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
326         LOGE("get channelId from context fail.");
327         return HC_ERR_JSON_GET;
328     }
329     if (AddIntToJson(receviedMsg, FIELD_CHANNEL_TYPE, channelType) != HC_SUCCESS) {
330         LOGE("add channelType to params fail.");
331         return HC_ERR_JSON_ADD;
332     }
333     if (AddByteToJson(receviedMsg, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
334         LOGE("add channelId to params fail.");
335         return HC_ERR_JSON_ADD;
336     }
337     return HC_SUCCESS;
338 }
339 
CombindServerBindParams(SessionImpl * impl,CJson * receviedMsg)340 static int32_t CombindServerBindParams(SessionImpl *impl, CJson *receviedMsg)
341 {
342     int32_t osAccountId;
343     if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
344         LOGE("get osAccountId from context fail.");
345         return HC_ERR_JSON_GET;
346     }
347     if (AddIntToJson(receviedMsg, FIELD_OS_ACCOUNT_ID, osAccountId) != HC_SUCCESS) {
348         LOGE("add osAccountId to receviedMsg fail.");
349         return HC_ERR_JSON_ADD;
350     }
351     int32_t protocolExpandVal = INVALID_PROTOCOL_EXPAND_VALUE;
352     (void)GetIntFromJson(impl->context, FIELD_PROTOCOL_EXPAND, &protocolExpandVal);
353     if (AddIntToJson(receviedMsg, FIELD_PROTOCOL_EXPAND, protocolExpandVal) != HC_SUCCESS) {
354         LOGE("Failed to add protocol expand val to receviedMsg!");
355         return HC_ERR_JSON_ADD;
356     }
357     return CombineConfirmData(impl->opCode, impl->context, receviedMsg);
358 }
359 
CombindServerAuthParams(SessionImpl * impl,CJson * receviedMsg)360 static int32_t CombindServerAuthParams(SessionImpl *impl, CJson *receviedMsg)
361 {
362     if (AddInt64StringToJson(receviedMsg, FIELD_REQUEST_ID, impl->base.id) != HC_SUCCESS) {
363         LOGE("add requestId to receviedMsg fail.");
364         return HC_ERR_JSON_ADD;
365     }
366     if (AddIntToJson(receviedMsg, FIELD_OPERATION_CODE, AUTHENTICATE) != HC_SUCCESS) {
367         LOGE("add operationCode to receviedMsg fail.");
368         return HC_ERR_JSON_ADD;
369     }
370     return CombineAuthConfirmData(impl->context, receviedMsg);
371 }
372 
CombineServerParams(SessionImpl * impl,bool isBind,CJson * receviedMsg)373 static int32_t CombineServerParams(SessionImpl *impl, bool isBind, CJson *receviedMsg)
374 {
375     int32_t res = AddChannelInfoToParams(impl, receviedMsg);
376     if (res != HC_SUCCESS) {
377         return res;
378     }
379     return isBind ? CombindServerBindParams(impl, receviedMsg) : CombindServerAuthParams(impl, receviedMsg);
380 }
381 
InitServerV1Session(SessionImpl * impl,const CJson * receviedMsg)382 static int32_t InitServerV1Session(SessionImpl *impl, const CJson *receviedMsg)
383 {
384     bool isBind = true;
385     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
386     int32_t res = CombineServerParams(impl, isBind, (CJson *)receviedMsg);
387     if (res != HC_SUCCESS) {
388         return res;
389     }
390     SubSessionTypeValue subSessionType = isBind ? TYPE_SERVER_BIND_SUB_SESSION : TYPE_SERVER_AUTH_SUB_SESSION;
391     res = CreateCompatibleSubSession(subSessionType, (CJson *)receviedMsg, &impl->base.callback,
392         &impl->compatibleSubSession);
393     if (res != HC_SUCCESS) {
394         LOGE("create compatibleSubSession fail. [Res]: %d", res);
395         return res;
396     }
397     return HC_SUCCESS;
398 }
399 
ProcV1SessionMsg(SessionImpl * impl,const CJson * receviedMsg,bool * isFinish)400 static int32_t ProcV1SessionMsg(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)
401 {
402     CJson *out = NULL;
403     int32_t status;
404     int32_t res = ProcessCompatibleSubSession(impl->compatibleSubSession, (CJson *)receviedMsg, &out, &status);
405     if (res != HC_SUCCESS) {
406         DestroyCompatibleSubSession(impl->compatibleSubSession);
407         impl->compatibleSubSession = NULL;
408         if (status == FINISH) {
409             LOGI("process compatibleSubSession finish.");
410             *isFinish = true;
411             return HC_SUCCESS;
412         } else {
413             LOGE("process compatibleSubSession fail. [Res]: %d", res);
414             return res;
415         }
416     }
417     *isFinish = false;
418     return HC_SUCCESS;
419 }
420 
HasNextAuthGroup(const CJson * receviedMsg)421 static inline bool HasNextAuthGroup(const CJson *receviedMsg)
422 {
423     return GetStringFromJson(receviedMsg, FIELD_ALTERNATIVE) != NULL;
424 }
425 
OnV1SessionError(SessionImpl * impl,int32_t errorCode,const CJson * receviedMsg)426 static void OnV1SessionError(SessionImpl *impl, int32_t errorCode, const CJson *receviedMsg)
427 {
428     if (HasNextAuthGroup(receviedMsg)) {
429         return;
430     }
431     ProcessErrorCallback(impl->base.id, impl->base.opCode, errorCode, NULL, &impl->base.callback);
432 }
433 
ProcV1Session(SessionImpl * impl,const CJson * receviedMsg,bool * isFinish)434 static int32_t ProcV1Session(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)
435 {
436     int32_t res;
437     if (impl->compatibleSubSession == NULL) {
438         res = InitServerV1Session(impl, receviedMsg);
439         if (res != HC_SUCCESS) {
440             OnV1SessionError(impl, res, receviedMsg);
441             return res;
442         }
443     }
444     res = ProcV1SessionMsg(impl, receviedMsg, isFinish);
445     if (res != HC_SUCCESS) {
446         OnV1SessionError(impl, res, receviedMsg);
447     }
448     return res;
449 }
450 
GetSessionReturnData(const SessionImpl * impl)451 static char *GetSessionReturnData(const SessionImpl *impl)
452 {
453     CJson *returnData = CreateJson();
454     if (returnData == NULL) {
455         LOGW("allocate returnData memory fail.");
456         return NULL;
457     }
458     const char *groupId = GetStringFromJson(impl->context, FIELD_GROUP_ID);
459     if (groupId == NULL) {
460         LOGW("get groupId from context fail.");
461         FreeJson(returnData);
462         return NULL;
463     }
464     if (AddStringToJson(returnData, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
465         LOGW("add groupId to returnData fail.");
466         FreeJson(returnData);
467         return NULL;
468     }
469     char *returnDataStr = PackJsonToString(returnData);
470     FreeJson(returnData);
471     if (returnDataStr == NULL) {
472         LOGW("pack returnData to returnDataStr fail.");
473     }
474     return returnDataStr;
475 }
476 
OnDevSessionFinish(const SessionImpl * impl)477 static void OnDevSessionFinish(const SessionImpl *impl)
478 {
479     UPDATE_PERFORM_DATA_BY_INPUT_INDEX(impl->base.id, ON_SESSION_KEY_RETURN_TIME, HcGetCurTimeInMillis());
480     ProcessSessionKeyCallback(impl->base.id, impl->sessionKey.val, impl->sessionKey.length, &impl->base.callback);
481 
482     char *returnData = GetSessionReturnData(impl);
483     UPDATE_PERFORM_DATA_BY_INPUT_INDEX(impl->base.id, ON_FINISH_TIME, HcGetCurTimeInMillis());
484     ProcessFinishCallback(impl->base.id, impl->base.opCode, returnData, &impl->base.callback);
485     FreeJsonString(returnData);
486 
487     bool isBind = true;
488     (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
489     if (isBind) {
490         NotifyBindResult(impl->channelType, impl->channelId);
491     }
492     CloseChannel(impl->channelType, impl->channelId);
493 }
494 
ProcV2Session(SessionImpl * impl,const CJson * receviedMsg,bool * isFinish)495 static int32_t ProcV2Session(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)
496 {
497     if (!IsSupportSessionV2()) {
498         LOGE("not suppot session v2.");
499         ProcessErrorCallback(impl->base.id, impl->base.opCode, HC_ERR_NOT_SUPPORT, NULL, &impl->base.callback);
500         return HC_ERR_NOT_SUPPORT;
501     }
502     if (impl->compatibleSubSession != NULL) {
503         DestroyCompatibleSubSession(impl->compatibleSubSession);
504         impl->compatibleSubSession = NULL;
505     }
506     int32_t res;
507     do {
508         res = ParseAllRecvEvent(impl, receviedMsg);
509         if (res != HC_SUCCESS) {
510             break;
511         }
512         res = ProcEventList(impl);
513     } while (0);
514     if (res != HC_SUCCESS) {
515         ProcessErrorCallback(impl->base.id, impl->base.opCode, res, NULL, &impl->base.callback);
516         return res;
517     }
518     if (impl->curState == SESSION_FINISH_STATE) {
519         *isFinish = true;
520         OnDevSessionFinish(impl);
521     } else {
522         *isFinish = false;
523     }
524     return HC_SUCCESS;
525 }
526 
ProcessSession(DevSession * self,const CJson * receviedMsg,bool * isFinish)527 static int32_t ProcessSession(DevSession *self, const CJson *receviedMsg, bool *isFinish)
528 {
529     if ((self == NULL) || (receviedMsg == NULL) || (isFinish == NULL)) {
530         LOGE("invalid params.");
531         return HC_ERR_INVALID_PARAMS;
532     }
533     SessionImpl *impl = (SessionImpl *)self;
534     if (!IsSupportSessionV2() || IsV1SessionMsg(receviedMsg)) {
535         return ProcV1Session(impl, receviedMsg, isFinish);
536     } else {
537         return ProcV2Session(impl, receviedMsg, isFinish);
538     }
539 }
540 
BuildDevSessionByContext(const CJson * context,SessionImpl * session)541 static int32_t BuildDevSessionByContext(const CJson *context, SessionImpl *session)
542 {
543     int32_t opCode;
544     if (GetIntFromJson(context, FIELD_OPERATION_CODE, &opCode) != HC_SUCCESS) {
545         LOGE("get opCode from context fail.");
546         return HC_ERR_JSON_GET;
547     }
548     int32_t channelType;
549     if (GetIntFromJson(context, FIELD_CHANNEL_TYPE, &channelType) != HC_SUCCESS) {
550         LOGE("get channelType from context fail.");
551         return HC_ERR_JSON_GET;
552     }
553     int64_t channelId;
554     if (GetByteFromJson(context, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
555         LOGE("get channelId from context fail.");
556         return HC_ERR_JSON_GET;
557     }
558     bool isClient;
559     if (GetBoolFromJson(context, FIELD_IS_CLIENT, &isClient) != HC_SUCCESS) {
560         LOGE("get isClient from context fail.");
561         return HC_ERR_JSON_GET;
562     }
563     session->base.opCode = opCode;
564     session->channelType = channelType;
565     session->channelId = channelId;
566     session->isClient = isClient;
567     return HC_SUCCESS;
568 }
569 
BuildDevSession(int64_t sessionId,const char * appId,SessionInitParams * params,SessionImpl * session)570 static int32_t BuildDevSession(int64_t sessionId, const char *appId, SessionInitParams *params, SessionImpl *session)
571 {
572     int32_t res = BuildDevSessionByContext(params->context, session);
573     if (res != HC_SUCCESS) {
574         return res;
575     }
576     res = DeepCopyString(appId, &session->base.appId);
577     if (res != HC_SUCCESS) {
578         LOGE("copy appId fail.");
579         return res;
580     }
581     CJson *copyContext = DuplicateJson(params->context);
582     if (copyContext == NULL) {
583         LOGE("copy context fail.");
584         HcFree(session->base.appId);
585         return HC_ERR_ALLOC_MEMORY;
586     }
587     session->base.id = sessionId;
588     session->base.start = StartSession;
589     session->base.process = ProcessSession;
590     session->base.destroy = DestroySession;
591     session->context = copyContext;
592     session->base.callback = params->callback;
593     session->curState = session->isClient ? INIT_CLIENT_STATE : INIT_SERVER_STATE;
594     session->restartState = session->curState;
595     session->credCurIndex = 0;
596     session->credTotalNum = 0;
597     session->credList = CreateIdentityInfoVec();
598     session->eventList = CreateEventList();
599     session->authSubSessionList = CreateAuthSubSessionList();
600     return HC_SUCCESS;
601 }
602 
CreateDevSession(int64_t sessionId,const char * appId,SessionInitParams * params,DevSession ** returnObj)603 int32_t CreateDevSession(int64_t sessionId, const char *appId, SessionInitParams *params, DevSession **returnObj)
604 {
605     if (appId == NULL || params == NULL || returnObj == NULL) {
606         LOGE("invalid params.");
607         return HC_ERR_INVALID_PARAMS;
608     }
609     SessionImpl *session = (SessionImpl *)HcMalloc(sizeof(SessionImpl), 0);
610     if (session == NULL) {
611         LOGE("allocate session memory fail.");
612         return HC_ERR_ALLOC_MEMORY;
613     }
614     int32_t res = BuildDevSession(sessionId, appId, params, session);
615     if (res != HC_SUCCESS) {
616         HcFree(session);
617         return res;
618     }
619     *returnObj = (DevSession *)session;
620     return HC_SUCCESS;
621 }
622