/* * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "wifi_hal.h" #include "wifi_ioctl.h" #include #include #include static const std::string POWER_MODE_SLEEP = "sleep"; static const std::string POWER_MODE_THIRD = "third"; static const std::string POWER_MODE_INIT = "init"; static int32_t SendCommandToDriverByInterfaceName(int32_t sock, char *cmd, const char *interfaceName) { struct ifreq ifr; int32_t ret = -1; WifiPrivCmd privCmd; if (cmd == nullptr || interfaceName == nullptr) { HDF_LOGE("SendCommandToDriver: cmd is null or interfaceName is null."); return HAL_INVALID_ARGS; } (void)memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)); (void)memset_s(&privCmd, sizeof(privCmd), 0, sizeof(privCmd)); #if (defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) privCmd.buf = static_cast(OsalMemCalloc(MAX_PRIV_CMD_SIZE)); if (privCmd.buf == nullptr) { HDF_LOGE("%{public}s :OsalMemCalloc fail", __func__); return HAL_NONE; } #endif do { if (memcpy_s(privCmd.buf, MAX_PRIV_CMD_SIZE, cmd, MAX_CMD_LEN) != EOK) { HDF_LOGE("memcpy_s privCmd fail"); break; } privCmd.size = MAX_PRIV_CMD_SIZE; privCmd.len = MAX_CMD_LEN; ifr.ifr_data = reinterpret_cast(&privCmd); if (strcpy_s(ifr.ifr_name, IFNAMSIZ, interfaceName) != EOK) { HDF_LOGE("strcpy_s ifr fail"); break; } ret = ioctl(sock, SIOCDEVPRIVATE + 1, &ifr); if (ret < 0) { HDF_LOGE("ioctl %{public}s fail, errno = %{public}d: %{public}s", cmd, errno, strerror(errno)); if (errno == EOPNOTSUPP) { ret = HAL_NOT_SUPPORTED; } else { ret = HAL_NONE; } } (void)memset_s(cmd, MAX_CMD_LEN, 0, MAX_CMD_LEN); if (memcpy_s(cmd, MAX_CMD_LEN, privCmd.buf, MAX_CMD_LEN - 1) != EOK) { HDF_LOGE("%{public}s :memcpy_s cmd fail", __func__); ret = HAL_NONE; break; } } while (0); #if (defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) OsalMemFree(privCmd.buf); #endif return ret; } static int SendCmdIoctl(const char *ifName, char *cmdBuf) { int ret = -1; int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { HDF_LOGE("%s :socket error", __func__); return ret; } ret = SendCommandToDriverByInterfaceName(sock, cmdBuf, ifName); HDF_LOGI("%s : ret: %d", __func__, ret); close(sock); return ret; } WifiError GetPowerMode(const char *ifName, int *mode) { return HAL_SUCCESS; } WifiError SetPowerMode(const char *ifName, int mode) { return HAL_SUCCESS; } WifiError SetTxPower(const char *ifName, int mode) { return HAL_SUCCESS; } WifiError EnablePowerMode(const char *ifName, int mode) { return HAL_SUCCESS; } uint32_t WifiGetSupportedFeatureSet(const char *ifName) { uint32_t ret = 0; char cmdBuf[MAX_CMD_LEN] = { 0 }; size_t cmdLen = strlen(CMD_GET_WIFI_PRIV_FEATURE_CAPABILITY); if (ifName == nullptr) { HDF_LOGE("WifiGetSupportedFeatureSet iface is null."); return ret; } if (memcpy_s(cmdBuf, MAX_CMD_LEN, CMD_GET_WIFI_PRIV_FEATURE_CAPABILITY, cmdLen) != EOK) { HDF_LOGE("%{public}s :memcpy_s cmdBuf fail", __FUNCTION__); return ret; } if (SendCmdIoctl(ifName, cmdBuf) == 0) { ret = *(reinterpret_cast(cmdBuf)); } else { HDF_LOGI("WifiGetSupportedFeatureSet failed"); } return ret; } uint32_t GetChipCaps(const char *ifName) { uint32_t ret = 0; char cmdBuf[MAX_CMD_LEN] = { 0 }; size_t cmdLen = strlen(CMD_WIFI_CATEGORY); if (ifName == nullptr) { HDF_LOGE("HisiGetWifiCategory ifName is null."); return ret; } if (memcpy_s(cmdBuf, MAX_CMD_LEN, CMD_WIFI_CATEGORY, cmdLen) != EOK) { HDF_LOGE("%{public}s :memcpy_s cmdBuf fail", __FUNCTION__); return ret; } if (SendCmdIoctl(ifName, cmdBuf) == 0) { if (strncmp(cmdBuf, CMD_WIFI_CATEGORY, cmdLen) != 0) { ret = *(reinterpret_cast(cmdBuf)); } } else { HDF_LOGI("GetChipCaps failed"); } return ret; }