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 &param) 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 &param) 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 &param) 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 &param) 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 &param) 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 &param) 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