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 extern WifiHidlEnvironment* gEnv; 39 40 namespace { 41 constexpr uint32_t kHalStartRetryMaxCount = 5; 42 constexpr uint32_t kHalStartRetryIntervalInMs = 2; 43 44 bool findAnyModeSupportingIfaceType( 45 IfaceType desired_type, const std::vector<IWifiChip::ChipMode>& modes, 46 ChipModeId* mode_id) { 47 for (const auto& mode : modes) { 48 for (const auto& combination : mode.availableCombinations) { 49 for (const auto& iface_limit : combination.limits) { 50 const auto& iface_types = iface_limit.types; 51 if (std::find(iface_types.begin(), iface_types.end(), 52 desired_type) != iface_types.end()) { 53 *mode_id = mode.id; 54 return true; 55 } 56 } 57 } 58 } 59 return false; 60 } 61 62 bool configureChipToSupportIfaceTypeInternal(const sp<IWifiChip>& wifi_chip, 63 IfaceType type, 64 ChipModeId* configured_mode_id) { 65 if (!configured_mode_id) { 66 return false; 67 } 68 const auto& status_and_modes = HIDL_INVOKE(wifi_chip, getAvailableModes); 69 if (status_and_modes.first.code != WifiStatusCode::SUCCESS) { 70 return false; 71 } 72 if (!findAnyModeSupportingIfaceType(type, status_and_modes.second, 73 configured_mode_id)) { 74 return false; 75 } 76 if (HIDL_INVOKE(wifi_chip, configureChip, *configured_mode_id).code != 77 WifiStatusCode::SUCCESS) { 78 return false; 79 } 80 return true; 81 } 82 83 bool configureChipToSupportIfaceTypeInternal(const sp<IWifiChip>& wifi_chip, 84 IfaceType type) { 85 ChipModeId mode_id; 86 return configureChipToSupportIfaceTypeInternal(wifi_chip, type, &mode_id); 87 } 88 } // namespace 89 90 sp<IWifi> getWifi() { 91 sp<IWifi> wifi = ::testing::VtsHalHidlTargetTestBase::getService<IWifi>( 92 gEnv->getServiceName<IWifi>()); 93 return wifi; 94 } 95 96 sp<IWifiChip> getWifiChip() { 97 sp<IWifi> wifi = getWifi(); 98 if (!wifi.get()) { 99 return nullptr; 100 } 101 uint32_t retry_count = 0; 102 auto status = HIDL_INVOKE(wifi, start); 103 while (retry_count < kHalStartRetryMaxCount && 104 status.code == WifiStatusCode::ERROR_NOT_AVAILABLE) { 105 retry_count++; 106 usleep(kHalStartRetryIntervalInMs * 1000); 107 status = HIDL_INVOKE(wifi, start); 108 } 109 if (status.code != WifiStatusCode::SUCCESS) { 110 return nullptr; 111 } 112 const auto& status_and_chip_ids = HIDL_INVOKE(wifi, getChipIds); 113 const auto& chip_ids = status_and_chip_ids.second; 114 if (status_and_chip_ids.first.code != WifiStatusCode::SUCCESS || 115 chip_ids.size() != 1) { 116 return nullptr; 117 } 118 const auto& status_and_chip = HIDL_INVOKE(wifi, getChip, chip_ids[0]); 119 if (status_and_chip.first.code != WifiStatusCode::SUCCESS) { 120 return nullptr; 121 } 122 return status_and_chip.second; 123 } 124 125 sp<IWifiApIface> getWifiApIface() { 126 sp<IWifiChip> wifi_chip = getWifiChip(); 127 if (!wifi_chip.get()) { 128 return nullptr; 129 } 130 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::AP)) { 131 return nullptr; 132 } 133 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createApIface); 134 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { 135 return nullptr; 136 } 137 return status_and_iface.second; 138 } 139 140 sp<IWifiNanIface> getWifiNanIface() { 141 sp<IWifiChip> wifi_chip = getWifiChip(); 142 if (!wifi_chip.get()) { 143 return nullptr; 144 } 145 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::NAN)) { 146 return nullptr; 147 } 148 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createNanIface); 149 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { 150 return nullptr; 151 } 152 return status_and_iface.second; 153 } 154 155 sp<IWifiP2pIface> getWifiP2pIface() { 156 sp<IWifiChip> wifi_chip = getWifiChip(); 157 if (!wifi_chip.get()) { 158 return nullptr; 159 } 160 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::P2P)) { 161 return nullptr; 162 } 163 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createP2pIface); 164 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { 165 return nullptr; 166 } 167 return status_and_iface.second; 168 } 169 170 sp<IWifiStaIface> getWifiStaIface() { 171 sp<IWifiChip> wifi_chip = getWifiChip(); 172 if (!wifi_chip.get()) { 173 return nullptr; 174 } 175 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::STA)) { 176 return nullptr; 177 } 178 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createStaIface); 179 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { 180 return nullptr; 181 } 182 return status_and_iface.second; 183 } 184 185 sp<IWifiRttController> getWifiRttController() { 186 sp<IWifiChip> wifi_chip = getWifiChip(); 187 if (!wifi_chip.get()) { 188 return nullptr; 189 } 190 sp<IWifiStaIface> wifi_sta_iface = getWifiStaIface(); 191 if (!wifi_sta_iface.get()) { 192 return nullptr; 193 } 194 const auto& status_and_controller = 195 HIDL_INVOKE(wifi_chip, createRttController, wifi_sta_iface); 196 if (status_and_controller.first.code != WifiStatusCode::SUCCESS) { 197 return nullptr; 198 } 199 return status_and_controller.second; 200 } 201 202 bool configureChipToSupportIfaceType(const sp<IWifiChip>& wifi_chip, 203 IfaceType type, 204 ChipModeId* configured_mode_id) { 205 return configureChipToSupportIfaceTypeInternal(wifi_chip, type, 206 configured_mode_id); 207 } 208 209 void stopWifi() { 210 sp<IWifi> wifi = getWifi(); 211 ASSERT_NE(wifi, nullptr); 212 HIDL_INVOKE(wifi, stop); 213 } 214