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