1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <VtsHalHidlTargetTestBase.h> 18 19 #include "wifi_hidl_call_util.h" 20 #include "wifi_hidl_test_utils.h" 21 22 using ::android::hardware::wifi::V1_0::IWifi; 23 using ::android::hardware::wifi::V1_0::IWifiApIface; 24 using ::android::hardware::wifi::V1_0::IWifiChip; 25 using ::android::hardware::wifi::V1_0::IWifiNanIface; 26 using ::android::hardware::wifi::V1_0::IWifiP2pIface; 27 using ::android::hardware::wifi::V1_0::IWifiRttController; 28 using ::android::hardware::wifi::V1_0::IWifiStaIface; 29 using ::android::hardware::wifi::V1_0::ChipModeId; 30 using ::android::hardware::wifi::V1_0::ChipId; 31 using ::android::hardware::wifi::V1_0::IfaceType; 32 using ::android::hardware::wifi::V1_0::WifiStatus; 33 using ::android::hardware::wifi::V1_0::WifiStatusCode; 34 using ::android::sp; 35 using ::android::hardware::hidl_string; 36 using ::android::hardware::hidl_vec; 37 38 namespace { 39 constexpr uint32_t kHalStartRetryMaxCount = 5; 40 constexpr uint32_t kHalStartRetryIntervalInMs = 2; 41 42 bool findAnyModeSupportingIfaceType( 43 IfaceType desired_type, const std::vector<IWifiChip::ChipMode>& modes, 44 ChipModeId* mode_id) { 45 for (const auto& mode : modes) { 46 for (const auto& combination : mode.availableCombinations) { 47 for (const auto& iface_limit : combination.limits) { 48 const auto& iface_types = iface_limit.types; 49 if (std::find(iface_types.begin(), iface_types.end(), 50 desired_type) != iface_types.end()) { 51 *mode_id = mode.id; 52 return true; 53 } 54 } 55 } 56 } 57 return false; 58 } 59 60 bool configureChipToSupportIfaceTypeInternal(const sp<IWifiChip>& wifi_chip, 61 IfaceType type, 62 ChipModeId* configured_mode_id) { 63 if (!configured_mode_id) { 64 return false; 65 } 66 const auto& status_and_modes = HIDL_INVOKE(wifi_chip, getAvailableModes); 67 if (status_and_modes.first.code != WifiStatusCode::SUCCESS) { 68 return false; 69 } 70 if (!findAnyModeSupportingIfaceType(type, status_and_modes.second, 71 configured_mode_id)) { 72 return false; 73 } 74 if (HIDL_INVOKE(wifi_chip, configureChip, *configured_mode_id).code != 75 WifiStatusCode::SUCCESS) { 76 return false; 77 } 78 return true; 79 } 80 81 bool configureChipToSupportIfaceTypeInternal(const sp<IWifiChip>& wifi_chip, 82 IfaceType type) { 83 ChipModeId mode_id; 84 return configureChipToSupportIfaceTypeInternal(wifi_chip, type, &mode_id); 85 } 86 } // namespace 87 88 sp<IWifi> getWifi() { 89 sp<IWifi> wifi = ::testing::VtsHalHidlTargetTestBase::getService<IWifi>(); 90 return wifi; 91 } 92 93 sp<IWifiChip> getWifiChip() { 94 sp<IWifi> wifi = getWifi(); 95 if (!wifi.get()) { 96 return nullptr; 97 } 98 uint32_t retry_count = 0; 99 auto status = HIDL_INVOKE(wifi, start); 100 while (retry_count < kHalStartRetryMaxCount && 101 status.code == WifiStatusCode::ERROR_NOT_AVAILABLE) { 102 retry_count++; 103 usleep(kHalStartRetryIntervalInMs * 1000); 104 status = HIDL_INVOKE(wifi, start); 105 } 106 if (status.code != WifiStatusCode::SUCCESS) { 107 return nullptr; 108 } 109 const auto& status_and_chip_ids = HIDL_INVOKE(wifi, getChipIds); 110 const auto& chip_ids = status_and_chip_ids.second; 111 if (status_and_chip_ids.first.code != WifiStatusCode::SUCCESS || 112 chip_ids.size() != 1) { 113 return nullptr; 114 } 115 const auto& status_and_chip = HIDL_INVOKE(wifi, getChip, chip_ids[0]); 116 if (status_and_chip.first.code != WifiStatusCode::SUCCESS) { 117 return nullptr; 118 } 119 return status_and_chip.second; 120 } 121 122 sp<IWifiApIface> getWifiApIface() { 123 sp<IWifiChip> wifi_chip = getWifiChip(); 124 if (!wifi_chip.get()) { 125 return nullptr; 126 } 127 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::AP)) { 128 return nullptr; 129 } 130 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createApIface); 131 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { 132 return nullptr; 133 } 134 return status_and_iface.second; 135 } 136 137 sp<IWifiNanIface> getWifiNanIface() { 138 sp<IWifiChip> wifi_chip = getWifiChip(); 139 if (!wifi_chip.get()) { 140 return nullptr; 141 } 142 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::NAN)) { 143 return nullptr; 144 } 145 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createNanIface); 146 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { 147 return nullptr; 148 } 149 return status_and_iface.second; 150 } 151 152 sp<IWifiP2pIface> getWifiP2pIface() { 153 sp<IWifiChip> wifi_chip = getWifiChip(); 154 if (!wifi_chip.get()) { 155 return nullptr; 156 } 157 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::P2P)) { 158 return nullptr; 159 } 160 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createP2pIface); 161 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { 162 return nullptr; 163 } 164 return status_and_iface.second; 165 } 166 167 sp<IWifiStaIface> getWifiStaIface() { 168 sp<IWifiChip> wifi_chip = getWifiChip(); 169 if (!wifi_chip.get()) { 170 return nullptr; 171 } 172 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::STA)) { 173 return nullptr; 174 } 175 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createStaIface); 176 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { 177 return nullptr; 178 } 179 return status_and_iface.second; 180 } 181 182 sp<IWifiRttController> getWifiRttController() { 183 sp<IWifiChip> wifi_chip = getWifiChip(); 184 if (!wifi_chip.get()) { 185 return nullptr; 186 } 187 sp<IWifiStaIface> wifi_sta_iface = getWifiStaIface(); 188 if (!wifi_sta_iface.get()) { 189 return nullptr; 190 } 191 const auto& status_and_controller = 192 HIDL_INVOKE(wifi_chip, createRttController, wifi_sta_iface); 193 if (status_and_controller.first.code != WifiStatusCode::SUCCESS) { 194 return nullptr; 195 } 196 return status_and_controller.second; 197 } 198 199 bool configureChipToSupportIfaceType(const sp<IWifiChip>& wifi_chip, 200 IfaceType type, 201 ChipModeId* configured_mode_id) { 202 return configureChipToSupportIfaceTypeInternal(wifi_chip, type, 203 configured_mode_id); 204 } 205 206 void stopWifi() { 207 sp<IWifi> wifi = getWifi(); 208 ASSERT_NE(wifi, nullptr); 209 const auto status = HIDL_INVOKE(wifi, stop); 210 ASSERT_TRUE((status.code == WifiStatusCode::SUCCESS) || 211 (status.code == WifiStatusCode::ERROR_NOT_AVAILABLE)); 212 } 213