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