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
OnDevSessionError(const SessionImpl *impl, int32_t errorCode, const char *errorReturn)228 static void OnDevSessionError(const SessionImpl *impl, int32_t errorCode, const char *errorReturn)
229 {
230 ProcessErrorCallback(impl->base.id, impl->base.opCode, errorCode, errorReturn, &impl->base.callback);
231 CloseChannel(impl->channelType, impl->channelId);
232 }
233
StartSession(DevSession *self)234 static int32_t StartSession(DevSession *self)
235 {
236 if (self == NULL) {
237 LOGE("self is NULL.");
238 return HC_ERR_INVALID_PARAMS;
239 }
240 SessionImpl *impl = (SessionImpl *)self;
241 int32_t res;
242 do {
243 CJson *sendMsg = NULL;
244 /* auth with credentials directly no need to start the v1 session. */
245 bool isDirectAuth = false;
246 bool isDeviceLevel = false;
247 (void)GetBoolFromJson(impl->context, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
248 if (!isDirectAuth) {
249 (void)GetBoolFromJson(impl->context, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
250 res = StartV1Session(impl, &sendMsg);
251 if ((res != HC_SUCCESS)
252 && (res != HC_ERR_NO_CANDIDATE_GROUP || !isDeviceLevel)) {
253 // if it's device level auth and no group founded,
254 // we also need try auth with credentails directly.
255 LOGE("start v1 session event fail.");
256 break;
257 }
258 }
259 sendMsg = (sendMsg == NULL ? CreateJson() : sendMsg);
260 if (sendMsg == NULL) {
261 LOGE("allocate sendMsg fail.");
262 return HC_ERR_ALLOC_MEMORY;
263 }
264 if (IsSupportSessionV2() && !IsMetaNode(impl->context)) {
265 res = StartV2Session(impl, sendMsg);
266 if (res != HC_SUCCESS) {
267 LOGE("start v2 session event fail.");
268 FreeJson(sendMsg);
269 break;
270 }
271 }
272 res = SendJsonMsg(impl, sendMsg);
273 FreeJson(sendMsg);
274 if (res != HC_SUCCESS) {
275 LOGE("send msg fail.");
276 break;
277 }
278 } while (0);
279 if (res != HC_SUCCESS) {
280 OnDevSessionError(impl, res, NULL);
281 }
282 return res;
283 }
284
ParseAllRecvEvent(SessionImpl *impl, const CJson *receviedMsg)285 static int32_t ParseAllRecvEvent(SessionImpl *impl, const CJson *receviedMsg)
286 {
287 CJson *sessionMsg = GetObjFromJson(receviedMsg, FIELD_MSG);
288 if (sessionMsg == NULL) {
289 LOGE("get sessionMsg from receviedMsg fail.");
290 return HC_ERR_JSON_GET;
291 }
292 int32_t eventNum = GetItemNum(sessionMsg);
293 if (eventNum <= 0) {
294 LOGE("There are no events in the received session message.");
295 return HC_ERR_BAD_MESSAGE;
296 }
297 for (int32_t i = 0; i < eventNum; i++) {
298 CJson *inputEventJson = GetItemFromArray(sessionMsg, i);
299 if (inputEventJson == NULL) {
300 LOGE("get inputEventJson from sessionMsg fail.");
301 return HC_ERR_JSON_GET;
302 }
303 int32_t eventType = DecodeEvent(inputEventJson);
304 CJson *eventData = GetObjFromJson(inputEventJson, FIELD_DATA);
305 if (eventData == NULL) {
306 LOGE("get eventData fail.");
307 return HC_ERR_JSON_GET;
308 }
309 SessionEvent event = { eventType, eventData };
310 if (HC_VECTOR_PUSHBACK(&impl->eventList, &event) == NULL) {
311 LOGE("push event fail.");
312 return HC_ERR_ALLOC_MEMORY;
313 }
314 LOGI("push event success. [Type]: %d", eventType);
315 }
316 return HC_SUCCESS;
317 }
318
IsV1SessionMsg(const CJson *receviedMsg)319 static bool IsV1SessionMsg(const CJson *receviedMsg)
320 {
321 return (GetObjFromJson(receviedMsg, FIELD_MSG) == NULL);
322 }
323
AddChannelInfoToParams(SessionImpl *impl, CJson *receviedMsg)324 static int32_t AddChannelInfoToParams(SessionImpl *impl, CJson *receviedMsg)
325 {
326 int32_t channelType;
327 if (GetIntFromJson(impl->context, FIELD_CHANNEL_TYPE, &channelType) != HC_SUCCESS) {
328 LOGE("get channelType from context fail.");
329 return HC_ERR_JSON_GET;
330 }
331 int64_t channelId;
332 if (GetByteFromJson(impl->context, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
333 LOGE("get channelId from context fail.");
334 return HC_ERR_JSON_GET;
335 }
336 if (AddIntToJson(receviedMsg, FIELD_CHANNEL_TYPE, channelType) != HC_SUCCESS) {
337 LOGE("add channelType to params fail.");
338 return HC_ERR_JSON_ADD;
339 }
340 if (AddByteToJson(receviedMsg, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
341 LOGE("add channelId to params fail.");
342 return HC_ERR_JSON_ADD;
343 }
344 return HC_SUCCESS;
345 }
346
CombindServerBindParams(SessionImpl *impl, CJson *receviedMsg)347 static int32_t CombindServerBindParams(SessionImpl *impl, CJson *receviedMsg)
348 {
349 int32_t osAccountId;
350 if (GetIntFromJson(impl->context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
351 LOGE("get osAccountId from context fail.");
352 return HC_ERR_JSON_GET;
353 }
354 if (AddIntToJson(receviedMsg, FIELD_OS_ACCOUNT_ID, osAccountId) != HC_SUCCESS) {
355 LOGE("add osAccountId to receviedMsg fail.");
356 return HC_ERR_JSON_ADD;
357 }
358 int32_t protocolExpandVal = INVALID_PROTOCOL_EXPAND_VALUE;
359 (void)GetIntFromJson(impl->context, FIELD_PROTOCOL_EXPAND, &protocolExpandVal);
360 if (AddIntToJson(receviedMsg, FIELD_PROTOCOL_EXPAND, protocolExpandVal) != HC_SUCCESS) {
361 LOGE("Failed to add protocol expand val to receviedMsg!");
362 return HC_ERR_JSON_ADD;
363 }
364 return CombineConfirmData(impl->opCode, impl->context, receviedMsg);
365 }
366
CombindServerAuthParams(SessionImpl *impl, CJson *receviedMsg)367 static int32_t CombindServerAuthParams(SessionImpl *impl, CJson *receviedMsg)
368 {
369 if (AddInt64StringToJson(receviedMsg, FIELD_REQUEST_ID, impl->base.id) != HC_SUCCESS) {
370 LOGE("add requestId to receviedMsg fail.");
371 return HC_ERR_JSON_ADD;
372 }
373 if (AddIntToJson(receviedMsg, FIELD_OPERATION_CODE, AUTHENTICATE) != HC_SUCCESS) {
374 LOGE("add operationCode to receviedMsg fail.");
375 return HC_ERR_JSON_ADD;
376 }
377 return CombineAuthConfirmData(impl->context, receviedMsg);
378 }
379
AddConfirmationToParams(const CJson *context, CJson *receviedMsg)380 static int32_t AddConfirmationToParams(const CJson *context, CJson *receviedMsg)
381 {
382 uint32_t confirmation = REQUEST_REJECTED;
383 (void)GetUnsignedIntFromJson(context, FIELD_CONFIRMATION, &confirmation);
384 if (AddIntToJson(receviedMsg, FIELD_CONFIRMATION, (int32_t)confirmation) != HC_SUCCESS) {
385 LOGE("add confirmation to receviedMsg fail.");
386 return HC_ERR_JSON_ADD;
387 }
388 return HC_SUCCESS;
389 }
390
CombineServerParams(SessionImpl *impl, bool isBind, CJson *receviedMsg)391 static int32_t CombineServerParams(SessionImpl *impl, bool isBind, CJson *receviedMsg)
392 {
393 int32_t res = AddChannelInfoToParams(impl, receviedMsg);
394 if (res != HC_SUCCESS) {
395 return res;
396 }
397 res = AddConfirmationToParams(impl->context, receviedMsg);
398 if (res != HC_SUCCESS) {
399 return res;
400 }
401 return isBind ? CombindServerBindParams(impl, receviedMsg) : CombindServerAuthParams(impl, receviedMsg);
402 }
403
InitServerV1Session(SessionImpl *impl, const CJson *receviedMsg)404 static int32_t InitServerV1Session(SessionImpl *impl, const CJson *receviedMsg)
405 {
406 bool isBind = true;
407 (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
408 int32_t res = CombineServerParams(impl, isBind, (CJson *)receviedMsg);
409 if (res != HC_SUCCESS) {
410 return res;
411 }
412 SubSessionTypeValue subSessionType = isBind ? TYPE_SERVER_BIND_SUB_SESSION : TYPE_SERVER_AUTH_SUB_SESSION;
413 res = CreateCompatibleSubSession(subSessionType, (CJson *)receviedMsg, &impl->base.callback,
414 &impl->compatibleSubSession);
415 if (res != HC_SUCCESS) {
416 LOGE("create compatibleSubSession fail. [Res]: %d", res);
417 return res;
418 }
419 return HC_SUCCESS;
420 }
421
ProcV1SessionMsg(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)422 static int32_t ProcV1SessionMsg(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)
423 {
424 CJson *out = NULL;
425 int32_t status;
426 int32_t res = ProcessCompatibleSubSession(impl->compatibleSubSession, (CJson *)receviedMsg, &out, &status);
427 if (res != HC_SUCCESS) {
428 DestroyCompatibleSubSession(impl->compatibleSubSession);
429 impl->compatibleSubSession = NULL;
430 if (status == FINISH) {
431 LOGI("process compatibleSubSession finish.");
432 *isFinish = true;
433 return HC_SUCCESS;
434 } else {
435 LOGE("process compatibleSubSession fail. [Res]: %d", res);
436 return res;
437 }
438 }
439 *isFinish = false;
440 return HC_SUCCESS;
441 }
442
HasNextAuthGroup(const CJson *receviedMsg)443 static inline bool HasNextAuthGroup(const CJson *receviedMsg)
444 {
445 return GetStringFromJson(receviedMsg, FIELD_ALTERNATIVE) != NULL;
446 }
447
GenerateErrorReturn(const CJson *receviedMsg, char **errorReturn)448 static void GenerateErrorReturn(const CJson *receviedMsg, char **errorReturn)
449 {
450 const char *pkInfoStr = GetStringFromJson(receviedMsg, FIELD_AUTH_PK_INFO);
451 if (pkInfoStr == NULL) {
452 LOGI("receviedMsg without authPkInfo.");
453 return;
454 }
455 CJson *pkInfoJson = CreateJsonFromString(pkInfoStr);
456 if (pkInfoJson == NULL) {
457 LOGE("create json from string failed.");
458 return;
459 }
460
461 const char *deviceId = GetStringFromJson(pkInfoJson, FIELD_DEVICE_ID);
462 if (deviceId == NULL) {
463 LOGI("receviedMsg without devcieId.");
464 FreeJson(pkInfoJson);
465 return;
466 }
467 CJson *message = CreateJson();
468 if (message == NULL) {
469 LOGE("create json failed.");
470 FreeJson(pkInfoJson);
471 return;
472 }
473 if (AddStringToJson(message, FIELD_AUTH_ID, deviceId) != HC_SUCCESS) {
474 LOGE("add string to json failed.");
475 FreeJson(message);
476 FreeJson(pkInfoJson);
477 return;
478 }
479
480 *errorReturn = PackJsonToString(message);
481 if (*errorReturn == NULL) {
482 LOGE("Pack authId Json To String fail.");
483 }
484 FreeJson(message);
485 FreeJson(pkInfoJson);
486 }
487
OnV1SessionError(SessionImpl *impl, int32_t errorCode, const CJson *receviedMsg)488 static void OnV1SessionError(SessionImpl *impl, int32_t errorCode, const CJson *receviedMsg)
489 {
490 if (HasNextAuthGroup(receviedMsg)) {
491 return;
492 }
493 char *errorReturn = NULL;
494 GenerateErrorReturn(receviedMsg, &errorReturn);
495 OnDevSessionError(impl, errorCode, errorReturn);
496 FreeJsonString(errorReturn);
497 }
498
ProcV1Session(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)499 static int32_t ProcV1Session(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)
500 {
501 int32_t res;
502 if (impl->compatibleSubSession == NULL) {
503 res = InitServerV1Session(impl, receviedMsg);
504 if (res != HC_SUCCESS) {
505 OnV1SessionError(impl, res, receviedMsg);
506 return res;
507 }
508 }
509 res = ProcV1SessionMsg(impl, receviedMsg, isFinish);
510 if (res != HC_SUCCESS) {
511 OnV1SessionError(impl, res, receviedMsg);
512 }
513 return res;
514 }
515
GetSessionReturnData(const SessionImpl *impl)516 static char *GetSessionReturnData(const SessionImpl *impl)
517 {
518 CJson *returnData = CreateJson();
519 if (returnData == NULL) {
520 LOGW("allocate returnData memory fail.");
521 return NULL;
522 }
523 const char *groupId = GetStringFromJson(impl->context, FIELD_GROUP_ID);
524 if (groupId == NULL) {
525 LOGW("get groupId from context fail.");
526 FreeJson(returnData);
527 return NULL;
528 }
529 if (AddStringToJson(returnData, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
530 LOGW("add groupId to returnData fail.");
531 FreeJson(returnData);
532 return NULL;
533 }
534 char *returnDataStr = PackJsonToString(returnData);
535 FreeJson(returnData);
536 if (returnDataStr == NULL) {
537 LOGW("pack returnData to returnDataStr fail.");
538 }
539 return returnDataStr;
540 }
541
OnDevSessionFinish(const SessionImpl *impl)542 static void OnDevSessionFinish(const SessionImpl *impl)
543 {
544 UPDATE_PERFORM_DATA_BY_INPUT_INDEX(impl->base.id, ON_SESSION_KEY_RETURN_TIME, HcGetCurTimeInMillis());
545 ProcessSessionKeyCallback(impl->base.id, impl->sessionKey.val, impl->sessionKey.length, &impl->base.callback);
546
547 char *returnData = GetSessionReturnData(impl);
548 UPDATE_PERFORM_DATA_BY_INPUT_INDEX(impl->base.id, ON_FINISH_TIME, HcGetCurTimeInMillis());
549 ProcessFinishCallback(impl->base.id, impl->base.opCode, returnData, &impl->base.callback);
550 FreeJsonString(returnData);
551
552 bool isBind = true;
553 (void)GetBoolFromJson(impl->context, FIELD_IS_BIND, &isBind);
554 if (isBind) {
555 NotifyBindResult(impl->channelType, impl->channelId);
556 }
557 CloseChannel(impl->channelType, impl->channelId);
558 }
559
ProcV2Session(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)560 static int32_t ProcV2Session(SessionImpl *impl, const CJson *receviedMsg, bool *isFinish)
561 {
562 if (!IsSupportSessionV2()) {
563 LOGE("not suppot session v2.");
564 OnDevSessionError(impl, HC_ERR_NOT_SUPPORT, NULL);
565 return HC_ERR_NOT_SUPPORT;
566 }
567 if (impl->compatibleSubSession != NULL) {
568 DestroyCompatibleSubSession(impl->compatibleSubSession);
569 impl->compatibleSubSession = NULL;
570 }
571 int32_t res;
572 do {
573 res = ParseAllRecvEvent(impl, receviedMsg);
574 if (res != HC_SUCCESS) {
575 break;
576 }
577 res = ProcEventList(impl);
578 } while (0);
579 if (res != HC_SUCCESS) {
580 OnDevSessionError(impl, res, NULL);
581 return res;
582 }
583 if (impl->curState == SESSION_FINISH_STATE) {
584 *isFinish = true;
585 OnDevSessionFinish(impl);
586 } else {
587 *isFinish = false;
588 }
589 return HC_SUCCESS;
590 }
591
ProcessSession(DevSession *self, const CJson *receviedMsg, bool *isFinish)592 static int32_t ProcessSession(DevSession *self, const CJson *receviedMsg, bool *isFinish)
593 {
594 if ((self == NULL) || (receviedMsg == NULL) || (isFinish == NULL)) {
595 LOGE("invalid params.");
596 return HC_ERR_INVALID_PARAMS;
597 }
598 SessionImpl *impl = (SessionImpl *)self;
599 if (!IsSupportSessionV2() || IsV1SessionMsg(receviedMsg)) {
600 return ProcV1Session(impl, receviedMsg, isFinish);
601 } else {
602 return ProcV2Session(impl, receviedMsg, isFinish);
603 }
604 }
605
BuildDevSessionByContext(const CJson *context, SessionImpl *session)606 static int32_t BuildDevSessionByContext(const CJson *context, SessionImpl *session)
607 {
608 int32_t opCode;
609 if (GetIntFromJson(context, FIELD_OPERATION_CODE, &opCode) != HC_SUCCESS) {
610 LOGE("get opCode from context fail.");
611 return HC_ERR_JSON_GET;
612 }
613 int32_t channelType;
614 if (GetIntFromJson(context, FIELD_CHANNEL_TYPE, &channelType) != HC_SUCCESS) {
615 LOGE("get channelType from context fail.");
616 return HC_ERR_JSON_GET;
617 }
618 int64_t channelId;
619 if (GetByteFromJson(context, FIELD_CHANNEL_ID, (uint8_t *)&channelId, sizeof(int64_t)) != HC_SUCCESS) {
620 LOGE("get channelId from context fail.");
621 return HC_ERR_JSON_GET;
622 }
623 bool isClient;
624 if (GetBoolFromJson(context, FIELD_IS_CLIENT, &isClient) != HC_SUCCESS) {
625 LOGE("get isClient from context fail.");
626 return HC_ERR_JSON_GET;
627 }
628 session->base.opCode = opCode;
629 session->channelType = channelType;
630 session->channelId = channelId;
631 session->isClient = isClient;
632 return HC_SUCCESS;
633 }
634
BuildDevSession(int64_t sessionId, const char *appId, SessionInitParams *params, SessionImpl *session)635 static int32_t BuildDevSession(int64_t sessionId, const char *appId, SessionInitParams *params, SessionImpl *session)
636 {
637 int32_t res = BuildDevSessionByContext(params->context, session);
638 if (res != HC_SUCCESS) {
639 return res;
640 }
641 res = DeepCopyString(appId, &session->base.appId);
642 if (res != HC_SUCCESS) {
643 LOGE("copy appId fail.");
644 return res;
645 }
646 CJson *copyContext = DuplicateJson(params->context);
647 if (copyContext == NULL) {
648 LOGE("copy context fail.");
649 HcFree(session->base.appId);
650 return HC_ERR_ALLOC_MEMORY;
651 }
652 session->base.id = sessionId;
653 session->base.start = StartSession;
654 session->base.process = ProcessSession;
655 session->base.destroy = DestroySession;
656 session->context = copyContext;
657 session->base.callback = params->callback;
658 session->curState = session->isClient ? INIT_CLIENT_STATE : INIT_SERVER_STATE;
659 session->restartState = session->curState;
660 session->credCurIndex = 0;
661 session->credTotalNum = 0;
662 session->credList = CreateIdentityInfoVec();
663 session->eventList = CreateEventList();
664 session->authSubSessionList = CreateAuthSubSessionList();
665 return HC_SUCCESS;
666 }
667
CreateDevSession(int64_t sessionId, const char *appId, SessionInitParams *params, DevSession **returnObj)668 int32_t CreateDevSession(int64_t sessionId, const char *appId, SessionInitParams *params, DevSession **returnObj)
669 {
670 if (appId == NULL || params == NULL || returnObj == NULL) {
671 LOGE("invalid params.");
672 return HC_ERR_INVALID_PARAMS;
673 }
674 SessionImpl *session = (SessionImpl *)HcMalloc(sizeof(SessionImpl), 0);
675 if (session == NULL) {
676 LOGE("allocate session memory fail.");
677 return HC_ERR_ALLOC_MEMORY;
678 }
679 int32_t res = BuildDevSession(sessionId, appId, params, session);
680 if (res != HC_SUCCESS) {
681 HcFree(session);
682 return res;
683 }
684 *returnObj = (DevSession *)session;
685 return HC_SUCCESS;
686 }
687