1 /*
2 * Copyright (C) 2023 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12
13 #include <cstdint>
14 #include <cstdio>
15 #include <ctime>
16 #include <securec.h>
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include <sys/ioctl.h>
20 #include <dlfcn.h>
21 #include "tee_client_type.h"
22 #include "tee_log.h"
23 #include "tc_ns_client.h"
24 #include "tui_file.h"
25 #include "tui_threadwork.h"
26 #ifdef LOG_TAG
27 #undef LOG_TAG
28 #endif
29 #define LOG_TAG "tee_tui_daemon"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 static const int32_t EVENT_PARAMS_LEN = 16;
36 static const int32_t PARAMS_INPUT_LEN = 10;
37 static const uint32_t SLEEP_TIME = 1;
38 static const int32_t RETRY_TIMES = 20;
39 static FILE *g_mTuiFp = nullptr;
40
41 enum {
42 TUI_DAEMON_TUI_INIT = 1,
43 TUI_DAEMON_TUI_START = 2,
44 TUI_DAEMON_TUI_END = 3
45 };
46
GetTuiDevFd()47 static FILE *GetTuiDevFd()
48 {
49 FILE *tuiFp = nullptr;
50 int32_t retryTimes = 0;
51 while (tuiFp == nullptr) {
52 tuiFp = GetTuiCStateFp(TUI_LISTEN_PATH, "rb");
53 if (tuiFp == nullptr) {
54 retryTimes++;
55 sleep(SLEEP_TIME);
56 if (retryTimes > RETRY_TIMES) {
57 tloge("can not open %" PUBLIC "s, %" PUBLIC "d", TUI_LISTEN_PATH, errno);
58 return nullptr;
59 }
60 }
61 }
62 return tuiFp;
63 }
64
GetEvent(char * eventParam,int * paramLen)65 int32_t GetEvent(char *eventParam, int *paramLen)
66 {
67 if (eventParam == nullptr || paramLen == nullptr) {
68 return -1;
69 }
70
71 int32_t readSize = 0;
72
73 if (g_mTuiFp == nullptr) {
74 g_mTuiFp = GetTuiDevFd();
75 if (g_mTuiFp == nullptr) {
76 tloge("get TuiFd failed\n");
77 return -1;
78 }
79 }
80
81 fseek(g_mTuiFp, 0, SEEK_SET);
82 tlogi("Tui SEEK_SET ok\n");
83 readSize = GetEventParamFromTui(eventParam, 1, *paramLen, g_mTuiFp);
84 if (readSize <= 0) {
85 tloge("TUI read state fail %" PUBLIC "d, len=%" PUBLIC "d\n", ferror(g_mTuiFp), readSize);
86 return -1;
87 } else {
88 *(eventParam + readSize) = '\0';
89 tlogi("get c_state len is %" PUBLIC "d\n", readSize);
90 }
91
92 *paramLen = readSize;
93
94 return 0;
95 }
96
97 static void *g_dlHandle = nullptr;
98 bool (*g_tuiDaemonFunc)(int) = nullptr;
99 bool (*g_tuiIsFoldableFunc)() = nullptr;
TuiDaemonInit(void)100 static bool TuiDaemonInit(void)
101 {
102 tlogi("tui daemon init\n");
103 if (g_dlHandle != nullptr) {
104 tlogw("tui daemon handle is opened");
105 return true;
106 }
107
108 #if defined(__LP64__)
109 g_dlHandle = dlopen("/system/lib64/libcadaemon_tui.so", RTLD_LAZY);
110 #else
111 g_dlHandle = dlopen("/system/lib/libcadaemon_tui.so", RTLD_LAZY);
112 #endif
113 if (g_dlHandle == nullptr) {
114 tlogi("tui daemon handle is null");
115 return false;
116 }
117
118 g_tuiDaemonFunc = (bool(*)(int))dlsym(g_dlHandle, "TeeTuiDaemonWork");
119 g_tuiIsFoldableFunc = (bool(*)())dlsym(g_dlHandle, "TeeTuiIsFoldable");
120 if (g_tuiDaemonFunc == nullptr || g_tuiIsFoldableFunc == nullptr) {
121 tloge("dlsym is null\n");
122 (void)dlclose(g_dlHandle);
123 g_dlHandle = nullptr;
124 return false;
125 }
126 tlogi("tui daemon init success\n");
127 return true;
128 }
129
TuiDaemonClean(void)130 static void TuiDaemonClean(void)
131 {
132 tlogi("tui daemon clean\n");
133 if (g_dlHandle == nullptr) {
134 tlogw("tui daemon handle is not opened");
135 return;
136 }
137
138 g_tuiDaemonFunc = nullptr;
139 g_tuiIsFoldableFunc = nullptr;
140 (void)dlclose(g_dlHandle);
141 g_dlHandle = nullptr;
142 }
143
HandleEvent(const char * eventParam,int32_t paramLen)144 void HandleEvent(const char *eventParam, int32_t paramLen)
145 {
146 if (eventParam == nullptr || paramLen == 0) {
147 return;
148 }
149
150 const char *str = eventParam;
151 if (strncmp(str, "unused", sizeof("unused")) == 0) {
152 tlogi("send false state to frame 1\n");
153 if (g_tuiDaemonFunc != nullptr) {
154 (void)g_tuiDaemonFunc(TUI_DAEMON_TUI_END);
155 if (!g_tuiIsFoldableFunc()) {
156 TuiDaemonClean();
157 }
158 }
159 } else if (strncmp(str, "config", sizeof("config")) == 0) {
160 tlogi("send true state to frame 1\n");
161 if (TuiDaemonInit()) {
162 (void)g_tuiDaemonFunc(TUI_DAEMON_TUI_START);
163 }
164 } else {
165 tlogi("do not need send data\n");
166 }
167
168 return;
169 }
170
171 #define TUI_INIT_RETRY_TIMES 10
TeeTuiThreadWork(void)172 void TeeTuiThreadWork(void)
173 {
174 tlogi("tee tui thread work\n");
175 uint32_t count = 0;
176 bool initFlag = false;
177 while (count++ <= TUI_INIT_RETRY_TIMES) {
178 if (TuiDaemonInit()) {
179 initFlag = g_tuiDaemonFunc(TUI_DAEMON_TUI_INIT);
180 TuiDaemonClean();
181 }
182
183 if (initFlag) {
184 tlogi("tee tui daemon init success\n");
185 break;
186 }
187 tlogi("tee tui daemon init retry %" PUBLIC "d \n", count);
188 sleep(2); // 2 : sleep 2s
189 }
190
191 do {
192 char eventParam[EVENT_PARAMS_LEN] = { 0 };
193 int32_t paramLen = PARAMS_INPUT_LEN;
194 int32_t ret = GetEvent(eventParam, ¶mLen);
195 if (ret == 0) {
196 HandleEvent(eventParam, paramLen);
197 } else {
198 tloge("get event failed, something wrong\n");
199 break;
200 }
201 } while (true);
202
203 tlogi("tui thread loop stop\n");
204 return;
205 }
206
207 #ifdef __cplusplus
208 }
209 #endif
210