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