1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci */
15cc290419Sopenharmony_ci
16cc290419Sopenharmony_ci#include <grp.h>
17cc290419Sopenharmony_ci#include <pwd.h>
18cc290419Sopenharmony_ci#include <unistd.h>
19cc290419Sopenharmony_ci#include <sys/types.h>
20cc290419Sopenharmony_ci#include "daemon_common.h"
21cc290419Sopenharmony_ci#if defined(SURPPORT_SELINUX)
22cc290419Sopenharmony_ci#include "selinux/selinux.h"
23cc290419Sopenharmony_ci#endif
24cc290419Sopenharmony_ciusing namespace Hdc;
25cc290419Sopenharmony_ci
26cc290419Sopenharmony_cistatic bool g_enableUsb = false;
27cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
28cc290419Sopenharmony_cistatic bool g_enableUart = false;
29cc290419Sopenharmony_ci#endif
30cc290419Sopenharmony_cistatic bool g_enableTcp = false;
31cc290419Sopenharmony_ci#ifdef HDC_EMULATOR
32cc290419Sopenharmony_cistatic bool g_enableBridge = false;
33cc290419Sopenharmony_ci#endif
34cc290419Sopenharmony_cistatic bool g_backgroundRun = false;
35cc290419Sopenharmony_cinamespace Hdc {
36cc290419Sopenharmony_cibool RestartDaemon(bool forkchild)
37cc290419Sopenharmony_ci{
38cc290419Sopenharmony_ci    char path[256] = "";
39cc290419Sopenharmony_ci    size_t nPathSize = 256;
40cc290419Sopenharmony_ci    uv_exepath(path, &nPathSize);
41cc290419Sopenharmony_ci    execl(path, "hdcd", forkchild ? "-forkchild" : nullptr, nullptr);
42cc290419Sopenharmony_ci    return true;
43cc290419Sopenharmony_ci}
44cc290419Sopenharmony_ci
45cc290419Sopenharmony_civoid GetTCPChannelMode(void)
46cc290419Sopenharmony_ci{
47cc290419Sopenharmony_ci    string modeValue;
48cc290419Sopenharmony_ci    if (SystemDepend::GetDevItem("persist.hdc.mode.tcp", modeValue)) {
49cc290419Sopenharmony_ci        g_enableTcp = (modeValue == "enable");
50cc290419Sopenharmony_ci        WRITE_LOG(LOG_INFO, "Property %s TCP", modeValue.c_str());
51cc290419Sopenharmony_ci    }
52cc290419Sopenharmony_ci    modeValue.clear();
53cc290419Sopenharmony_ci    if (SystemDepend::GetDevItem("persist.hdc.mode.usb", modeValue)) {
54cc290419Sopenharmony_ci        g_enableUsb = (modeValue == "enable");
55cc290419Sopenharmony_ci        WRITE_LOG(LOG_INFO, "Property %s USB", modeValue.c_str());
56cc290419Sopenharmony_ci    }
57cc290419Sopenharmony_ci    return;
58cc290419Sopenharmony_ci}
59cc290419Sopenharmony_ci
60cc290419Sopenharmony_cibool ForkChildCheck(int argc, const char *argv[])
61cc290419Sopenharmony_ci{
62cc290419Sopenharmony_ci    // hdcd        #service start foreground
63cc290419Sopenharmony_ci    // hdcd -b     #service start backgroundRun
64cc290419Sopenharmony_ci    // hdcd -fork  #fork
65cc290419Sopenharmony_ci    Base::PrintMessage("Background mode, persist.hdc.mode");
66cc290419Sopenharmony_ci    string workMode;
67cc290419Sopenharmony_ci    SystemDepend::GetDevItem("persist.hdc.mode", workMode);
68cc290419Sopenharmony_ci    workMode = Base::Trim(workMode);
69cc290419Sopenharmony_ci    if (workMode == "all") {
70cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Property enable USB and TCP");
71cc290419Sopenharmony_ci        g_enableUsb = true;
72cc290419Sopenharmony_ci        g_enableTcp = true;
73cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
74cc290419Sopenharmony_ci        g_enableUart = true;
75cc290419Sopenharmony_ci#endif
76cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
77cc290419Sopenharmony_ci    } else if (workMode == CMDSTR_TMODE_UART) {
78cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Property enable UART");
79cc290419Sopenharmony_ci        g_enableUart = true;
80cc290419Sopenharmony_ci#endif
81cc290419Sopenharmony_ci#ifdef HDC_EMULATOR
82cc290419Sopenharmony_ci    } else if (workMode == CMDSTR_TMODE_BRIDGE || workMode.empty()) {
83cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Property enable Bridge");
84cc290419Sopenharmony_ci        g_enableBridge = true;
85cc290419Sopenharmony_ci#endif
86cc290419Sopenharmony_ci    } else if (workMode == CMDSTR_TMODE_USB || workMode == CMDSTR_TMODE_TCP) {
87cc290419Sopenharmony_ci        // for tcp and usb, we use persist.hdc.mode.tcp and persist.hdc.mode.usb to control
88cc290419Sopenharmony_ci        GetTCPChannelMode();
89cc290419Sopenharmony_ci    } else {
90cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Default USB mode");
91cc290419Sopenharmony_ci        g_enableUsb = true;
92cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
93cc290419Sopenharmony_ci        WRITE_LOG(LOG_DEBUG, "Default UART mode");
94cc290419Sopenharmony_ci        g_enableUart = true;
95cc290419Sopenharmony_ci#endif
96cc290419Sopenharmony_ci    }
97cc290419Sopenharmony_ci    if (argc == CMD_ARG1_COUNT) {
98cc290419Sopenharmony_ci        if (!strcmp(argv[1], "-forkchild")) {
99cc290419Sopenharmony_ci            g_backgroundRun = false;  // forkchild,Forced foreground
100cc290419Sopenharmony_ci        } else if (!strcmp(argv[1], "-b")) {
101cc290419Sopenharmony_ci            g_backgroundRun = true;
102cc290419Sopenharmony_ci        }
103cc290419Sopenharmony_ci    }
104cc290419Sopenharmony_ci    return true;
105cc290419Sopenharmony_ci}
106cc290419Sopenharmony_ci
107cc290419Sopenharmony_cistatic size_t CheckUvThreadConfig()
108cc290419Sopenharmony_ci{
109cc290419Sopenharmony_ci    return SystemDepend::GetDevUint("persist.hdc.uv.threads", SIZE_THREAD_POOL);
110cc290419Sopenharmony_ci}
111cc290419Sopenharmony_ci
112cc290419Sopenharmony_ciint BackgroundRun()
113cc290419Sopenharmony_ci{
114cc290419Sopenharmony_ci    pid_t pc = fork();  // create process as daemon process
115cc290419Sopenharmony_ci    if (pc < 0) {
116cc290419Sopenharmony_ci        return -1;
117cc290419Sopenharmony_ci    } else if (!pc) {
118cc290419Sopenharmony_ci        int i;
119cc290419Sopenharmony_ci        const int MAX_NUM = 64;
120cc290419Sopenharmony_ci        for (i = 0; i < MAX_NUM; ++i) {
121cc290419Sopenharmony_ci            int fd = i;
122cc290419Sopenharmony_ci            Base::CloseFd(fd);
123cc290419Sopenharmony_ci        }
124cc290419Sopenharmony_ci        RestartDaemon(true);
125cc290419Sopenharmony_ci    } else {  // >0 orig process
126cc290419Sopenharmony_ci    }
127cc290419Sopenharmony_ci    return 0;
128cc290419Sopenharmony_ci}
129cc290419Sopenharmony_ci
130cc290419Sopenharmony_cistring DaemonUsage()
131cc290419Sopenharmony_ci{
132cc290419Sopenharmony_ci    string ret = "";
133cc290419Sopenharmony_ci    ret = "\n                         Harmony device connector daemon(HDCD) Usage: hdcd [options]...\n\n"
134cc290419Sopenharmony_ci          "\n"
135cc290419Sopenharmony_ci          "general options:\n"
136cc290419Sopenharmony_ci          " -h                            - Print help\n"
137cc290419Sopenharmony_ci          " -l 0-5                        - Print runtime log\n"
138cc290419Sopenharmony_ci          "\n"
139cc290419Sopenharmony_ci          "daemon mode options:\n"
140cc290419Sopenharmony_ci          " -b                            - Daemon run in background/fork mode\n"
141cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
142cc290419Sopenharmony_ci          " -i                            - Enable UART mode\n"
143cc290419Sopenharmony_ci#endif
144cc290419Sopenharmony_ci          " -u                            - Enable USB mode\n"
145cc290419Sopenharmony_ci          " -t                            - Enable TCP mode\n";
146cc290419Sopenharmony_ci    return ret;
147cc290419Sopenharmony_ci}
148cc290419Sopenharmony_ci
149cc290419Sopenharmony_cibool GetDaemonCommandlineOptions(int argc, const char *argv[])
150cc290419Sopenharmony_ci{
151cc290419Sopenharmony_ci    int ch;
152cc290419Sopenharmony_ci    // hdcd -l4 ...
153cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "Foreground cli-mode");
154cc290419Sopenharmony_ci    // Both settings are running with parameters
155cc290419Sopenharmony_ci    while ((ch = getopt(argc, const_cast<char *const *>(argv), "utl:")) != -1) {
156cc290419Sopenharmony_ci        switch (ch) {
157cc290419Sopenharmony_ci            case 'l': {
158cc290419Sopenharmony_ci                int logLevel = atoi(optarg);
159cc290419Sopenharmony_ci                if (logLevel < 0 || logLevel > LOG_LAST) {
160cc290419Sopenharmony_ci                    WRITE_LOG(LOG_DEBUG, "Loglevel error!\n");
161cc290419Sopenharmony_ci                    return -1;
162cc290419Sopenharmony_ci                }
163cc290419Sopenharmony_ci                Base::SetLogLevel(logLevel);
164cc290419Sopenharmony_ci                break;
165cc290419Sopenharmony_ci            }
166cc290419Sopenharmony_ci            case 'u': {
167cc290419Sopenharmony_ci                Base::PrintMessage("Option USB enabled");
168cc290419Sopenharmony_ci                g_enableUsb = true;
169cc290419Sopenharmony_ci                break;
170cc290419Sopenharmony_ci            }
171cc290419Sopenharmony_ci            case 't': {
172cc290419Sopenharmony_ci                Base::PrintMessage("Option TCP enabled");
173cc290419Sopenharmony_ci                g_enableTcp = true;
174cc290419Sopenharmony_ci                break;
175cc290419Sopenharmony_ci            }
176cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
177cc290419Sopenharmony_ci            case 'i': { // enable uart
178cc290419Sopenharmony_ci                Base::PrintMessage("Parament Enable UART");
179cc290419Sopenharmony_ci                g_enableUart = true;
180cc290419Sopenharmony_ci                break;
181cc290419Sopenharmony_ci            }
182cc290419Sopenharmony_ci#endif
183cc290419Sopenharmony_ci            default:
184cc290419Sopenharmony_ci                Base::PrintMessage("Option:%c non-supported!", ch);
185cc290419Sopenharmony_ci                exit(0);
186cc290419Sopenharmony_ci                break;
187cc290419Sopenharmony_ci        }
188cc290419Sopenharmony_ci    }
189cc290419Sopenharmony_ci    return true;
190cc290419Sopenharmony_ci}
191cc290419Sopenharmony_ci
192cc290419Sopenharmony_cibool DropRootPrivileges()
193cc290419Sopenharmony_ci{
194cc290419Sopenharmony_ci    int ret;
195cc290419Sopenharmony_ci    const char *userName = "shell";
196cc290419Sopenharmony_ci    vector<const char *> groupsNames = { "shell", "log", "readproc", "file_manager" };
197cc290419Sopenharmony_ci    struct passwd *user;
198cc290419Sopenharmony_ci    gid_t *gids = nullptr;
199cc290419Sopenharmony_ci
200cc290419Sopenharmony_ci    user = getpwnam(userName);
201cc290419Sopenharmony_ci    if (user == nullptr) {
202cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "getpwuid %s fail, %s", userName, strerror(errno));
203cc290419Sopenharmony_ci        return false;
204cc290419Sopenharmony_ci    }
205cc290419Sopenharmony_ci
206cc290419Sopenharmony_ci    gids = static_cast<gid_t *>(calloc(groupsNames.size(), sizeof(gid_t)));
207cc290419Sopenharmony_ci    if (gids == nullptr) {
208cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "calloc fail");
209cc290419Sopenharmony_ci        return false;
210cc290419Sopenharmony_ci    }
211cc290419Sopenharmony_ci
212cc290419Sopenharmony_ci    for (size_t i = 0; i < groupsNames.size(); i++) {
213cc290419Sopenharmony_ci        struct group *group = getgrnam(groupsNames[i]);
214cc290419Sopenharmony_ci        if (group == nullptr) {
215cc290419Sopenharmony_ci            WRITE_LOG(LOG_FATAL, "calloc fail");
216cc290419Sopenharmony_ci            continue;
217cc290419Sopenharmony_ci        }
218cc290419Sopenharmony_ci        gids[i] = group->gr_gid;
219cc290419Sopenharmony_ci    }
220cc290419Sopenharmony_ci
221cc290419Sopenharmony_ci    ret = setuid(user->pw_uid);
222cc290419Sopenharmony_ci    if (ret) {
223cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "setuid %s fail, %s", userName, strerror(errno));
224cc290419Sopenharmony_ci        free(gids);
225cc290419Sopenharmony_ci        return false;
226cc290419Sopenharmony_ci    }
227cc290419Sopenharmony_ci
228cc290419Sopenharmony_ci    ret = setgid(user->pw_gid);
229cc290419Sopenharmony_ci    if (ret) {
230cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "setgid %s fail, %s", userName, strerror(errno));
231cc290419Sopenharmony_ci        free(gids);
232cc290419Sopenharmony_ci        return false;
233cc290419Sopenharmony_ci    }
234cc290419Sopenharmony_ci
235cc290419Sopenharmony_ci    ret = setgroups(groupsNames.size(), gids);
236cc290419Sopenharmony_ci    if (ret) {
237cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "setgroups %s fail, %s", userName, strerror(errno));
238cc290419Sopenharmony_ci        free(gids);
239cc290419Sopenharmony_ci        return false;
240cc290419Sopenharmony_ci    }
241cc290419Sopenharmony_ci
242cc290419Sopenharmony_ci    free(gids);
243cc290419Sopenharmony_ci#if defined(SURPPORT_SELINUX)
244cc290419Sopenharmony_ci    if (setcon("u:r:hdcd:s0") != 0) {
245cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "setcon fail, errno %s", userName, strerror(errno));
246cc290419Sopenharmony_ci    }
247cc290419Sopenharmony_ci#endif
248cc290419Sopenharmony_ci    return true;
249cc290419Sopenharmony_ci}
250cc290419Sopenharmony_ci
251cc290419Sopenharmony_cibool NeedDropRootPrivileges()
252cc290419Sopenharmony_ci{
253cc290419Sopenharmony_ci    string rootMode;
254cc290419Sopenharmony_ci    string debugMode;
255cc290419Sopenharmony_ci    SystemDepend::GetDevItem("const.debuggable", debugMode);
256cc290419Sopenharmony_ci    SystemDepend::GetDevItem("persist.hdc.root", rootMode);
257cc290419Sopenharmony_ci    if (debugMode == "1") {
258cc290419Sopenharmony_ci        if (rootMode == "1") {
259cc290419Sopenharmony_ci            int rc = setuid(0);
260cc290419Sopenharmony_ci            if (rc != 0) {
261cc290419Sopenharmony_ci                char buffer[BUF_SIZE_DEFAULT] = { 0 };
262cc290419Sopenharmony_ci                strerror_r(errno, buffer, BUF_SIZE_DEFAULT);
263cc290419Sopenharmony_ci                WRITE_LOG(LOG_FATAL, "setuid(0) fail %s", buffer);
264cc290419Sopenharmony_ci            }
265cc290419Sopenharmony_ci            WRITE_LOG(LOG_DEBUG, "Root run rc:%d", rc);
266cc290419Sopenharmony_ci        } else if (rootMode == "0") {
267cc290419Sopenharmony_ci            if (getuid() == 0) {
268cc290419Sopenharmony_ci                return DropRootPrivileges();
269cc290419Sopenharmony_ci            }
270cc290419Sopenharmony_ci        }
271cc290419Sopenharmony_ci        // default keep root
272cc290419Sopenharmony_ci    } else {
273cc290419Sopenharmony_ci        return DropRootPrivileges();
274cc290419Sopenharmony_ci    }
275cc290419Sopenharmony_ci    return true;
276cc290419Sopenharmony_ci}
277cc290419Sopenharmony_ci} // namespace Hdc
278cc290419Sopenharmony_ci
279cc290419Sopenharmony_ci#ifndef UNIT_TEST
280cc290419Sopenharmony_ci// daemon running with default behavior. options also can be given to custom its behavior including b/t/u/l etc.
281cc290419Sopenharmony_ciint main(int argc, const char *argv[])
282cc290419Sopenharmony_ci{
283cc290419Sopenharmony_ci#ifdef CONFIG_USE_JEMALLOC_DFX_INIF
284cc290419Sopenharmony_ci    mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE);
285cc290419Sopenharmony_ci    mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE);
286cc290419Sopenharmony_ci#endif
287cc290419Sopenharmony_ci#ifndef UPDATER_MODE
288cc290419Sopenharmony_ci    string developerMode;
289cc290419Sopenharmony_ci    SystemDepend::GetDevItem("const.security.developermode.state", developerMode);
290cc290419Sopenharmony_ci    if (developerMode != "true") {
291cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "non developer mode, hdcd does not start");
292cc290419Sopenharmony_ci        return -1;
293cc290419Sopenharmony_ci    }
294cc290419Sopenharmony_ci#endif
295cc290419Sopenharmony_ci    // check property
296cc290419Sopenharmony_ci    if (argc == CMD_ARG1_COUNT && !strcmp(argv[1], "-h")) {
297cc290419Sopenharmony_ci        string usage = DaemonUsage();
298cc290419Sopenharmony_ci        fprintf(stderr, "%s", usage.c_str());
299cc290419Sopenharmony_ci        return 0;
300cc290419Sopenharmony_ci    }
301cc290419Sopenharmony_ci    if (argc == CMD_ARG1_COUNT && !strcmp(argv[1], "-v")) {
302cc290419Sopenharmony_ci        string ver = Hdc::Base::GetVersion();
303cc290419Sopenharmony_ci        fprintf(stderr, "%s\n", ver.c_str());
304cc290419Sopenharmony_ci        return 0;
305cc290419Sopenharmony_ci    }
306cc290419Sopenharmony_ci    if (argc == 1 || (argc == CMD_ARG1_COUNT && (!strcmp(argv[1], "-forkchild") || !strcmp(argv[1], "-b")))) {
307cc290419Sopenharmony_ci        ForkChildCheck(argc, argv);
308cc290419Sopenharmony_ci    } else {
309cc290419Sopenharmony_ci        GetDaemonCommandlineOptions(argc, argv);
310cc290419Sopenharmony_ci    }
311cc290419Sopenharmony_ci    if (!g_enableTcp && !g_enableUsb) {
312cc290419Sopenharmony_ci#ifdef HDC_EMULATOR
313cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
314cc290419Sopenharmony_ci        if (!g_enableBridge && !g_enableUart) {
315cc290419Sopenharmony_ci            Base::PrintMessage("TCP, USB, Bridge and Uart are disable, cannot run continue\n");
316cc290419Sopenharmony_ci            return -1;
317cc290419Sopenharmony_ci        }
318cc290419Sopenharmony_ci#else
319cc290419Sopenharmony_ci        if (!g_enableBridge) {
320cc290419Sopenharmony_ci            Base::PrintMessage("Both TCP, Bridge and USB are disable, cannot run continue\n");
321cc290419Sopenharmony_ci            return -1;
322cc290419Sopenharmony_ci        }
323cc290419Sopenharmony_ci#endif
324cc290419Sopenharmony_ci#else
325cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
326cc290419Sopenharmony_ci        if (!g_enableUart) {
327cc290419Sopenharmony_ci            Base::PrintMessage("TCP, USB and Uart are disable, cannot run continue\n");
328cc290419Sopenharmony_ci            return -1;
329cc290419Sopenharmony_ci        }
330cc290419Sopenharmony_ci#else
331cc290419Sopenharmony_ci        Base::PrintMessage("Both TCP and USB are disable, cannot run continue\n");
332cc290419Sopenharmony_ci        return -1;
333cc290419Sopenharmony_ci#endif
334cc290419Sopenharmony_ci#endif
335cc290419Sopenharmony_ci    }
336cc290419Sopenharmony_ci    if (g_backgroundRun) {
337cc290419Sopenharmony_ci        return BackgroundRun();
338cc290419Sopenharmony_ci    }
339cc290419Sopenharmony_ci    string debugMode;
340cc290419Sopenharmony_ci    SystemDepend::GetDevItem("const.debuggable", debugMode);
341cc290419Sopenharmony_ci    if (debugMode == "1") {
342cc290419Sopenharmony_ci        if (!NeedDropRootPrivileges()) {
343cc290419Sopenharmony_ci            Base::PrintMessage("DropRootPrivileges fail, EXITING...\n");
344cc290419Sopenharmony_ci            return -1;
345cc290419Sopenharmony_ci        }
346cc290419Sopenharmony_ci        WRITE_LOG(LOG_INFO, "HdcDaemon run as root mode.");
347cc290419Sopenharmony_ci    } else {
348cc290419Sopenharmony_ci        WRITE_LOG(LOG_INFO, "HdcDaemon run as user mode.");
349cc290419Sopenharmony_ci    }
350cc290419Sopenharmony_ci
351cc290419Sopenharmony_ci    Base::InitProcess();
352cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "HdcDaemon main run");
353cc290419Sopenharmony_ci    HdcDaemon daemon(false, CheckUvThreadConfig());
354cc290419Sopenharmony_ci
355cc290419Sopenharmony_ci#ifdef HDC_EMULATOR
356cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
357cc290419Sopenharmony_ci    daemon.InitMod(g_enableTcp, g_enableUsb, g_enableBridge, g_enableUart);
358cc290419Sopenharmony_ci#else
359cc290419Sopenharmony_ci    daemon.InitMod(g_enableTcp, g_enableUsb, g_enableBridge);
360cc290419Sopenharmony_ci#endif
361cc290419Sopenharmony_ci#else
362cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
363cc290419Sopenharmony_ci    daemon.InitMod(g_enableTcp, g_enableUsb, g_enableUart);
364cc290419Sopenharmony_ci#else
365cc290419Sopenharmony_ci    daemon.InitMod(g_enableTcp, g_enableUsb);
366cc290419Sopenharmony_ci#endif
367cc290419Sopenharmony_ci#endif
368cc290419Sopenharmony_ci    daemon.ClearKnownHosts();
369cc290419Sopenharmony_ci    daemon.WorkerPendding();
370cc290419Sopenharmony_ci    bool wantRestart = daemon.WantRestart();
371cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "Daemon finish wantRestart %d", wantRestart);
372cc290419Sopenharmony_ci    // There is no daemon, we can only restart myself.
373cc290419Sopenharmony_ci    if (wantRestart) {
374cc290419Sopenharmony_ci        // just root can self restart, low privilege will be exit and start by service(root)
375cc290419Sopenharmony_ci        WRITE_LOG(LOG_INFO, "Daemon restart");
376cc290419Sopenharmony_ci        RestartDaemon(false);
377cc290419Sopenharmony_ci    }
378cc290419Sopenharmony_ci#ifdef HDC_SUPPORT_UART
379cc290419Sopenharmony_ci    // when no usb insert , device will hung here , we don't know why.
380cc290419Sopenharmony_ci    // Test the command "smode -r" in uart mode, then execute shell
381cc290419Sopenharmony_ci    // hdcd will not really exit until usb plug in
382cc290419Sopenharmony_ci    // so we use abort here
383cc290419Sopenharmony_ci    _exit(0);
384cc290419Sopenharmony_ci#endif
385cc290419Sopenharmony_ci    return 0;
386cc290419Sopenharmony_ci}
387cc290419Sopenharmony_ci#endif
388