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#define LOG_TAG "wifi_offload_hidl_hal_test"
18
19#include <android-base/logging.h>
20#include <android/hardware/wifi/offload/1.0/IOffload.h>
21#include <android/hardware/wifi/offload/1.0/IOffloadCallback.h>
22#include <android/hardware/wifi/offload/1.0/types.h>
23
24#include <VtsHalHidlTargetCallbackBase.h>
25#include <VtsHalHidlTargetTestBase.h>
26
27#include <vector>
28
29#include "hidl_call_util.h"
30
31using ::android::hardware::wifi::offload::V1_0::IOffload;
32using ::android::hardware::wifi::offload::V1_0::IOffloadCallback;
33using ::android::hardware::wifi::offload::V1_0::ScanResult;
34using ::android::hardware::wifi::offload::V1_0::ScanParam;
35using ::android::hardware::wifi::offload::V1_0::Ssid;
36using ::android::hardware::wifi::offload::V1_0::NetworkInfo;
37using ::android::hardware::wifi::offload::V1_0::ScanFilter;
38using ::android::hardware::wifi::offload::V1_0::ScanStats;
39using ::android::hardware::wifi::offload::V1_0::OffloadStatus;
40using ::android::hardware::wifi::offload::V1_0::OffloadStatusCode;
41using ::android::hardware::Return;
42using ::android::hardware::Void;
43using ::android::hardware::hidl_vec;
44using ::android::sp;
45
46constexpr char kOffloadCallbackSendScanResult[] = "onScanResult";
47constexpr char kOffloadCallbackSendError[] = "onError";
48
49namespace {
50const uint8_t kSsid1[] = {'G', 'o', 'o', 'g', 'l', 'e'};
51const uint8_t kSsid2[] = {'X', 'f', 'i', 'n', 'i', 't', 'y'};
52const uint8_t kBssid[6] = {0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b};
53const int16_t kRssi = -60;
54const uint32_t kFrequency = 2412;
55const uint8_t kBssidSize = 6;
56const uint64_t kTsf = 0;
57const uint16_t kCapability = 0;
58const uint8_t kNetworkFlags = 0;
59const uint32_t kFrequency1 = 2412;
60const uint32_t kFrequency2 = 2437;
61const uint32_t kDisconnectedModeScanIntervalMs = 5000;
62const int16_t kRssiThreshold = -76;
63}
64
65class OffloadCallbackArgs {
66   public:
67    hidl_vec<ScanResult> scan_results_;
68    OffloadStatus error_code_;
69};
70
71// The main test class for WifiOffload HIDL HAL.
72class WifiOffloadHidlTest : public ::testing::VtsHalHidlTargetTestBase {
73   public:
74    virtual void SetUp() override {
75        wifi_offload_ =
76            ::testing::VtsHalHidlTargetTestBase::getService<IOffload>();
77        ASSERT_NE(wifi_offload_, nullptr);
78
79        wifi_offload_cb_ = new OffloadCallback();
80        ASSERT_NE(wifi_offload_cb_, nullptr);
81    }
82
83    virtual void TearDown() override {}
84
85    /* Callback class for Offload HAL. */
86    class OffloadCallback
87        : public ::testing::VtsHalHidlTargetCallbackBase<OffloadCallbackArgs>,
88          public IOffloadCallback {
89       public:
90        OffloadCallback(){};
91
92        virtual ~OffloadCallback() = default;
93
94        Return<void> onScanResult(
95            const hidl_vec<ScanResult>& scan_result) override {
96            OffloadCallbackArgs args;
97            args.scan_results_ = scan_result;
98            NotifyFromCallback(kOffloadCallbackSendScanResult, args);
99            return Void();
100        };
101
102        Return<void> onError(const OffloadStatus& status) override {
103            OffloadCallbackArgs args;
104            args.error_code_ = status;
105            NotifyFromCallback(kOffloadCallbackSendError, args);
106            return Void();
107        }
108    };
109
110    sp<IOffload> wifi_offload_;
111    sp<OffloadCallback> wifi_offload_cb_;
112};
113
114/*
115 * Verify that setEventCallback method returns without errors
116 */
117TEST_F(WifiOffloadHidlTest, setEventCallback) {
118    auto returnObject = wifi_offload_->setEventCallback(wifi_offload_cb_);
119    ASSERT_EQ(true, returnObject.isOk());
120}
121
122/*
123 * Verify that subscribeScanResults method returns without errors
124 */
125TEST_F(WifiOffloadHidlTest, subscribeScanResults) {
126    const auto& result = HIDL_INVOKE(wifi_offload_, subscribeScanResults, 0);
127    ASSERT_EQ(OffloadStatusCode::OK, result.code);
128}
129
130/*
131 * Verify that unsubscribeScanResults method returns without errors
132 */
133TEST_F(WifiOffloadHidlTest, unsubscribeScanResults) {
134    auto returnObject = wifi_offload_->unsubscribeScanResults();
135    ASSERT_EQ(true, returnObject.isOk());
136}
137
138/*
139 * Verify that configureScans method returns without errors
140 */
141TEST_F(WifiOffloadHidlTest, configureScans) {
142    ScanParam* pScanParam = new ScanParam();
143    std::vector<uint32_t> frequencyList = {kFrequency1, kFrequency2};
144    pScanParam->disconnectedModeScanIntervalMs =
145        kDisconnectedModeScanIntervalMs;
146    pScanParam->frequencyList = frequencyList;
147    std::vector<Ssid> ssidList;
148    std::vector<std::vector<uint8_t>> ssids{kSsid1, kSsid2};
149    for (const auto& ssid : ssids) {
150        Ssid tmp = ssid;
151        ssidList.push_back(tmp);
152    }
153    pScanParam->ssidList = ssidList;
154    ScanFilter* pScanFilter = new ScanFilter();
155    pScanFilter->rssiThreshold = kRssiThreshold;
156    std::vector<std::vector<uint8_t>> match_ssids{kSsid1, kSsid2};
157    std::vector<uint8_t> security_flags{kNetworkFlags, kNetworkFlags};
158    std::vector<NetworkInfo> preferredNetworksList;
159    for (size_t i = 0; i < security_flags.size(); i++) {
160        NetworkInfo nwInfo;
161        nwInfo.ssid = match_ssids[i];
162        nwInfo.flags = security_flags[i];
163        preferredNetworksList.push_back(nwInfo);
164    }
165    const auto& result =
166        HIDL_INVOKE(wifi_offload_, configureScans, *pScanParam, *pScanFilter);
167    ASSERT_EQ(OffloadStatusCode::OK, result.code);
168}
169
170/*
171 * Verify that getScanStats returns without any errors
172 */
173TEST_F(WifiOffloadHidlTest, getScanStats) {
174    const auto& result = HIDL_INVOKE(wifi_offload_, getScanStats);
175    OffloadStatus status = result.first;
176    ASSERT_EQ(OffloadStatusCode::OK, status.code);
177}
178
179/*
180 * Verify that onScanResult callback is invoked
181 */
182TEST_F(WifiOffloadHidlTest, getScanResults) {
183    wifi_offload_->setEventCallback(wifi_offload_cb_);
184    std::vector<ScanResult> scan_results;
185    std::vector<uint8_t> ssid(kSsid1, kSsid1 + sizeof(kSsid1));
186    ScanResult scan_result;
187    scan_result.tsf = kTsf;
188    scan_result.rssi = kRssi;
189    scan_result.frequency = kFrequency;
190    scan_result.capability = kCapability;
191    memcpy(&scan_result.bssid[0], &kBssid[0], kBssidSize);
192    scan_result.networkInfo.ssid = ssid;
193    scan_result.networkInfo.flags = kNetworkFlags;
194    scan_results.push_back(scan_result);
195    wifi_offload_cb_->onScanResult(scan_results);
196    auto res =
197        wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendScanResult);
198    ASSERT_EQ(true, res.no_timeout);
199}
200
201/*
202 * Verify that onError callback is invoked
203 */
204TEST_F(WifiOffloadHidlTest, getError) {
205    wifi_offload_->setEventCallback(wifi_offload_cb_);
206    OffloadStatus status = {OffloadStatusCode::ERROR, ""};
207    wifi_offload_cb_->onError(status);
208    auto res = wifi_offload_cb_->WaitForCallback(kOffloadCallbackSendError);
209    ASSERT_EQ(true, res.no_timeout);
210}
211
212// A class for test environment setup
213class WifiOffloadHalHidlEnvironment : public ::testing::Environment {
214   public:
215    virtual void SetUp() {}
216    virtual void TearDown() {}
217};
218
219int main(int argc, char** argv) {
220    ::testing::AddGlobalTestEnvironment(new WifiOffloadHalHidlEnvironment);
221    ::testing::InitGoogleTest(&argc, argv);
222
223    int status = RUN_ALL_TESTS();
224    LOG(INFO) << "Test result = " << status;
225
226    return status;
227}
228