1 /*
2 * Copyright (C) 2023 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 "wifi_cmd_client.h"
16 #include <linux/sockios.h>
17 #include <net/if.h>
18 #include <net/route.h>
19 #include <netinet/in.h>
20 #include <sys/ioctl.h>
21 #include <sys/socket.h>
22 #include <sys/types.h>
23 #include <cerrno>
24 #include <unistd.h>
25 #include "securec.h"
26 #include "wifi_logger.h"
27
28 namespace OHOS {
29 namespace Wifi {
30 DEFINE_WIFILOG_LABEL("WifiCmdClient");
31
32 static const int MAX_PRIV_CMD_SIZE = 4096;
33 static const int MSS_BLA_LIST_MAX_PARAMSIZE = 129;
34 static const int MSS_BLA_LIST_BUFSIZE = 192;
35 static const int TINY_BUFF_SIZE = 64;
36
37 static const auto RX_LISTEN_ON = "Y";
38 static const auto RX_LISTEN_OFF = "N";
39 static const auto CMD_SET_RX_LISTEN_ON = "SET_RX_LISTEN_PS_SWITCH 1";
40 static const auto CMD_SET_RX_LISTEN_OFF = "SET_RX_LISTEN_PS_SWITCH 0";
41 static const auto CMD_SET_AX_BLA_LIST = "SET_AX_BLACKLIST";
42 static const auto CMD_SET_AX_CLOSE_HTC = "SET_AX_CLOSE_HTC";
43 static const auto CMD_SET_BE_BLA_LIST = "SET_BE_BLACKLIST";
44 static const auto CMD_SET_EMLSR_MODE = "SET_EMLSR_SWITCH";
45 static const auto CMD_SET_MLSR_LINK_SWITCH = "SET_MLSR_LINK_SWITCH ";
46
47 #define MSS_SOFTAP_MAX_IFNAMESIZE 5
48 #define MSS_SOFTAP_CMDSIZE 30
49
GetInstance()50 WifiCmdClient &WifiCmdClient::GetInstance()
51 {
52 static WifiCmdClient instance;
53 return instance;
54 }
SendCmdToDriver(const std::string & ifName,int commandId,const std::string & param) const55 int WifiCmdClient::SendCmdToDriver(const std::string &ifName, int commandId, const std::string ¶m) const
56 {
57 int ret = -1;
58 if (ifName.empty() || param.empty() || (param.size() + 1) > MAX_PRIV_CMD_SIZE) {
59 WIFI_LOGE("%{public}s invalid input params", __FUNCTION__);
60 return ret;
61 }
62 if (commandId == CMD_SET_RX_LISTEN_POWER_SAVING_SWITCH) {
63 ret = SetRxListen(ifName, param);
64 } else if (commandId == CMD_SET_SOFTAP_2G_MSS) {
65 ret = Set2gSoftapMss(ifName, param);
66 } else if (commandId == CMD_AX_BLA_LIST) {
67 ret = SetAxBlaList(ifName, param);
68 } else if (commandId == CMD_AX_SELFCURE) {
69 ret = AxSelfcure(ifName, param);
70 } else if (commandId == CMD_BE_BLA_LIST) {
71 ret = SetBeBlaList(ifName, param);
72 } else if (commandId == CMD_EMLSR_MODE) {
73 ret = SetEmlsrMode(ifName, param);
74 } else if (commandId == CMD_MLD_LINK_SWITCH) {
75 ret = StartMldLinkSwitch(ifName, param);
76 } else {
77 WIFI_LOGD("%{public}s not supported command", __FUNCTION__);
78 }
79 return ret;
80 }
81
SendCommandToDriverByInterfaceName(const std::string & ifName,const std::string & cmdParm,char * out) const82 int WifiCmdClient::SendCommandToDriverByInterfaceName(const std::string &ifName,
83 const std::string &cmdParm, char *out) const
84 {
85 int ret = -1;
86 if (ifName.size() + 1 > IFNAMSIZ) {
87 WIFI_LOGE("%{public}s ifName size too large", __FUNCTION__);
88 return ret;
89 }
90 if (ifName.size() + 1 > MAX_PRIV_CMD_SIZE) {
91 WIFI_LOGE("%{public}s cmdParm size too large", __FUNCTION__);
92 return ret;
93 }
94 struct ifreq ifr;
95 WifiPrivCmd privCmd = { 0 };
96 uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
97 if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
98 WIFI_LOGE("%{public}s memset_s ifr error", __FUNCTION__);
99 return ret;
100 }
101 if (memcpy_s(buf, MAX_PRIV_CMD_SIZE, cmdParm.c_str(), cmdParm.size() + 1) != EOK) {
102 WIFI_LOGE("%{public}s memcpy_s privCmd buf error", __FUNCTION__);
103 return ret;
104 }
105 privCmd.buf = buf;
106 if (strncmp(cmdParm.c_str(), CMD_SET_AX_BLA_LIST, strlen(CMD_SET_AX_BLA_LIST)) == 0) {
107 WIFI_LOGI("%{public}s send wifi6 bla list", __FUNCTION__);
108 privCmd.size = static_cast<int>(cmdParm.size());
109 } else if (strncmp(cmdParm.c_str(), CMD_SET_BE_BLA_LIST, strlen(CMD_SET_BE_BLA_LIST)) == 0) {
110 WIFI_LOGI("%{public}s send wifi7 bla list", __FUNCTION__);
111 privCmd.size = static_cast<int>(cmdParm.size());
112 } else {
113 privCmd.size = sizeof(buf);
114 }
115 privCmd.len = static_cast<int>(cmdParm.size());
116 ifr.ifr_data = reinterpret_cast<char *>(&privCmd);
117 if (memcpy_s(ifr.ifr_name, IFNAMSIZ, ifName.c_str(), ifName.size() + 1) != EOK) {
118 WIFI_LOGE("%{public}s memcpy_s ifr fail", __FUNCTION__);
119 return ret;
120 }
121 int sock = socket(AF_INET, SOCK_DGRAM, 0);
122 if (sock < 0) {
123 WIFI_LOGE("%{public}s socked fail", __FUNCTION__);
124 return ret;
125 }
126 ret = ioctl(sock, SIOCDEVPRIVATE + 1, &ifr);
127 if (ret < 0) {
128 WIFI_LOGE("%{public}s ioctl failed, error is: %{public}d.", __FUNCTION__, errno);
129 }
130 close(sock);
131 if (out != nullptr) {
132 if (memset_s(out, TINY_BUFF_SIZE, 0, TINY_BUFF_SIZE) != EOK) {
133 WIFI_LOGE("%{public}s memset_s cmd fail", __FUNCTION__);
134 }
135 if (memcpy_s(out, TINY_BUFF_SIZE, privCmd.buf, TINY_BUFF_SIZE - 1) != EOK) {
136 WIFI_LOGE("%{public}s memcpy_s cmd fail", __FUNCTION__);
137 }
138 }
139 return ret;
140 }
141
VoWifiDetectInternal(std::string cmd)142 std::string WifiCmdClient::VoWifiDetectInternal(std::string cmd)
143 {
144 std::string ifName = "wlan0";
145 char out[MAX_PRIV_CMD_SIZE] = {};
146 int ret = SendCommandToDriverByInterfaceName(ifName, cmd, out);
147 if (ret == 0) {
148 std::string reply = out;
149 return reply;
150 }
151 return "";
152 }
153
SetRxListen(const std::string & ifName,const std::string & param) const154 int WifiCmdClient::SetRxListen(const std::string &ifName, const std::string ¶m) const
155 {
156 WIFI_LOGD("%{public}s enter", __FUNCTION__);
157 std::string cmdParam;
158 if (param.compare(RX_LISTEN_ON) == 0) {
159 cmdParam = CMD_SET_RX_LISTEN_ON;
160 WIFI_LOGD("%{public}s enable rx listen", __FUNCTION__);
161 } else if (param.compare(RX_LISTEN_OFF) == 0) {
162 cmdParam = CMD_SET_RX_LISTEN_OFF;
163 WIFI_LOGD("%{public}s disable rx listen", __FUNCTION__);
164 } else {
165 WIFI_LOGE("%{public}s invalid param", __FUNCTION__);
166 return -1;
167 }
168 return SendCommandToDriverByInterfaceName(ifName, cmdParam);
169 }
170
Set2gSoftapMss(const std::string & ifName,const std::string & param) const171 int WifiCmdClient::Set2gSoftapMss(const std::string &ifName, const std::string ¶m) const
172 {
173 if (ifName.empty() || ifName.size() > MSS_SOFTAP_MAX_IFNAMESIZE) {
174 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
175 return -1;
176 }
177 if ((ifName.size() + param.size()) > MSS_SOFTAP_CMDSIZE) {
178 WIFI_LOGE("%{public}s ifNameLen + cmdLen overflow", __FUNCTION__);
179 return -1;
180 }
181 return SendCommandToDriverByInterfaceName(ifName, param);
182 }
183
SetAxBlaList(const std::string & ifName,const std::string & param) const184 int WifiCmdClient::SetAxBlaList(const std::string &ifName, const std::string ¶m) const
185 {
186 WIFI_LOGD("%{public}s enter", __FUNCTION__);
187 if (param.size() > MSS_BLA_LIST_MAX_PARAMSIZE ||
188 param.size() + strlen(CMD_SET_AX_BLA_LIST) > MSS_BLA_LIST_BUFSIZE) {
189 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
190 return -1;
191 }
192 std::string cmdParm = CMD_SET_AX_BLA_LIST;
193 cmdParm.append(" ");
194 cmdParm.append(param);
195 return SendCommandToDriverByInterfaceName(ifName, cmdParm);
196 }
197
AxSelfcure(const std::string & ifName,const std::string & param) const198 int WifiCmdClient::AxSelfcure(const std::string &ifName, const std::string ¶m) const
199 {
200 WIFI_LOGD("%{public}s enter", __FUNCTION__);
201 if (param.empty() || param.size() == 0 ||
202 param.size() + strlen(CMD_SET_AX_CLOSE_HTC) > TINY_BUFF_SIZE) {
203 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
204 return -1;
205 }
206 std::string cmdParm = CMD_SET_AX_CLOSE_HTC;
207 cmdParm.append(" ");
208 cmdParm.append(param);
209 return SendCommandToDriverByInterfaceName(ifName, cmdParm);
210 }
211
SetBeBlaList(const std::string & ifName,const std::string & param) const212 int WifiCmdClient::SetBeBlaList(const std::string &ifName, const std::string ¶m) const
213 {
214 WIFI_LOGD("%{public}s enter", __FUNCTION__);
215 if (param.size() > MSS_BLA_LIST_MAX_PARAMSIZE ||
216 param.size() + strlen(CMD_SET_BE_BLA_LIST) > MSS_BLA_LIST_BUFSIZE) {
217 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
218 return -1;
219 }
220 std::string cmdParm = CMD_SET_BE_BLA_LIST;
221 cmdParm.append(" ");
222 cmdParm.append(param);
223 return SendCommandToDriverByInterfaceName(ifName, cmdParm);
224 }
225
SetEmlsrMode(const std::string & ifName,const std::string & param) const226 int WifiCmdClient::SetEmlsrMode(const std::string &ifName, const std::string ¶m) const
227 {
228 WIFI_LOGD("%{public}s enter", __FUNCTION__);
229 if (param.size() + strlen(CMD_SET_EMLSR_MODE) > TINY_BUFF_SIZE) {
230 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
231 return -1;
232 }
233 std::string cmdParm = CMD_SET_EMLSR_MODE;
234 cmdParm.append(" ");
235 cmdParm.append(param);
236 return SendCommandToDriverByInterfaceName(ifName, cmdParm);
237 }
238
StartMldLinkSwitch(const std::string & ifName,const std::string & param) const239 int WifiCmdClient::StartMldLinkSwitch(const std::string &ifName, const std::string ¶m) const
240 {
241 WIFI_LOGD("%{public}s enter", __FUNCTION__);
242 if (param.size() + strlen(CMD_SET_MLSR_LINK_SWITCH) > TINY_BUFF_SIZE) {
243 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
244 return -1;
245 }
246 std::string cmdParm = CMD_SET_MLSR_LINK_SWITCH;
247 cmdParm.append(param);
248 return SendCommandToDriverByInterfaceName(ifName, cmdParm);
249 }
250 } // namespace Wifi
251 } // namespace OHOS