| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * 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 <general_test/basic_wifi_test.h> |
| |
| #include <algorithm> |
| #include <cmath> |
| |
| #include <chre.h> |
| #include <shared/macros.h> |
| #include <shared/send_message.h> |
| #include <shared/time_util.h> |
| |
| #include "chre/util/nanoapp/log.h" |
| #include "chre/util/time.h" |
| #include "chre/util/unique_ptr.h" |
| |
| using nanoapp_testing::sendFatalFailureToHost; |
| using nanoapp_testing::sendFatalFailureToHostUint8; |
| using nanoapp_testing::sendSuccessToHost; |
| |
| #define LOG_TAG "[BasicWifiTest]" |
| |
| /* |
| * Test to check expected functionality of the CHRE WiFi APIs. |
| * |
| * 1. If scan monitor is not supported, skip to 5; |
| * otherwise enables scan monitor. |
| * 2. Checks async result of enabling scan monitor. |
| * 3. Disables scan monitor. |
| * 4. Checks async result of disabling scan monitor. |
| * 5. If on demand WiFi scan is not supported, skip to end; |
| * otherwise sends default scan request. |
| * 6. Checks the result of on demand WiFi scan. |
| */ |
| namespace general_test { |
| |
| namespace { |
| |
| //! A fake/unused cookie to pass into the enable configure scan monitoring async |
| //! request. |
| constexpr uint32_t kEnableScanMonitoringCookie = 0x1337; |
| |
| //! A fake/unused cookie to pass into the disable configure scan monitoring |
| //! async request. |
| constexpr uint32_t kDisableScanMonitoringCookie = 0x1338; |
| |
| //! A fake/unused cookie to pass into request ranging async. |
| constexpr uint32_t kRequestRangingCookie = 0xefac; |
| |
| //! A fake/unused cookie to pass into request scan async. |
| constexpr uint32_t kOnDemandScanCookie = 0xcafe; |
| |
| //! Starting frequency of band 2.4 GHz |
| constexpr uint32_t kWifiBandStartFreq_2_4_GHz = 2407; |
| |
| //! Starting frequency of band 5 GHz |
| constexpr uint32_t kWifiBandStartFreq_5_GHz = 5000; |
| |
| //! Frequency of channel 14 |
| constexpr uint32_t kWifiBandFreqOfChannel_14 = 2484; |
| |
| //! The amount of time to allow between an operation timing out and the event |
| //! being deliverd to the test. |
| constexpr uint32_t kTimeoutWiggleRoomNs = 2 * chre::kOneSecondInNanoseconds; |
| |
| /** |
| * Calls API testConfigureScanMonitorAsync. Sends fatal failure to host |
| * if API call fails. |
| * |
| * @param enable Set to true to enable monitoring scan results, |
| * false to disable. |
| * @param cookie An opaque value that will be included in the chreAsyncResult |
| * sent in relation to this request. |
| */ |
| void testConfigureScanMonitorAsync(bool enable, const void *cookie) { |
| if (!chreWifiConfigureScanMonitorAsync(enable, cookie)) { |
| if (enable) { |
| sendFatalFailureToHost("Failed to request to enable scan monitor."); |
| } else { |
| sendFatalFailureToHost("Failed to request to disable scan monitor."); |
| } |
| } |
| } |
| |
| /** |
| * Calls API chreWifiRequestScanAsyncDefault. Sends fatal failure to host |
| * if API call fails. |
| */ |
| void testRequestScanAsync() { |
| // Request a fresh scan to ensure the correct scan type is performed. |
| constexpr struct chreWifiScanParams kParams = { |
| /*.scanType=*/CHRE_WIFI_SCAN_TYPE_ACTIVE, |
| /*.maxScanAgeMs=*/0, // 0 seconds |
| /*.frequencyListLen=*/0, |
| /*.frequencyList=*/NULL, |
| /*.ssidListLen=*/0, |
| /*.ssidList=*/NULL, |
| /*.radioChainPref=*/CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT, |
| /*.channelSet=*/CHRE_WIFI_CHANNEL_SET_NON_DFS}; |
| |
| if (!chreWifiRequestScanAsync(&kParams, &kOnDemandScanCookie)) { |
| sendFatalFailureToHost("Failed to request for on-demand WiFi scan."); |
| } |
| } |
| |
| /** |
| * Calls API chreWifiRequestRangingAsync. Sends fatal failure to host if the |
| * API call fails. |
| */ |
| void testRequestRangingAsync(const struct chreWifiScanResult *aps, |
| uint8_t length) { |
| // Sending an array larger than CHRE_WIFI_RANGING_LIST_MAX_LEN will cause |
| // an immediate failure. |
| uint8_t targetLength = |
| std::min(length, static_cast<uint8_t>(CHRE_WIFI_RANGING_LIST_MAX_LEN)); |
| |
| void *array = chreHeapAlloc(sizeof(chreWifiRangingTarget) * targetLength); |
| ASSERT_NE(array, nullptr, |
| "Failed to allocate array for issuing a ranging request"); |
| |
| chre::UniquePtr<struct chreWifiRangingTarget> targetList( |
| static_cast<struct chreWifiRangingTarget *>(array)); |
| |
| // Save the last spot for any available RTT APs in case they didn't make it |
| // in the array earlier. This first loop allows non-RTT compatible APs as a |
| // way to test that the driver implementation will return failure for only |
| // those APs and success for valid RTT APs. |
| for (uint8_t i = 0; i < targetLength - 1; i++) { |
| chreWifiRangingTargetFromScanResult(&aps[i], &targetList[i]); |
| } |
| |
| for (uint8_t i = targetLength - 1; i < length; i++) { |
| if ((aps[i].flags & CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER) == |
| CHRE_WIFI_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER || |
| i == (length - 1)) { |
| chreWifiRangingTargetFromScanResult(&aps[i], |
| &targetList[targetLength - 1]); |
| break; |
| } |
| } |
| |
| struct chreWifiRangingParams params = {.targetListLen = targetLength, |
| .targetList = targetList.get()}; |
| if (!chreWifiRequestRangingAsync(¶ms, &kRequestRangingCookie)) { |
| sendFatalFailureToHost( |
| "Failed to request ranging for a list of WiFi scans."); |
| } |
| } |
| |
| /** |
| * Validates primaryChannel and sends fatal failure to host if failing. |
| * 1. (primaryChannel - start frequecny) is a multiple of 5. |
| * 2. primaryChannelNumber is multiple of 5 and between [1, maxChannelNumber]. |
| * |
| * @param primaryChannel primary channel of a WiFi scan result. |
| * @param startFrequency start frequency of band 2.4/5 GHz. |
| * @param maxChannelNumber max channel number of band 2.4/5 GHz. |
| */ |
| void validatePrimaryChannel(uint32_t primaryChannel, uint32_t startFrequency, |
| uint8_t maxChannelNumber) { |
| if ((primaryChannel - startFrequency) % 5 != 0) { |
| chreLog(CHRE_LOG_ERROR, |
| "primaryChannel - %" PRIu32 |
| " must be a multiple of 5," |
| "got primaryChannel: %" PRIu32, |
| startFrequency, primaryChannel); |
| } |
| |
| uint32_t primaryChannelNumber = (primaryChannel - startFrequency) / 5; |
| if (primaryChannelNumber < 1 || primaryChannelNumber > maxChannelNumber) { |
| chreLog(CHRE_LOG_ERROR, |
| "primaryChannelNumber must be between 1 and %" PRIu8 |
| "," |
| "got primaryChannel: %" PRIu32, |
| maxChannelNumber, primaryChannel); |
| } |
| } |
| |
| /** |
| * Validates primaryChannel for band 2.4/5 GHz. |
| * |
| * primaryChannelNumber of band 2.4 GHz is between 1 and 13, |
| * plus a special case for channel 14 (primaryChannel == 2484); |
| * primaryChannelNumber of band 5 GHz is between 1 and 200, |
| * ref: IEEE Std 802.11-2016, 19.3.15.2. |
| * Also, (primaryChannel - start frequecny) is a multiple of 5, |
| * except channel 14 of 2.4 GHz. |
| * |
| * @param result WiFi scan result. |
| */ |
| void validatePrimaryChannel(const chreWifiScanResult &result) { |
| // channel 14 (primaryChannel = 2484) is not applicable for this test. |
| if (result.band == CHRE_WIFI_BAND_2_4_GHZ && |
| result.primaryChannel != kWifiBandFreqOfChannel_14) { |
| validatePrimaryChannel(result.primaryChannel, kWifiBandStartFreq_2_4_GHz, |
| 13); |
| } else if (result.band == CHRE_WIFI_BAND_5_GHZ) { |
| validatePrimaryChannel(result.primaryChannel, kWifiBandStartFreq_5_GHz, |
| 200); |
| } |
| } |
| |
| /** |
| * Validates centerFreqPrimary and centerFreqSecondary |
| * TODO (jacksun) add test when channelWidth is 20, 40, 80, or 160 MHz |
| */ |
| void validateCenterFreq(const chreWifiScanResult &result) { |
| if (result.channelWidth != CHRE_WIFI_CHANNEL_WIDTH_80_PLUS_80_MHZ && |
| result.centerFreqSecondary != 0) { |
| // TODO (jacksun) Format the centerFreqSecondary into the message |
| // after redesigning of sendFatalFailureToHost() |
| sendFatalFailureToHost( |
| "centerFreqSecondary must be 0 if channelWidth is not 80+80MHZ"); |
| } |
| } |
| |
| /** |
| * Validates that RSSI is within sane limits. |
| */ |
| void validateRssi(int8_t rssi) { |
| // It's possible for WiFi RSSI to be positive if the phone is placed |
| // right next to a high-power AP (e.g. transmitting at 20 dBm), |
| // in which case RSSI will be < 20 dBm. Place a high threshold to check |
| // against values likely to be erroneous (36 dBm/4W). |
| ASSERT_LT(rssi, 36, "RSSI is greater than 36"); |
| } |
| |
| /** |
| * Validates that the amount of access points ranging was requested for matches |
| * the number of ranging results returned. Also, verifies that the BSSID of |
| * the each access point is present in the ranging results. |
| */ |
| void validateRangingEventArray(const struct chreWifiScanResult *results, |
| size_t resultsSize, |
| const struct chreWifiRangingEvent *event) { |
| size_t expectedArraySize = std::min( |
| resultsSize, static_cast<size_t>(CHRE_WIFI_RANGING_LIST_MAX_LEN)); |
| ASSERT_EQ(event->resultCount, expectedArraySize, |
| "RTT ranging result count was not the same as the requested target " |
| "list size"); |
| |
| uint8_t matchesFound = 0; |
| |
| for (size_t i = 0; i < resultsSize; i++) { |
| for (size_t j = 0; j < expectedArraySize; j++) { |
| if (memcmp(results[i].bssid, event->results[j].macAddress, |
| CHRE_WIFI_BSSID_LEN) == 0) { |
| matchesFound++; |
| break; |
| } |
| } |
| } |
| |
| ASSERT_EQ( |
| matchesFound, expectedArraySize, |
| "BSSID(s) from the ranging request were not found in the ranging result"); |
| } |
| |
| /** |
| * Validates the location configuration information returned by a ranging result |
| * is compliant with the formatting specified at @see chreWifiLci. |
| */ |
| void validateLci(const struct chreWifiRangingResult::chreWifiLci *lci) { |
| // Per RFC 6225 2.3, there are 25 fractional bits and up to 9 integer bits |
| // used for lat / lng so verify that no bits outside those are used. |
| constexpr int64_t kMaxLat = INT64_C(90) << 25; |
| constexpr int64_t kMaxLng = INT64_C(180) << 25; |
| ASSERT_IN_RANGE(lci->latitude, -1 * kMaxLat, kMaxLat, |
| "LCI's latitude is outside the range of -90 to 90"); |
| ASSERT_IN_RANGE(lci->longitude, -1 * kMaxLng, kMaxLng, |
| "LCI's longitude is outside the range of -180 to 180"); |
| |
| // According to RFC 6225, values greater than 34 are reserved |
| constexpr uint8_t kMaxLatLngUncertainty = 34; |
| ASSERT_LE(lci->latitudeUncertainty, kMaxLatLngUncertainty, |
| "LCI's latitude uncertainty is greater than 34"); |
| ASSERT_LE(lci->longitudeUncertainty, kMaxLatLngUncertainty, |
| "LCI's longitude uncertainty is greater than 34"); |
| |
| if (lci->altitudeType == CHRE_WIFI_LCI_ALTITUDE_TYPE_METERS) { |
| // Highest largely populated city in the world, El Alto, Bolivia, is 4300 |
| // meters and the tallest building in the world is 828 meters so the upper |
| // bound for this range should be 5500 meters (contains some padding). |
| constexpr int32_t kMaxAltitudeMeters = 5500 << 8; |
| |
| // Lowest largely populated city in the world, Baku, Azerbaijan, is 28 |
| // meters below sea level so -100 meters should be a good lower bound. |
| constexpr int32_t kMinAltitudeMeters = (100 << 8) * -1; |
| ASSERT_IN_RANGE( |
| lci->altitude, kMinAltitudeMeters, kMaxAltitudeMeters, |
| "LCI's altitude is outside of the range of -25 to 500 meters"); |
| |
| // According to RFC 6225, values greater than 30 are reserved |
| constexpr uint8_t kMaxAltitudeUncertainty = 30; |
| ASSERT_LE(lci->altitudeUncertainty, kMaxAltitudeUncertainty, |
| "LCI's altitude certainty is greater than 30"); |
| } else if (lci->altitudeType == CHRE_WIFI_LCI_ALTITUDE_TYPE_FLOORS) { |
| // Tallest building has 163 floors. Assume -5 to 100 floors is a sane range. |
| constexpr int32_t kMaxAltitudeFloors = 100 << 8; |
| constexpr int32_t kMinAltitudeFloors = (5 << 8) * -1; |
| ASSERT_IN_RANGE( |
| lci->altitude, kMinAltitudeFloors, kMaxAltitudeFloors, |
| "LCI's altitude is outside of the range of -5 to 100 floors"); |
| } else if (lci->altitudeType != CHRE_WIFI_LCI_ALTITUDE_TYPE_UNKNOWN) { |
| sendFatalFailureToHost( |
| "LCI's altitude type was not unknown, floors, or meters"); |
| } |
| } |
| |
| } // anonymous namespace |
| |
| BasicWifiTest::BasicWifiTest() : Test(CHRE_API_VERSION_1_1) {} |
| |
| void BasicWifiTest::setUp(uint32_t messageSize, const void * /* message */) { |
| if (messageSize != 0) { |
| sendFatalFailureToHost("Expected 0 byte message, got more bytes:", |
| &messageSize); |
| } else { |
| mWifiCapabilities = chreWifiGetCapabilities(); |
| startScanMonitorTestStage(); |
| } |
| } |
| |
| void BasicWifiTest::handleEvent(uint32_t /* senderInstanceId */, |
| uint16_t eventType, const void *eventData) { |
| ASSERT_NE(eventData, nullptr, "Received null eventData"); |
| switch (eventType) { |
| case CHRE_EVENT_WIFI_ASYNC_RESULT: |
| handleChreWifiAsyncEvent(static_cast<const chreAsyncResult *>(eventData)); |
| break; |
| case CHRE_EVENT_WIFI_SCAN_RESULT: { |
| if (!scanEventExpected()) { |
| sendFatalFailureToHost("WiFi scan event received when not requested"); |
| } |
| const auto *result = static_cast<const chreWifiScanEvent *>(eventData); |
| |
| if (!isActiveWifiScanType(result)) { |
| LOGW("Received unexpected scan type %" PRIu8, result->scanType); |
| } |
| |
| // The first chreWifiScanResult is expected to come immediately, |
| // but a long delay is possible if it's implemented incorrectly, |
| // e.g. the async result comes right away (before the scan is actually |
| // completed), then there's a long delay to the scan result. |
| constexpr uint64_t maxDelayNs = 100 * chre::kOneMillisecondInNanoseconds; |
| bool delayExceeded = (mStartTimestampNs != 0) && |
| (chreGetTime() - mStartTimestampNs > maxDelayNs); |
| if (delayExceeded) { |
| sendFatalFailureToHost( |
| "Did not receive chreWifiScanResult within 100 milliseconds."); |
| } |
| // Do not reset mStartTimestampNs here, because it is used for the |
| // subsequent RTT ranging timestamp validation. |
| validateWifiScanEvent(result); |
| break; |
| } |
| case CHRE_EVENT_WIFI_RANGING_RESULT: { |
| if (!rangingEventExpected()) { |
| sendFatalFailureToHost( |
| "WiFi ranging event received when not requested"); |
| } |
| const auto *result = static_cast<const chreWifiRangingEvent *>(eventData); |
| // Allow some wiggle room between the expected timeout and when the event |
| // would actually be delivered to the test. |
| if (mStartTimestampNs != 0 && |
| chreGetTime() - mStartTimestampNs > |
| CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS + kTimeoutWiggleRoomNs) { |
| sendFatalFailureToHost( |
| "Did not receive chreWifiRangingEvent within the ranging timeout"); |
| } |
| validateRangingEvent(result); |
| // Ensure timestamp is reset after everything is validated as it's used to |
| // validate the ranging event |
| mStartTimestampNs = 0; |
| mTestSuccessMarker.markStageAndSuccessOnFinish( |
| BASIC_WIFI_TEST_STAGE_SCAN_RTT); |
| break; |
| } |
| default: |
| unexpectedEvent(eventType); |
| break; |
| } |
| } |
| |
| void BasicWifiTest::handleChreWifiAsyncEvent(const chreAsyncResult *result) { |
| if (!mCurrentWifiRequest.has_value()) { |
| nanoapp_testing::sendFailureToHost("Unexpected async result"); |
| } |
| |
| validateChreAsyncResult(result, mCurrentWifiRequest.value()); |
| |
| switch (result->requestType) { |
| case CHRE_WIFI_REQUEST_TYPE_RANGING: |
| // Reuse same start timestamp as the scan request since ranging fields |
| // may be retrieved automatically as part of that scan. |
| break; |
| case CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN: |
| mStartTimestampNs = chreGetTime(); |
| break; |
| case CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR: |
| if (mCurrentWifiRequest->cookie == &kDisableScanMonitoringCookie) { |
| mTestSuccessMarker.markStageAndSuccessOnFinish( |
| BASIC_WIFI_TEST_STAGE_SCAN_MONITOR); |
| startScanAsyncTestStage(); |
| } else { |
| testConfigureScanMonitorAsync(false /* enable */, |
| &kDisableScanMonitoringCookie); |
| resetCurrentWifiRequest(&kDisableScanMonitoringCookie, |
| CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR, |
| CHRE_ASYNC_RESULT_TIMEOUT_NS); |
| } |
| break; |
| default: |
| sendFatalFailureToHostUint8("Received unexpected requestType %d", |
| result->requestType); |
| break; |
| } |
| } |
| |
| bool BasicWifiTest::isActiveWifiScanType(const chreWifiScanEvent *eventData) { |
| return (eventData->scanType == CHRE_WIFI_SCAN_TYPE_ACTIVE); |
| } |
| |
| void BasicWifiTest::startScanMonitorTestStage() { |
| if (mWifiCapabilities & CHRE_WIFI_CAPABILITIES_SCAN_MONITORING) { |
| testConfigureScanMonitorAsync(true /* enable */, |
| &kEnableScanMonitoringCookie); |
| resetCurrentWifiRequest(&kEnableScanMonitoringCookie, |
| CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR, |
| CHRE_ASYNC_RESULT_TIMEOUT_NS); |
| } else { |
| mTestSuccessMarker.markStageAndSuccessOnFinish( |
| BASIC_WIFI_TEST_STAGE_SCAN_MONITOR); |
| startScanAsyncTestStage(); |
| } |
| } |
| |
| void BasicWifiTest::startScanAsyncTestStage() { |
| if (mWifiCapabilities & CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN) { |
| testRequestScanAsync(); |
| resetCurrentWifiRequest(&kOnDemandScanCookie, |
| CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN, |
| CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS); |
| } else { |
| mTestSuccessMarker.markStageAndSuccessOnFinish( |
| BASIC_WIFI_TEST_STAGE_SCAN_ASYNC); |
| startRangingAsyncTestStage(); |
| } |
| } |
| |
| void BasicWifiTest::startRangingAsyncTestStage() { |
| // If no scans were received, the test has nothing to range with so simply |
| // mark it as a success. |
| if (mWifiCapabilities & CHRE_WIFI_CAPABILITIES_RTT_RANGING && |
| mLatestWifiScanResults.size() != 0) { |
| testRequestRangingAsync(mLatestWifiScanResults.data(), |
| mLatestWifiScanResults.size()); |
| resetCurrentWifiRequest(&kRequestRangingCookie, |
| CHRE_WIFI_REQUEST_TYPE_RANGING, |
| CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS); |
| } else { |
| mTestSuccessMarker.markStageAndSuccessOnFinish( |
| BASIC_WIFI_TEST_STAGE_SCAN_RTT); |
| } |
| } |
| |
| void BasicWifiTest::resetCurrentWifiRequest(const void *cookie, |
| uint8_t requestType, |
| uint64_t timeoutNs) { |
| chreAsyncRequest request = {.cookie = cookie, |
| .requestType = requestType, |
| .requestTimeNs = chreGetTime(), |
| .timeoutNs = timeoutNs}; |
| mCurrentWifiRequest = request; |
| } |
| |
| void BasicWifiTest::validateWifiScanEvent(const chreWifiScanEvent *eventData) { |
| if (eventData->version != CHRE_WIFI_SCAN_EVENT_VERSION) { |
| sendFatalFailureToHostUint8("Got unexpected scan event version %d", |
| eventData->version); |
| } |
| |
| if (mNextExpectedIndex != eventData->eventIndex) { |
| chreLog(CHRE_LOG_ERROR, |
| "Expected index: %" PRIu32 ", received index: %" PRIu8, |
| mNextExpectedIndex, eventData->eventIndex); |
| sendFatalFailureToHost("Received out-of-order events"); |
| } |
| mNextExpectedIndex++; |
| |
| if (eventData->eventIndex == 0) { |
| mWiFiScanResultRemaining = eventData->resultTotal; |
| } |
| if (mWiFiScanResultRemaining < eventData->resultCount) { |
| chreLog(CHRE_LOG_ERROR, |
| "Remaining scan results %" PRIu32 ", received %" PRIu8, |
| mWiFiScanResultRemaining, eventData->resultCount); |
| sendFatalFailureToHost("Received too many WiFi scan results"); |
| } |
| mWiFiScanResultRemaining -= eventData->resultCount; |
| |
| validateWifiScanResult(eventData->resultCount, eventData->results); |
| |
| // Save the latest results for future tests retaining old data if the new |
| // scan is empty (so the test has something to use). |
| if (eventData->resultCount > 0) { |
| mLatestWifiScanResults.copy_array(eventData->results, |
| eventData->resultCount); |
| } |
| |
| if (mWiFiScanResultRemaining == 0) { |
| mNextExpectedIndex = 0; |
| mTestSuccessMarker.markStageAndSuccessOnFinish( |
| BASIC_WIFI_TEST_STAGE_SCAN_ASYNC); |
| startRangingAsyncTestStage(); |
| } |
| } |
| |
| void BasicWifiTest::validateWifiScanResult(uint8_t count, |
| const chreWifiScanResult *results) { |
| for (uint8_t i = 0; i < count; ++i) { |
| if (results[i].ssidLen > CHRE_WIFI_SSID_MAX_LEN) { |
| sendFatalFailureToHostUint8("Got unexpected ssidLen %d", |
| results[i].ssidLen); |
| } |
| |
| // TODO: Enable fatal failures on band, RSSI, and primary channel |
| // validations when proper error waiver is implemented in CHQTS. |
| if (results[i].band != CHRE_WIFI_BAND_2_4_GHZ && |
| results[i].band != CHRE_WIFI_BAND_5_GHZ) { |
| chreLog(CHRE_LOG_ERROR, "Got unexpected band %d", results[i].band); |
| } |
| |
| validateRssi(results[i].rssi); |
| |
| validatePrimaryChannel(results[i]); |
| validateCenterFreq(results[i]); |
| } |
| } |
| |
| void BasicWifiTest::validateRangingEvent( |
| const chreWifiRangingEvent *eventData) { |
| if (eventData->version != CHRE_WIFI_RANGING_EVENT_VERSION) { |
| sendFatalFailureToHostUint8("Got unexpected ranging event version %d", |
| eventData->version); |
| } |
| |
| validateRangingEventArray(mLatestWifiScanResults.data(), |
| mLatestWifiScanResults.size(), eventData); |
| |
| for (uint8_t i = 0; i < eventData->resultCount; i++) { |
| auto &result = eventData->results[i]; |
| ASSERT_IN_RANGE(result.timestamp, mStartTimestampNs, chreGetTime(), |
| "Ranging result timestamp isn't between the ranging " |
| "request start time and the current time"); |
| |
| if (result.status != CHRE_WIFI_RANGING_STATUS_SUCCESS) { |
| if (result.rssi != 0 || result.distance != 0 || |
| result.distanceStdDev != 0) { |
| sendFatalFailureToHost( |
| "Ranging result with failure status had non-zero state"); |
| } |
| } else { |
| validateRssi(result.rssi); |
| |
| constexpr uint32_t kMaxDistanceMillimeters = 100 * 1000; |
| if (result.distance > kMaxDistanceMillimeters) { |
| sendFatalFailureToHost( |
| "Ranging result was more than 100 meters away %" PRIu32, |
| &result.distance); |
| } |
| |
| constexpr uint32_t kMaxStdDevMillimeters = 10 * 1000; |
| if (result.distanceStdDev > kMaxStdDevMillimeters) { |
| sendFatalFailureToHost( |
| "Ranging result distance stddev was more than 10 meters %" PRIu32, |
| &result.distanceStdDev); |
| } |
| |
| if (result.flags & CHRE_WIFI_RTT_RESULT_HAS_LCI) { |
| validateLci(&result.lci); |
| } |
| } |
| } |
| } |
| |
| bool BasicWifiTest::rangingEventExpected() { |
| return mTestSuccessMarker.isStageMarked(BASIC_WIFI_TEST_STAGE_SCAN_ASYNC) && |
| !mTestSuccessMarker.isStageMarked(BASIC_WIFI_TEST_STAGE_SCAN_RTT); |
| } |
| |
| bool BasicWifiTest::scanEventExpected() { |
| return mTestSuccessMarker.isStageMarked(BASIC_WIFI_TEST_STAGE_SCAN_MONITOR) && |
| !mTestSuccessMarker.isStageMarked(BASIC_WIFI_TEST_STAGE_SCAN_ASYNC); |
| } |
| |
| } // namespace general_test |