1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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
16 #include <string>
17 #include "wifi_hal.h"
18 #include "wifi_ioctl.h"
19 #include <securec.h>
20 #include <osal_mem.h>
21 #include <hdf_log.h>
22
23 static const std::string POWER_MODE_SLEEP = "sleep";
24 static const std::string POWER_MODE_THIRD = "third";
25 static const std::string POWER_MODE_INIT = "init";
26
SendCommandToDriverByInterfaceName(int32_t sock,char * cmd,const char * interfaceName)27 static int32_t SendCommandToDriverByInterfaceName(int32_t sock, char *cmd, const char *interfaceName)
28 {
29 struct ifreq ifr;
30 int32_t ret = -1;
31 WifiPrivCmd privCmd;
32
33 if (cmd == nullptr || interfaceName == nullptr) {
34 HDF_LOGE("SendCommandToDriver: cmd is null or interfaceName is null.");
35 return HAL_INVALID_ARGS;
36 }
37 (void)memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr));
38 (void)memset_s(&privCmd, sizeof(privCmd), 0, sizeof(privCmd));
39 #if (defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
40 privCmd.buf = static_cast<unsigned char *>(OsalMemCalloc(MAX_PRIV_CMD_SIZE));
41 if (privCmd.buf == nullptr) {
42 HDF_LOGE("%{public}s :OsalMemCalloc fail", __func__);
43 return HAL_NONE;
44 }
45 #endif
46 do {
47 if (memcpy_s(privCmd.buf, MAX_PRIV_CMD_SIZE, cmd, MAX_CMD_LEN) != EOK) {
48 HDF_LOGE("memcpy_s privCmd fail");
49 break;
50 }
51 privCmd.size = MAX_PRIV_CMD_SIZE;
52 privCmd.len = MAX_CMD_LEN;
53 ifr.ifr_data = reinterpret_cast<char *>(&privCmd);
54 if (strcpy_s(ifr.ifr_name, IFNAMSIZ, interfaceName) != EOK) {
55 HDF_LOGE("strcpy_s ifr fail");
56 break;
57 }
58 ret = ioctl(sock, SIOCDEVPRIVATE + 1, &ifr);
59 if (ret < 0) {
60 HDF_LOGE("ioctl %{public}s fail, errno = %{public}d: %{public}s", cmd, errno, strerror(errno));
61 if (errno == EOPNOTSUPP) {
62 ret = HAL_NOT_SUPPORTED;
63 } else {
64 ret = HAL_NONE;
65 }
66 }
67 (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN);
68 if (memcpy_s(cmd, MAX_CMD_LEN, privCmd.buf, MAX_CMD_LEN - 1) != EOK) {
69 HDF_LOGE("%{public}s :memcpy_s cmd fail", __func__);
70 ret = HAL_NONE;
71 break;
72 }
73 } while (0);
74 #if (defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
75 OsalMemFree(privCmd.buf);
76 #endif
77 return ret;
78 }
79
SendCmdIoctl(const char * ifName,char * cmdBuf)80 static int SendCmdIoctl(const char *ifName, char *cmdBuf)
81 {
82 int ret = -1;
83
84 int sock = socket(AF_INET, SOCK_DGRAM, 0);
85 if (sock < 0) {
86 HDF_LOGE("%s :socket error", __func__);
87 return ret;
88 }
89
90 ret = SendCommandToDriverByInterfaceName(sock, cmdBuf, ifName);
91 HDF_LOGI("%s : ret: %d", __func__, ret);
92 close(sock);
93 return ret;
94 }
95
GetPowerMode(const char * ifName,int * mode)96 WifiError GetPowerMode(const char *ifName, int *mode)
97 {
98 return HAL_SUCCESS;
99 }
100
SetPowerMode(const char * ifName,int mode)101 WifiError SetPowerMode(const char *ifName, int mode)
102 {
103 return HAL_SUCCESS;
104 }
105
SetTxPower(const char * ifName,int mode)106 WifiError SetTxPower(const char *ifName, int mode)
107 {
108 return HAL_SUCCESS;
109 }
110
EnablePowerMode(const char * ifName,int mode)111 WifiError EnablePowerMode(const char *ifName, int mode)
112 {
113 return HAL_SUCCESS;
114 }
115
WifiGetSupportedFeatureSet(const char * ifName)116 uint32_t WifiGetSupportedFeatureSet(const char *ifName)
117 {
118 uint32_t ret = 0;
119 char cmdBuf[MAX_CMD_LEN] = { 0 };
120 size_t cmdLen = strlen(CMD_GET_WIFI_PRIV_FEATURE_CAPABILITY);
121
122 if (ifName == nullptr) {
123 HDF_LOGE("WifiGetSupportedFeatureSet iface is null.");
124 return ret;
125 }
126 if (memcpy_s(cmdBuf, MAX_CMD_LEN, CMD_GET_WIFI_PRIV_FEATURE_CAPABILITY, cmdLen) != EOK) {
127 HDF_LOGE("%{public}s :memcpy_s cmdBuf fail", __FUNCTION__);
128 return ret;
129 }
130 if (SendCmdIoctl(ifName, cmdBuf) == 0) {
131 ret = *(reinterpret_cast<uint32_t *>(cmdBuf));
132 } else {
133 HDF_LOGI("WifiGetSupportedFeatureSet failed");
134 }
135 return ret;
136 }
137
GetChipCaps(const char * ifName)138 uint32_t GetChipCaps(const char *ifName)
139 {
140 uint32_t ret = 0;
141 char cmdBuf[MAX_CMD_LEN] = { 0 };
142 size_t cmdLen = strlen(CMD_WIFI_CATEGORY);
143
144 if (ifName == nullptr) {
145 HDF_LOGE("HisiGetWifiCategory ifName is null.");
146 return ret;
147 }
148 if (memcpy_s(cmdBuf, MAX_CMD_LEN, CMD_WIFI_CATEGORY, cmdLen) != EOK) {
149 HDF_LOGE("%{public}s :memcpy_s cmdBuf fail", __FUNCTION__);
150 return ret;
151 }
152 if (SendCmdIoctl(ifName, cmdBuf) == 0) {
153 if (strncmp(cmdBuf, CMD_WIFI_CATEGORY, cmdLen) != 0) {
154 ret = *(reinterpret_cast<uint8_t *>(cmdBuf));
155 }
156 } else {
157 HDF_LOGI("GetChipCaps failed");
158 }
159 return ret;
160 }
161
162