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 "tee_client_type.h"
21 #include "tee_log.h"
22 #include "tc_ns_client.h"
23 #include "tui_event.h"
24 
25 #ifdef LOG_TAG
26 #undef LOG_TAG
27 #endif
28 #define LOG_TAG "tee_tui_daemon"
29 
30 using namespace std;
31 
32 TUIEvent *g_tuiEventInstance = nullptr;
33 TUIDaemon *g_tuiDaemon = nullptr;
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 static const int32_t EVENT_PARAMS_LEN = 16;
40 static const int32_t PARAMS_INPUT_LEN = 10;
41 static const uint32_t TUI_POLL_FOLD   = 26;
42 static const uint32_t SLEEP_TIME = 1;
43 static const int32_t RETRY_TIMES = 20;
44 static FILE *g_mTuiFp = nullptr;
45 
GetTuiDevFd()46 static FILE *GetTuiDevFd()
47 {
48     FILE *tuiFp = nullptr;
49     int32_t retryTimes = 0;
50 
51     while (tuiFp == nullptr) {
52         tuiFp = fopen(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 static int32_t GetEvent(char *eventParam, int *paramLen)
66 {
67     int32_t readSize = 0;
68 
69     if (g_mTuiFp == nullptr) {
70         g_mTuiFp = GetTuiDevFd();
71         if (g_mTuiFp == nullptr) {
72             tloge("get TuiFd failed\n");
73             return -1;
74         }
75     }
76 
77     fseek(g_mTuiFp, 0, SEEK_SET);
78     tlogi("Tui SEEK_SET ok\n");
79     readSize = fread(eventParam, 1, *paramLen, g_mTuiFp);
80     if (readSize <= 0) {
81         tloge("TUI read state fail %{public}d, len=%{public}d\n", ferror(g_mTuiFp), readSize);
82         fclose(g_mTuiFp);
83         g_mTuiFp = nullptr;
84         return -1;
85     } else {
86         *(eventParam + readSize) = '\0';
87         tlogi("get c_state len is %{public}d\n", readSize);
88     }
89 
90     *paramLen = readSize;
91 
92     return 0;
93 }
94 
HandleEvent(const char * eventParam,int32_t paramLen)95 static void HandleEvent(const char *eventParam, int32_t paramLen)
96 {
97     const char *str = eventParam;
98 
99     if (strncmp(str, "unused", sizeof("unused")) == 0) {
100         tlogi("send false state to frame \n");
101         g_tuiEventInstance->TUIDealWithEvent(false);
102     } else if (strncmp(str, "config", sizeof("config")) == 0) {
103         tlogi("send true state to frame \n");
104         g_tuiEventInstance->TUIDealWithEvent(true);
105     } else {
106         tlogi("do not need send data\n");
107     }
108 
109     return;
110 }
111 
ThreadInit()112 static void ThreadInit()
113 {
114     g_tuiDaemon = new TUIDaemon();
115     g_tuiDaemon->TuiDaemonInit();
116     g_tuiEventInstance = TUIEvent::GetInstance();
117     g_tuiEventInstance->TUIGetPannelInfo();
118     g_tuiEventInstance->TUISendCmd(TUI_POLL_FOLD);
119 }
120 
ThreadClear()121 static void ThreadClear()
122 {
123     if (g_mTuiFp != nullptr) {
124         fclose(g_mTuiFp);
125         g_mTuiFp = nullptr;
126     }
127 
128     if (g_tuiDaemon != nullptr) {
129         delete g_tuiDaemon;
130         g_tuiDaemon = nullptr;
131     }
132 }
133 
TuiThreadLoop()134 static void TuiThreadLoop()
135 {
136     tlogi("Tui Thread Loop Start\n");
137     g_mTuiFp = GetTuiDevFd();
138     if (g_mTuiFp == nullptr) {
139         tloge("failed to get c_state, stop ThreadLoop\n");
140         return;
141     }
142 
143     ThreadInit();
144 
145     do {
146         char eventParam[EVENT_PARAMS_LEN];
147         int32_t paramLen = PARAMS_INPUT_LEN;
148         int32_t ret = GetEvent(eventParam, &paramLen);
149         if (ret == 0) {
150             HandleEvent(eventParam, paramLen);
151         } else {
152             tloge("get event failed, something wrong\n");
153             break;
154         }
155     } while (true);
156     tlogi("Tui Thread Loop stop\n");
157     ThreadClear();
158 }
159 
TeeTuiThreadWork(void)160 void TeeTuiThreadWork(void)
161 {
162     TuiThreadLoop();
163     return;
164 }
165 
166 #ifdef __cplusplus
167 }
168 #endif