• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &paramLen);
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