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_server_task.h"
17 #include "hc_log.h"
18 #include "hc_types.h"
19 #include "iso_server_bind_exchange_task.h"
20 #include "iso_server_protocol_task.h"
21 #include "iso_task_common.h"
22 
GetIsoServerTaskType(const struct SubTaskBaseT * task)23 static int GetIsoServerTaskType(const struct SubTaskBaseT *task)
24 {
25     IsoServerTask *realTask = (IsoServerTask *)task;
26     if (realTask->curTask == NULL) {
27         LOGE("CurTask is null.");
28         return TASK_TYPE_NONE;
29     }
30     return realTask->curTask->getCurTaskType();
31 }
32 
DestroyIsoServerTask(struct SubTaskBaseT * task)33 static void DestroyIsoServerTask(struct SubTaskBaseT *task)
34 {
35     IsoServerTask *innerTask = (IsoServerTask *)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(IsoServerTask * realTask,const CJson * in,CJson * out,int32_t * status)46 static int CreateNextTask(IsoServerTask *realTask, const CJson *in, CJson *out, int32_t *status)
47 {
48     int32_t message = 0;
49     if (GetIntFromJson(in, FIELD_MESSAGE, &message) != 0) {
50         LOGE("Get message code failed.");
51         return HC_ERR_JSON_GET;
52     }
53     int res = HC_SUCCESS;
54     switch (realTask->params.opCode) {
55         case OP_BIND:
56             if (message != ISO_CLIENT_BIND_EXCHANGE_CMD) {
57                 LOGI("The message is repeated, ignore it message: %d.", message);
58                 *status = IGNORE_MSG;
59                 break;
60             }
61             realTask->curTask = CreateServerBindExchangeTask(&(realTask->params), in, out, status);
62             if (realTask->curTask == NULL) {
63                 LOGE("CreateBindExchangeTask failed");
64                 return HC_ERROR;
65             }
66             break;
67         case AUTHENTICATE:
68             if (message != ISO_RESULT_CONFIRM_CMD) {
69                 LOGI("The message is repeated, ignore it message: %d.", message);
70                 *status = IGNORE_MSG;
71                 break;
72             }
73             if ((res = CheckEncResult(&(realTask->params), in, RESULT_AAD)) != 0) {
74                 LOGE("CheckEncResult failed, res: %d.", res);
75                 break;
76             }
77             if ((res = SendResultToFinalSelf(&(realTask->params), out, true)) != 0) {
78                 LOGE("SendResultToFinalSelf failed, res: %d.", res);
79                 break;
80             }
81             LOGD("Authenticate task end.");
82             *status = FINISH;
83             break;
84         default:
85             LOGE("Unsupported opCode: %d.", realTask->params.opCode);
86             res = HC_ERR_NOT_SUPPORT;
87     }
88 
89     return res;
90 }
91 
Process(struct SubTaskBaseT * task,const CJson * in,CJson * out,int32_t * status)92 static int Process(struct SubTaskBaseT *task, const CJson *in, CJson *out, int32_t *status)
93 {
94     IsoServerTask *realTask = (IsoServerTask *)task;
95     if (realTask->curTask != NULL) {
96         int res = realTask->curTask->process(realTask->curTask, &(realTask->params), in, out, status);
97         if (res != HC_SUCCESS) {
98             LOGE("CurTask processes failed, res: %x.", res);
99         }
100         if (*status == FINISH && (realTask->curTask->getCurTaskType() == TASK_TYPE_ISO_PROTOCOL)) {
101             realTask->curTask->destroyTask(realTask->curTask);
102             realTask->curTask = NULL;
103             *status = CONTINUE;
104         }
105         return res;
106     } else {
107         return CreateNextTask(realTask, in, out, status);
108     }
109 }
110 
CreateIsoServerTask(const CJson * in)111 SubTaskBase *CreateIsoServerTask(const CJson *in)
112 {
113     IsoServerTask *task = (IsoServerTask *)HcMalloc(sizeof(IsoServerTask), 0);
114     if (task == NULL) {
115         LOGE("Malloc for IsoServerTask failed.");
116         return NULL;
117     }
118 
119     task->taskBase.getTaskType = GetIsoServerTaskType;
120     task->taskBase.destroyTask = DestroyIsoServerTask;
121     task->taskBase.process = Process;
122 
123     int res = InitIsoParams(&(task->params), in);
124     if (res != 0) {
125         LOGE("InitIsoParams failed, res: %x.", res);
126         DestroyIsoServerTask((struct SubTaskBaseT *)task);
127         return NULL;
128     }
129 
130     task->curTask = CreateProtocolServerTask();
131     if (task->curTask == NULL) {
132         LOGE("CreateProtocolServerTask failed.");
133         DestroyIsoServerTask((struct SubTaskBaseT *)task);
134         return NULL;
135     }
136     return (SubTaskBase *)task;
137 }
138