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
45 #define MSS_SOFTAP_MAX_IFNAMESIZE 5
46 #define MSS_SOFTAP_CMDSIZE 30
47
GetInstance()48 WifiCmdClient &WifiCmdClient::GetInstance()
49 {
50 static WifiCmdClient instance;
51 return instance;
52 }
SendCmdToDriver(const std::string & ifName,int commandId,const std::string & param) const53 int WifiCmdClient::SendCmdToDriver(const std::string &ifName, int commandId, const std::string ¶m) const
54 {
55 int ret = -1;
56 if (ifName.empty() || param.empty() || (param.size() + 1) > MAX_PRIV_CMD_SIZE) {
57 WIFI_LOGE("%{public}s invalid input params", __FUNCTION__);
58 return ret;
59 }
60 if (commandId == CMD_SET_RX_LISTEN_POWER_SAVING_SWITCH) {
61 ret = SetRxListen(ifName, param);
62 } else if (commandId == CMD_SET_SOFTAP_2G_MSS) {
63 ret = Set2gSoftapMss(ifName, param);
64 } else if (commandId == CMD_AX_BLA_LIST) {
65 ret = SetAxBlaList(ifName, param);
66 } else if (commandId == CMD_AX_SELFCURE) {
67 ret = AxSelfcure(ifName, param);
68 } else if (commandId == CMD_BE_BLA_LIST) {
69 ret = SetBeBlaList(ifName, param);
70 } else {
71 WIFI_LOGD("%{public}s not supported command", __FUNCTION__);
72 }
73 return ret;
74 }
SendCommandToDriverByInterfaceName(const std::string & ifName,const std::string & cmdParm) const75 int WifiCmdClient::SendCommandToDriverByInterfaceName(const std::string &ifName,
76 const std::string &cmdParm) const
77 {
78 int ret = -1;
79 if (ifName.size() + 1 > IFNAMSIZ) {
80 WIFI_LOGE("%{public}s ifName size too large", __FUNCTION__);
81 return ret;
82 }
83 if (ifName.size() + 1 > MAX_PRIV_CMD_SIZE) {
84 WIFI_LOGE("%{public}s cmdParm size too large", __FUNCTION__);
85 return ret;
86 }
87 struct ifreq ifr;
88 WifiPrivCmd privCmd = { 0 };
89 uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
90 (void)memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr));
91 if (memcpy_s(buf, MAX_PRIV_CMD_SIZE, cmdParm.c_str(), cmdParm.size() + 1) != EOK) {
92 WIFI_LOGE("%{public}s memcpy_s privCmd buf error", __FUNCTION__);
93 return ret;
94 }
95 privCmd.buf = buf;
96 if (strncmp(cmdParm.c_str(), CMD_SET_AX_BLA_LIST, strlen(CMD_SET_AX_BLA_LIST)) == 0) {
97 WIFI_LOGI("%{public}s send wifi6 bla list", __FUNCTION__);
98 privCmd.size = static_cast<int>(cmdParm.size());
99 } else if (strncmp(cmdParm.c_str(), CMD_SET_BE_BLA_LIST, strlen(CMD_SET_BE_BLA_LIST)) == 0) {
100 WIFI_LOGI("%{public}s send wifi7 bla list", __FUNCTION__);
101 privCmd.size = static_cast<int>(cmdParm.size());
102 } else {
103 privCmd.size = sizeof(buf);
104 }
105 privCmd.len = static_cast<int>(cmdParm.size());
106 ifr.ifr_data = reinterpret_cast<char *>(&privCmd);
107 if (memcpy_s(ifr.ifr_name, IFNAMSIZ, ifName.c_str(), ifName.size() + 1) != EOK) {
108 WIFI_LOGE("%{public}s memcpy_s ifr fail", __FUNCTION__);
109 return ret;
110 }
111 int sock = socket(AF_INET, SOCK_DGRAM, 0);
112 if (sock < 0) {
113 WIFI_LOGE("%{public}s socked fail", __FUNCTION__);
114 return ret;
115 }
116 ret = ioctl(sock, SIOCDEVPRIVATE + 1, &ifr);
117 if (ret < 0) {
118 WIFI_LOGE("%{public}s ioctl failed, error is: %{public}d.", __FUNCTION__, errno);
119 }
120 close(sock);
121 return ret;
122 }
123
SetRxListen(const std::string & ifName,const std::string & param) const124 int WifiCmdClient::SetRxListen(const std::string &ifName, const std::string ¶m) const
125 {
126 WIFI_LOGD("%{public}s enter", __FUNCTION__);
127 std::string cmdParam;
128 if (param.compare(RX_LISTEN_ON) == 0) {
129 cmdParam = CMD_SET_RX_LISTEN_ON;
130 WIFI_LOGD("%{public}s enable rx listen", __FUNCTION__);
131 } else if (param.compare(RX_LISTEN_OFF) == 0) {
132 cmdParam = CMD_SET_RX_LISTEN_OFF;
133 WIFI_LOGD("%{public}s disable rx listen", __FUNCTION__);
134 } else {
135 WIFI_LOGE("%{public}s invalid param", __FUNCTION__);
136 return -1;
137 }
138 return SendCommandToDriverByInterfaceName(ifName, cmdParam);
139 }
140
Set2gSoftapMss(const std::string & ifName,const std::string & param) const141 int WifiCmdClient::Set2gSoftapMss(const std::string &ifName, const std::string ¶m) const
142 {
143 if (ifName.empty() || ifName.size() > MSS_SOFTAP_MAX_IFNAMESIZE) {
144 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
145 return -1;
146 }
147 if ((ifName.size() + param.size()) > MSS_SOFTAP_CMDSIZE) {
148 WIFI_LOGE("%{public}s ifNameLen + cmdLen overflow", __FUNCTION__);
149 return -1;
150 }
151 return SendCommandToDriverByInterfaceName(ifName, param);
152 }
153
SetAxBlaList(const std::string & ifName,const std::string & param) const154 int WifiCmdClient::SetAxBlaList(const std::string &ifName, const std::string ¶m) const
155 {
156 WIFI_LOGD("%{public}s enter", __FUNCTION__);
157 if (param.size() > MSS_BLA_LIST_MAX_PARAMSIZE ||
158 param.size() + strlen(CMD_SET_AX_BLA_LIST) > MSS_BLA_LIST_BUFSIZE) {
159 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
160 return -1;
161 }
162 std::string cmdParm = CMD_SET_AX_BLA_LIST;
163 cmdParm.append(" ");
164 cmdParm.append(param);
165 return SendCommandToDriverByInterfaceName(ifName, cmdParm);
166 }
167
AxSelfcure(const std::string & ifName,const std::string & param) const168 int WifiCmdClient::AxSelfcure(const std::string &ifName, const std::string ¶m) const
169 {
170 WIFI_LOGD("%{public}s enter", __FUNCTION__);
171 if (param.empty() || param.size() == 0 ||
172 param.size() + strlen(CMD_SET_AX_CLOSE_HTC) > TINY_BUFF_SIZE) {
173 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
174 return -1;
175 }
176 std::string cmdParm = CMD_SET_AX_CLOSE_HTC;
177 cmdParm.append(" ");
178 cmdParm.append(param);
179 return SendCommandToDriverByInterfaceName(ifName, cmdParm);
180 }
181
SetBeBlaList(const std::string & ifName,const std::string & param) const182 int WifiCmdClient::SetBeBlaList(const std::string &ifName, const std::string ¶m) const
183 {
184 WIFI_LOGD("%{public}s enter", __FUNCTION__);
185 if (param.size() > MSS_BLA_LIST_MAX_PARAMSIZE ||
186 param.size() + strlen(CMD_SET_BE_BLA_LIST) > MSS_BLA_LIST_BUFSIZE) {
187 WIFI_LOGE("%{public}s invalid input param", __FUNCTION__);
188 return -1;
189 }
190 std::string cmdParm = CMD_SET_BE_BLA_LIST;
191 cmdParm.append(" ");
192 cmdParm.append(param);
193 return SendCommandToDriverByInterfaceName(ifName, cmdParm);
194 }
195
196 } // namespace Wifi
197 } // namespace OHOS