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