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