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