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