1 /*
2 * Copyright (C) 2021-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 "iso_client_task.h"
17 #include "hc_log.h"
18 #include "hc_types.h"
19 #include "iso_client_bind_exchange_task.h"
20 #include "iso_client_protocol_task.h"
21 #include "iso_task_common.h"
22
GetIsoClientTaskType(const struct SubTaskBaseT * task)23 static int GetIsoClientTaskType(const struct SubTaskBaseT *task)
24 {
25 IsoClientTask *realTask = (IsoClientTask *)task;
26 if (realTask->curTask == NULL) {
27 LOGE("CurTask is null.");
28 return TASK_TYPE_NONE;
29 }
30 return realTask->curTask->getCurTaskType();
31 }
32
DestroyIsoClientTask(struct SubTaskBaseT * task)33 static void DestroyIsoClientTask(struct SubTaskBaseT *task)
34 {
35 IsoClientTask *innerTask = (IsoClientTask *)task;
36 if (innerTask == NULL) {
37 return;
38 }
39 DestroyIsoParams(&(innerTask->params));
40 if (innerTask->curTask != NULL) {
41 innerTask->curTask->destroyTask(innerTask->curTask);
42 }
43 HcFree(innerTask);
44 }
45
CreateNextTask(IsoClientTask * realTask,const CJson * in,CJson * out,int32_t * status)46 static int CreateNextTask(IsoClientTask *realTask, const CJson *in, CJson *out, int32_t *status)
47 {
48 int res = HC_SUCCESS;
49 switch (realTask->params.opCode) {
50 case OP_BIND:
51 if (realTask->curTask->getCurTaskType() == TASK_TYPE_BIND_LITE_EXCHANGE) {
52 LOGI("Bind exchange task end successfully.");
53 *status = FINISH;
54 return HC_SUCCESS;
55 }
56 realTask->curTask->destroyTask(realTask->curTask);
57 realTask->curTask = CreateClientBindExchangeTask(&(realTask->params), in, out, status);
58 if (realTask->curTask == NULL) {
59 LOGE("CreateBindExchangeTask failed.");
60 return HC_ERROR;
61 }
62 break;
63 case AUTHENTICATE:
64 res = GenEncResult(&(realTask->params), ISO_RESULT_CONFIRM_CMD, out, RESULT_AAD, true);
65 if (res != HC_SUCCESS) {
66 LOGE("GenEncResult failed, res:%d", res);
67 return res;
68 }
69 LOGI("Authenticate task end successfully.");
70 *status = FINISH;
71 break;
72 default:
73 LOGE("Unsupported opCode: %d.", realTask->params.opCode);
74 res = HC_ERR_NOT_SUPPORT;
75 }
76 return res;
77 }
78
Process(struct SubTaskBaseT * task,const CJson * in,CJson * out,int32_t * status)79 static int Process(struct SubTaskBaseT *task, const CJson *in, CJson *out, int32_t *status)
80 {
81 IsoClientTask *realTask = (IsoClientTask *)task;
82 if (realTask->curTask == NULL) {
83 LOGE("CurTask is null.");
84 return HC_ERROR;
85 }
86 int res = realTask->curTask->process(realTask->curTask, &(realTask->params), in, out, status);
87 if (res != HC_SUCCESS) {
88 LOGE("CurTask process failed, res: %x.", res);
89 return res;
90 }
91 if (*status != FINISH) {
92 return res;
93 }
94 return CreateNextTask(realTask, in, out, status);
95 }
96
CreateIsoClientTask(const CJson * in)97 SubTaskBase *CreateIsoClientTask(const CJson *in)
98 {
99 IsoClientTask *task = (IsoClientTask *)HcMalloc(sizeof(IsoClientTask), 0);
100 if (task == NULL) {
101 LOGE("Malloc for IsoClientTask failed.");
102 return NULL;
103 }
104
105 task->taskBase.getTaskType = GetIsoClientTaskType;
106 task->taskBase.destroyTask = DestroyIsoClientTask;
107 task->taskBase.process = Process;
108
109 int res = InitIsoParams(&(task->params), in);
110 if (res != HC_SUCCESS) {
111 LOGE("InitIsoParams failed, res: %x.", res);
112 DestroyIsoClientTask((struct SubTaskBaseT *)task);
113 return NULL;
114 }
115
116 task->curTask = CreateProtocolClientTask();
117 if (task->curTask == NULL) {
118 LOGE("CreateProtocolClientTask failed.");
119 DestroyIsoClientTask((struct SubTaskBaseT *)task);
120 return NULL;
121 }
122 return (SubTaskBase *)task;
123 }
124