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