• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include "svc_control.h"
16 
17 #include <cstdio>
18 #include <string>
19 #include <map>
20 #include <functional>
21 
22 #include "iservice_registry.h"
23 #include "if_local_ability_manager.h"
24 #include "string_ex.h"
25 #include "ipc_skeleton.h"
26 #include "safwk_log.h"
27 
28 namespace OHOS {
SvcControl()29 SvcControl::SvcControl()
30 {
31 }
32 
~SvcControl()33 SvcControl::~SvcControl()
34 {
35 }
36 
HelpInfo(int32_t fd)37 void SvcControl::HelpInfo(int32_t fd)
38 {
39     dprintf(fd, "svc wifi | bluetooth | nearlink enable | disable | help\n");
40 }
41 
CmdErrorToString(SvcCmd cmd)42 std::string SvcControl::CmdErrorToString(SvcCmd cmd)
43 {
44     if (cmd < SvcCmd::ARGS_CNT_NOT_ENOUGH) {
45         return "exception error code";
46     }
47     std::unordered_map<SvcCmd, std::string> errToString = {
48         { SvcCmd::ARGS_INVALID, "argument invalid" },
49         { SvcCmd::ARGS_CNT_EXCEED, "argument's cnt exceed" },
50         { SvcCmd::ARGS_CNT_NOT_ENOUGH, "argument's cnt not enough" },
51     };
52     return errToString[cmd];
53 }
54 
Main(int32_t argc,char * argv[],int32_t outFd)55 int32_t SvcControl::Main(int32_t argc, char *argv[], int32_t outFd)
56 {
57     HILOGI(TAG, "enter SVC main, proc:%{public}d", getpid());
58     if (argv == nullptr) {
59         dprintf(outFd, "argument is null\n");
60         HelpInfo(outFd);
61         HILOGE(TAG, "argument is null");
62         return -1;
63     }
64     SvcCmd cmd = Parse(argc, argv);
65     if (cmd == SvcCmd::HELP_CMD) {
66         HelpInfo(outFd);
67         return 0;
68     } else if (cmd <= SvcCmd::ARGS_INVALID) {
69         dprintf(outFd, "parse failed, parse status: %s\n", CmdErrorToString(cmd).c_str());
70         HelpInfo(outFd);
71         HILOGE(TAG, "parse failed, parse status: %{public}d", static_cast<int32_t>(cmd));
72         return -1;
73     }
74 
75     int32_t saId = static_cast<int32_t>(cmd);
76     auto sysm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
77     if (sysm == nullptr) {
78         dprintf(outFd, "get object of system ability manager failed\n");
79         HILOGE(TAG, "GetSystemAbilityManager failed");
80         return -1;
81     }
82     sptr<IRemoteObject> localObj = sysm->GetLocalAbilityManagerProxy(saId);
83     if (localObj == nullptr) {
84         (void)sysm->LoadSystemAbility(saId, TIME_OUT);
85         localObj = sysm->GetLocalAbilityManagerProxy(saId);
86     }
87     if (localObj == nullptr) {
88         dprintf(outFd, "get object of local ability manager proxy failed\n");
89         HILOGE(TAG, "GetLocalAbilityManagerProxy failed");
90         return -1;
91     }
92 
93     sptr<ILocalAbilityManager> localAbilityManager = iface_cast<ILocalAbilityManager>(localObj);
94     std::vector<std::u16string> args;
95     SetCmdArgs(argc, argv, args);
96 
97     int32_t ret = localAbilityManager->ServiceControlCmd(outFd, saId, args);
98     if (ret != NO_ERROR) {
99         dprintf(outFd, "set service cmd failed, ret: %d\n", ret);
100         HILOGE(TAG, "set ServiceControlCmd failed, ret: %{public}d", ret);
101         return -1;
102     }
103     dprintf(outFd, "set service cmd success\n");
104     return ret;
105 }
106 
Parse(int32_t argc,char * argv[])107 SvcCmd SvcControl::Parse(int32_t argc, char *argv[])
108 {
109     if (argc < ARG_MIN_COUNT) {
110         HILOGE(TAG, "need more arguments(%{public}d), min size %{public}d", argc, ARG_MIN_COUNT);
111         return SvcCmd::ARGS_CNT_NOT_ENOUGH;
112     }
113     if (argc > ARG_MAX_COUNT) {
114         HILOGE(TAG, "too many arguments(%{public}d), limit size %{public}d", argc, ARG_MAX_COUNT);
115         return SvcCmd::ARGS_CNT_EXCEED;
116     }
117 
118     for (int32_t i = 0; i < argc; ++i) {
119         if (argv[i] == nullptr) {
120             HILOGE(TAG, "argument(%{public}d) is null", i);
121             return SvcCmd::ARGS_INVALID;
122         }
123         size_t len = strlen(argv[i]);
124         if (len == 0) {
125             HILOGE(TAG, "argument(%{public}d) is empty", i);
126             return SvcCmd::ARGS_INVALID;
127         } else if (len > SINGLE_ARG_MAXLEN) {
128             HILOGE(TAG, "too long argument(%{public}d), limit size: %{public}d", i, SINGLE_ARG_MAXLEN);
129             return SvcCmd::ARGS_INVALID;
130         }
131     }
132 
133     constexpr int32_t cnt = 1;
134     bool isEnd = false;
135     SvcCmd cmd = ParseCmd(argv, cnt, isEnd);
136     if (cmd == SvcCmd::ARGS_INVALID) {
137         HILOGE(TAG, "the %{public}dth argument(%{public}s) is abnormal", cnt, argv[cnt]);
138     } else if (isEnd && argc > cnt + 1) {
139         cmd = SvcCmd::ARGS_CNT_EXCEED;
140         HILOGE(TAG, "too many arguments(%{public}d), current limit size %{public}d", argc, cnt + 1);
141     } else if (!isEnd && argc == cnt + 1) {
142         cmd = SvcCmd::ARGS_CNT_NOT_ENOUGH;
143         HILOGE(TAG, "the argument(%{public}s) need more sub-argument", argv[cnt]);
144     }
145     return cmd;
146 }
147 
ParseCmd(char * argv[],int32_t cnt,bool & isEnd)148 SvcCmd SvcControl::ParseCmd(char *argv[], int32_t cnt, bool &isEnd)
149 {
150     struct {
151         std::string op;
152         SvcCmd cmd;
153         bool isEnd;
154     } options[] = {
155         { "wifi",       SvcCmd::WIFI_CMD,       false },
156         { "bluetooth",  SvcCmd::BLUETOOTH_CMD,  false },
157         { "nearlink",   SvcCmd::NEARLINK_CMD,   false },
158         { "help",       SvcCmd::HELP_CMD,       true  },
159     };
160     SvcCmd cmd = SvcCmd::ARGS_INVALID;
161     for (auto &op: options) {
162         if (op.op == argv[cnt]) {
163             cmd = op.cmd;
164             isEnd = op.isEnd;
165             break;
166         }
167     }
168     return cmd;
169 }
170 
SetCmdArgs(int32_t argc,char * argv[],std::vector<std::u16string> & args)171 void SvcControl::SetCmdArgs(int32_t argc, char *argv[], std::vector<std::u16string>& args)
172 {
173     std::string argStr;
174     for (int32_t i = 0; i < ARG_MIN_COUNT; ++i) {
175         argStr += argv[i];
176         argStr += " ";
177     }
178     for (int32_t i = ARG_MIN_COUNT; i < argc; ++i) {
179         args.push_back(Str8ToStr16(std::string(argv[i])));
180         argStr += argv[i];
181         argStr += " ";
182     }
183     HILOGI(TAG, "svc cmd: %{public}s, callingUid=%{public}d, callingPid=%{public}d", argStr.c_str(),
184         IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid());
185 }
186 }
187