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 
findAnyModeSupportingIfaceType(IfaceType desired_type,const std::vector<IWifiChip::ChipMode> & modes,ChipModeId * mode_id)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 
configureChipToSupportIfaceTypeInternal(const sp<IWifiChip> & wifi_chip,IfaceType type,ChipModeId * configured_mode_id)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 
configureChipToSupportIfaceTypeInternal(const sp<IWifiChip> & wifi_chip,IfaceType type)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 
getWifi()88 sp<IWifi> getWifi() {
89     sp<IWifi> wifi = ::testing::VtsHalHidlTargetTestBase::getService<IWifi>();
90     return wifi;
91 }
92 
getWifiChip()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 
getWifiApIface()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 
getWifiNanIface()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 
getWifiP2pIface()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 
getWifiStaIface()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 
getWifiRttController()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 
configureChipToSupportIfaceType(const sp<IWifiChip> & wifi_chip,IfaceType type,ChipModeId * configured_mode_id)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 
stopWifi()206 void stopWifi() {
207     sp<IWifi> wifi = getWifi();
208     ASSERT_NE(wifi, nullptr);
209     ASSERT_EQ(HIDL_INVOKE(wifi, stop).code, WifiStatusCode::SUCCESS);
210 }
211