From 2611844e98f9fb2fdbd5426fb233a049b02a83a2 Mon Sep 17 00:00:00 2001 From: Sohani Rao Date: Wed, 26 Jul 2017 14:04:05 -0700 Subject: [PATCH 1/6] Offload HAL Service: Utilities Provides the implementation of utilities to convert between HIDL format of data types used in Offload HAL service and the format used by CHRE. Added unit tests to verify conversions. Bug: 32842314 Test: VTS and Unit tests Change-Id: I26a1d9a8efe68cdacacd8226d0739ad40d2b339f Merged-In: I26a1d9a8efe68cdacacd8226d0739ad40d2b339f --- wifi_offload/Android.bp | 10 +- wifi_offload/offload_utils.cpp | 285 ++++++++++++++++++ wifi_offload/offload_utils.h | 30 ++ .../test/offload_hal_test_constants.cpp | 91 ++++++ .../test/offload_hal_test_constants.h | 74 +++++ wifi_offload/test/offload_hal_test_utils.cpp | 200 ++++++++++++ wifi_offload/test/offload_hal_test_utils.h | 47 +++ wifi_offload/test/offload_utils_test.cpp | 73 +++++ 8 files changed, 809 insertions(+), 1 deletion(-) create mode 100644 wifi_offload/offload_utils.cpp create mode 100644 wifi_offload/offload_utils.h create mode 100644 wifi_offload/test/offload_hal_test_constants.cpp create mode 100644 wifi_offload/test/offload_hal_test_constants.h create mode 100644 wifi_offload/test/offload_hal_test_utils.cpp create mode 100644 wifi_offload/test/offload_hal_test_utils.h create mode 100644 wifi_offload/test/offload_utils_test.cpp diff --git a/wifi_offload/Android.bp b/wifi_offload/Android.bp index 8f466e52..8ff578f5 100644 --- a/wifi_offload/Android.bp +++ b/wifi_offload/Android.bp @@ -22,6 +22,7 @@ cc_library_static { "offload_server.cpp", "chre_interface_factory.cpp", "offload_status_util.cpp", + "offload_utils.cpp", ], cflags: ["-Wall", "-Wextra"], shared_libs: [ @@ -33,7 +34,8 @@ cc_library_static { "android.hardware.wifi.offload@1.0", ], whole_static_libs: [ - "chre_client" + "chre_client", + "wifi_offload_types", ] } @@ -68,6 +70,9 @@ cc_test { "test/mock_chre_interface.cpp", "test/offload_server_test.cpp", "test/chre_interface_test.cpp", + "test/offload_utils_test.cpp", + "test/offload_hal_test_constants.cpp", + "test/offload_hal_test_utils.cpp", ], local_include_dirs: [ "test", @@ -87,5 +92,8 @@ cc_test { "libgtest", "android.hardware.wifi.offload@1.0-lib", ], + whole_static_libs: [ + "wifi_offload_types", + ], } diff --git a/wifi_offload/offload_utils.cpp b/wifi_offload/offload_utils.cpp new file mode 100644 index 00000000..90d4b9ae --- /dev/null +++ b/wifi_offload/offload_utils.cpp @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2016, 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 "offload_utils.h" + +#include +#include + +namespace { + +bool ToHidlRecordName(const wifi_offload::RpcLogRecord::RpcLogRecordType& chreRecordType, + android::hardware::wifi::offload::V1_0::RecordName* hidlRecordName) { + bool result = true; + switch (chreRecordType) { + case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_INIT: + *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::CMD_INT; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_CONFIG_SCANS: + *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::CMD_CONFIG_SCANS; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_SUBSCRIBE_SCAN_RESULTS: + *hidlRecordName = + android::hardware::wifi::offload::V1_0::RecordName::CMD_SUBSCRIBE_SCAN_RESULTS; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_UNSUBSCRIBE_SCAN_RESULTS: + *hidlRecordName = + android::hardware::wifi::offload::V1_0::RecordName::CMD_UNSUBSCRIBE_SCAN_RESULTS; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_GET_SCAN_STATS: + *hidlRecordName = + android::hardware::wifi::offload::V1_0::RecordName::CMD_GET_SCAN_STATS; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_RESET: + *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::CMD_RESET; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_RECVD_SCAN_RESULT_ASYNC: + *hidlRecordName = + android::hardware::wifi::offload::V1_0::RecordName::EVENT_RECVD_SCAN_RESULT_ASYNC; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_RECVD_SCAN_RESULT: + *hidlRecordName = + android::hardware::wifi::offload::V1_0::RecordName::EVENT_RECVD_SCAN_RESULT; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_SCAN_RESULT: + *hidlRecordName = + android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_SCAN_RESULT; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_ABORT: + *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_ABORT; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_ERROR: + *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_ERROR; + break; + case wifi_offload::RpcLogRecord::RpcLogRecordType::REQ_SCAN: + *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::REQ_SCAN; + break; + default: + result = false; + break; + } + return result; +} + +uint8_t ToChreSecurityMode(uint8_t hidlSecurityMode) { + uint8_t chreSecurityMode = 0; + if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::OPEN) { + chreSecurityMode |= wifi_offload::SecurityMode::OPEN; + } + if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::WEP) { + chreSecurityMode |= wifi_offload::SecurityMode::WEP; + } + if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::PSK) { + chreSecurityMode |= wifi_offload::SecurityMode::PSK; + } + if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::EAP) { + chreSecurityMode |= wifi_offload::SecurityMode::EAP; + } + return chreSecurityMode; +} + +uint8_t ToHidlSecurityMode(uint8_t chreSecurityMode) { + uint8_t hidlSecurityMode = 0; + if (chreSecurityMode & wifi_offload::SecurityMode::OPEN) { + hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::OPEN; + } + if (chreSecurityMode & wifi_offload::SecurityMode::WEP) { + hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::WEP; + } + if (chreSecurityMode & wifi_offload::SecurityMode::PSK) { + hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::PSK; + } + if (chreSecurityMode & wifi_offload::SecurityMode::EAP) { + hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::EAP; + } + return hidlSecurityMode; +} + +} // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace offload { +namespace V1_0 { +namespace implementation { +namespace offload_utils { + +bool ToHidlScanResult(const wifi_offload::ScanResult& chreScanResult, ScanResult* hidlScanResult) { + if (hidlScanResult == nullptr) { + return false; + } + hidlScanResult->tsf = chreScanResult.tsf_; + hidlScanResult->capability = chreScanResult.capability_; + hidlScanResult->rssi = chreScanResult.rssi_dbm_; + hidlScanResult->frequency = chreScanResult.frequency_scanned_mhz_; + memcpy(&hidlScanResult->bssid[0], &chreScanResult.bssid_[0], + wifi_offload::ScanResult::kBssidSize); + chreWifiSsidListItem chreWifiSsid; + chreScanResult.ssid_.ToChreWifiSsidListItem(&chreWifiSsid); + std::vector ssid; + for (size_t i = 0; i < chreWifiSsid.ssidLen; i++) { + ssid.push_back(chreWifiSsid.ssid[i]); + } + hidlScanResult->networkInfo.ssid = ssid; + hidlScanResult->networkInfo.flags = ToHidlSecurityMode(chreScanResult.security_modes_); + return true; +} + +bool ToHidlScanResults(const std::vector& chreScanResults, + std::vector* hidlScanResults) { + LOG(VERBOSE) << "ScanResults from CHRE, size=" << chreScanResults.size(); + for (const auto& scan_result_from_nano_app : chreScanResults) { + ScanResult hidl_scan_result; + if (!ToHidlScanResult(scan_result_from_nano_app, &hidl_scan_result)) { + return false; + } + hidlScanResults->push_back(hidl_scan_result); + } + return true; +} + +bool ToHidlScanStats(const wifi_offload::ScanStats& chreScanStats, ScanStats* hidlScanStats) { + hidlScanStats->subscriptionDurationMs = chreScanStats.last_subscription_duration_ms_; + hidlScanStats->numScansRequestedByWifi = chreScanStats.num_scans_requested_by_nanoapp_; + hidlScanStats->numScansServicedByWifi = chreScanStats.num_scans_serviced_by_hardware_; + hidlScanStats->numScansServicedbyCache = chreScanStats.num_scans_serviced_by_cache_; + std::vector hidlScanRecords; + for (const auto& chreScanRecord : chreScanStats.scan_records_) { + ScanRecord hidlScanRecord; + hidlScanRecord.durationMs = chreScanRecord.time_spent_scanning_ms_; + hidlScanRecord.numChannelsScanned = chreScanRecord.num_channels_scanned_; + hidlScanRecord.numEntriesAggregated = chreScanRecord.num_entries_aggregated_; + hidlScanRecords.push_back(hidlScanRecord); + } + hidlScanStats->scanRecord = hidlScanRecords; + std::vector logRecords; + for (const auto& chreLogRecord : chreScanStats.rpc_log_records_) { + LogRecord logRecord; + if (!ToHidlRecordName(chreLogRecord.record_type_, &logRecord.recordName)) { + return false; + } + logRecord.logTimeMs = chreLogRecord.timestamp_chre_ms_; + logRecords.push_back(logRecord); + } + hidlScanStats->logRecord = logRecords; + for (size_t i = 0; i < hidlScanStats->histogramChannelsScanned.elementCount(); i++) { + hidlScanStats->histogramChannelsScanned[i] = + chreScanStats.channel_histogram_.GetChannelScanCount(i); + } + return true; +} + +bool ToChreScanConfig(const ScanParam& param, const ScanFilter& filter, + wifi_offload::ScanConfig* scanConfig) { + scanConfig->scan_params_.disconnected_mode_scan_interval_ms_ = + param.disconnectedModeScanIntervalMs; + for (const auto& ssid : param.ssidList) { + wifi_offload::Ssid chreSsid; + chreSsid.SetData(ssid.data(), ssid.size()); + scanConfig->scan_params_.ssids_to_scan_.push_back(chreSsid); + } + for (const auto& freq : param.frequencyList) { + scanConfig->scan_params_.frequencies_to_scan_mhz_.push_back(freq); + } + scanConfig->scan_filter_.min_rssi_threshold_dbm_ = filter.rssiThreshold; + for (const auto& nwInfo : filter.preferredNetworkInfoList) { + wifi_offload::PreferredNetwork chreNwInfo; + chreNwInfo.security_modes_ = ToChreSecurityMode(nwInfo.flags); + chreNwInfo.ssid_.SetData(nwInfo.ssid.data(), nwInfo.ssid.size()); + scanConfig->scan_filter_.networks_to_match_.push_back(std::move(chreNwInfo)); + } + return true; +} + +bool ToHidlErrorMessage(uint32_t errorCode, std::string* errorMessage) { + bool reportError = true; + switch (errorCode) { + case wifi_offload::ErrorCode::FAILED_TO_ALLOCATE_MESSAGE_BUFFER: + *errorMessage = "Failed to allocate message buffer"; + break; + case wifi_offload::ErrorCode::FAILED_TO_SERIALIZE_MESSAGE: + *errorMessage = "Failed to serialize message"; + break; + case wifi_offload::ErrorCode::FAILED_TO_SEND_MESSAGE: + *errorMessage = "Failed to send message"; + break; + case wifi_offload::ErrorCode::FAILED_TO_DESERIALIZE_SCAN_CONFIG: + *errorMessage = "Failed to deserialize scan config"; + break; + case wifi_offload::ErrorCode::INVALID_SUBSCRIBE_MESSAGE_SIZE: + *errorMessage = "Invalid subscribe message size"; + break; + case wifi_offload::ErrorCode::SCAN_CONFIG_NOT_INITIALIZED: + *errorMessage = "Scan config not initialized"; + break; + case wifi_offload::ErrorCode::UNSPECIFIED_HOST_ENDPOINT: + *errorMessage = "Unspecified host end point"; + break; + case wifi_offload::ErrorCode::FAILED_TO_SEND_SCAN_RESULTS: + *errorMessage = "Failed to send scan results"; + break; + case wifi_offload::ErrorCode::FAILED_TO_SEND_SCAN_STATS: + *errorMessage = "Failed to send scan stats"; + break; + case wifi_offload::ErrorCode::ONDEMAND_SCAN_NOT_SUPPORTED: + *errorMessage = "On demand scans not supported"; + break; + case wifi_offload::ErrorCode::FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST: + *errorMessage = "Failed to send on demand scan request"; + break; + case wifi_offload::ErrorCode::FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST_ASYNC: + *errorMessage = "Failed to send on demand scan request async"; + break; + case wifi_offload::ErrorCode::OUT_OF_ORDER_SCAN_RESULTS: + *errorMessage = "Out of order scan results"; + break; + case wifi_offload::ErrorCode::INCOMPLETE_SCAN_RESULTS_BEFORE_SCAN_REQUEST: + *errorMessage = "Incomplete scan results before scan request"; + break; + case wifi_offload::ErrorCode::FAILED_TO_SET_SCAN_TIMER: + *errorMessage = "Failed to set scan timer"; + break; + case wifi_offload::ErrorCode::SCAN_MONITORING_NOT_SUPPORTED: + *errorMessage = "Scan Monitoring not supported"; + break; + case wifi_offload::ErrorCode::FAILED_TO_START_SCAN_MONITORING: + *errorMessage = "Failed to start scan monitoring"; + reportError = false; + break; + case wifi_offload::ErrorCode::FAILED_TO_STOP_SCAN_MONITORING: + *errorMessage = "Failed to stop scan monitoring"; + reportError = false; + break; + case wifi_offload::ErrorCode::FAILED_TO_CONFIGURE_SCAN_MONITORING_ASYNC: + *errorMessage = "Failed to configure scan monitoring async"; + reportError = false; + break; + default: + *errorMessage = "Invalid error code"; + reportError = false; + break; + } + return reportError; +} + +} // namespace offload_utils +} // namespace implementation +} // namespace V1_0 +} // namespace offload +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi_offload/offload_utils.h b/wifi_offload/offload_utils.h new file mode 100644 index 00000000..ef087c9f --- /dev/null +++ b/wifi_offload/offload_utils.h @@ -0,0 +1,30 @@ +#ifndef WIFI_OFFLOAD_SERVER_UTILS_H_ +#define WIFI_OFFLOAD_SERVER_UTILS_H_ + +#include +#include + +namespace android { +namespace hardware { +namespace wifi { +namespace offload { +namespace V1_0 { +namespace implementation { +namespace offload_utils { + +bool ToHidlScanResults(const std::vector& chreScanResults, + std::vector* hidlScanResults); +bool ToHidlScanStats(const wifi_offload::ScanStats& chreScanStats, ScanStats* hildScanStats); +bool ToChreScanConfig(const ScanParam& param, const ScanFilter& filter, + wifi_offload::ScanConfig* scanConfig); +bool ToHidlErrorMessage(uint32_t errorCode, std::string* errorMessage); + +} // namespace offload_utils +} // namespace implementation +} // namespace V1_0 +} // namespace offload +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_OFFLOAD_SERVER_UTILS_H_ diff --git a/wifi_offload/test/offload_hal_test_constants.cpp b/wifi_offload/test/offload_hal_test_constants.cpp new file mode 100644 index 00000000..805090de --- /dev/null +++ b/wifi_offload/test/offload_hal_test_constants.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2017 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 "offload_hal_test_constants.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace offload { +namespace V1_0 { +namespace implementation { +namespace offload_hal_test_constants { + +const uint8_t kSsid1[] = {'G', 'o', 'o', 'g', 'l', 'e'}; +const size_t kSsid1_size = sizeof(kSsid1); +const uint8_t kSsid2[] = {'X', 'f', 'i', 'n', 'i', 't', 'y'}; +const size_t kSsid2_size = sizeof(kSsid2); +const uint8_t kBssid[6] = {0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b}; +const int16_t kRssi = -60; +const int16_t kRssiThreshold = -76; +const uint32_t kFrequency1 = 2412; +const uint32_t kFrequency2 = 2437; +const uint8_t kBssidSize = 6; +const uint64_t kTsf = 0; +const uint16_t kCapability = 0; +const uint8_t kNetworkFlags = 0; +const uint32_t kDisconnectedModeScanIntervalMs = 5000; +const uint64_t kSubscriptionDurationMs = 10000; +const uint64_t kScanDurationMs[2] = {2000, 500}; +const uint32_t kNumChannelsScanned[] = {1, 2}; +const uint8_t kChannelNotScanned = 0; +const uint32_t kDefaultNumScansRequestedByWifi = 2; +const uint32_t kDefaultNumScansServicedByWifi = 2; +const uint64_t kScanDurationTotalMs = 2000; +const uint32_t kNumChannelsTotalScanned = 3; +const uint32_t kNumChannelsInHistogram = 256; +const uint8_t kTestChannels[] = {1, 6, 11}; +const uint32_t kNumTimesChannelScanned[] = {1, 1, 255}; +const uint32_t kSystemStartTime = 32164; +const uint32_t kIncrementBetweenEvents = 10; +const size_t kRecordLength = 8; +const size_t kInvalidRecordLength = 4; + +const wifi_offload::RpcLogRecord::RpcLogRecordType kChreRecordTypeList[] = { + wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_INIT, + wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_CONFIG_SCANS, + wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_SUBSCRIBE_SCAN_RESULTS, + wifi_offload::RpcLogRecord::RpcLogRecordType::REQ_SCAN, + wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_RECVD_SCAN_RESULT, + wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_SCAN_RESULT, + wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_UNSUBSCRIBE_SCAN_RESULTS, + wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_GET_SCAN_STATS, +}; + +const wifi_offload::RpcLogRecord::RpcLogRecordType kInvalidChreRecordTypeLog[] = { + wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_LAST_ITEM, + wifi_offload::RpcLogRecord::RpcLogRecordType::REQ_LAST_ITEM, + wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_RECVD_LAST_ITEM, + wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_LAST_ITEM, +}; + +const android::hardware::wifi::offload::V1_0::RecordName kHidlRecordNameList[] = { + android::hardware::wifi::offload::V1_0::RecordName::CMD_INT, + android::hardware::wifi::offload::V1_0::RecordName::CMD_CONFIG_SCANS, + android::hardware::wifi::offload::V1_0::RecordName::CMD_SUBSCRIBE_SCAN_RESULTS, + android::hardware::wifi::offload::V1_0::RecordName::REQ_SCAN, + android::hardware::wifi::offload::V1_0::RecordName::EVENT_RECVD_SCAN_RESULT, + android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_SCAN_RESULT, + android::hardware::wifi::offload::V1_0::RecordName::CMD_UNSUBSCRIBE_SCAN_RESULTS, + android::hardware::wifi::offload::V1_0::RecordName::CMD_GET_SCAN_STATS, +}; + +} // namespace offload_hal_test_constants +} // namespace implementation +} // namespace V1_0 +} // namespace offload +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi_offload/test/offload_hal_test_constants.h b/wifi_offload/test/offload_hal_test_constants.h new file mode 100644 index 00000000..195e0e8b --- /dev/null +++ b/wifi_offload/test/offload_hal_test_constants.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef OFFLOAD_HAL_TEST_CONSTANTS_ +#define OFFLOAD_HAL_TEST_CONSTANTS_ + +#include + +#include "offload_utils.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace offload { +namespace V1_0 { +namespace implementation { +namespace offload_hal_test_constants { + +extern const uint8_t kSsid1[]; +extern const size_t kSsid1_size; +extern const uint8_t kSsid2[]; +extern const size_t kSsid2_size; +extern const uint8_t kBssid[6]; +extern const int16_t kRssi; +extern const int16_t kRssiThreshold; +extern const uint32_t kFrequency1; +extern const uint32_t kFrequency2; +extern const uint8_t kBssidSize; +extern const uint64_t kTsf; +extern const uint16_t kCapability; +extern const uint8_t kNetworkFlags; +extern const uint32_t kDisconnectedModeScanIntervalMs; +extern const uint64_t kSubscriptionDurationMs; +extern const uint64_t kScanDurationMs[2]; +extern const uint32_t kNumChannelsScanned[]; +extern const uint8_t kChannelNotScanned; +extern const uint32_t kDefaultNumScansRequestedByWifi; +extern const uint32_t kDefaultNumScansServicedByWifi; +extern const uint64_t kScanDurationTotalMs; +extern const uint32_t kNumChannelsTotalScanned; +extern const uint32_t kNumChannelsInHistogram; +extern const uint64_t kDeathCode; +extern const uint8_t kTestChannels[]; +extern const uint32_t kNumTimesChannelScanned[]; +extern const uint32_t kSystemStartTime; +extern const uint32_t kIncrementBetweenEvents; +extern const size_t kRecordLength; +extern const size_t kInvalidRecordLength; +extern const wifi_offload::RpcLogRecord::RpcLogRecordType kChreRecordTypeList[]; +extern const wifi_offload::RpcLogRecord::RpcLogRecordType kInvalidChreRecordTypeLog[]; +extern const android::hardware::wifi::offload::V1_0::RecordName kHidlRecordNameList[]; + +} // namespace offload_hal_test_constants +} // namespace implementation +} // namespace V1_0 +} // namespace offload +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // OFFLOAD_HAL_TEST_CONSTANTS_ diff --git a/wifi_offload/test/offload_hal_test_utils.cpp b/wifi_offload/test/offload_hal_test_utils.cpp new file mode 100644 index 00000000..b58ce408 --- /dev/null +++ b/wifi_offload/test/offload_hal_test_utils.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2017 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 "offload_hal_test_utils.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace offload { +namespace V1_0 { +namespace implementation { +namespace offload_hal_test_utils { + +using namespace offload_hal_test_constants; + +void createChreScanResultsForTest(std::vector* chreScanResults) { + wifi_offload::ScanResult chreScanResult; + chreScanResult.security_modes_ = kNetworkFlags; + chreScanResult.capability_ = kCapability; + chreScanResult.frequency_scanned_mhz_ = kFrequency1; + chreScanResult.rssi_dbm_ = kRssi; + chreScanResult.tsf_ = kTsf; + chreScanResult.ssid_.SetData(&kSsid1[0], kSsid1_size); + memcpy(&chreScanResult.bssid_[0], &kBssid[0], kBssidSize); + chreScanResults->push_back(chreScanResult); +} + +void createChreScanStatsForTest(wifi_offload::ScanStats* chreScanStats) { + chreScanStats->num_scans_requested_by_nanoapp_ = kDefaultNumScansRequestedByWifi; + chreScanStats->num_scans_serviced_by_hardware_ = kDefaultNumScansServicedByWifi; + chreScanStats->num_scans_serviced_by_cache_ = + (kDefaultNumScansRequestedByWifi - kDefaultNumScansServicedByWifi); + for (size_t j = 0; j < kNumChannelsScanned[0] + kNumChannelsScanned[1]; j++) { + chreScanStats->channel_histogram_.IncrementScanCountForChannelForTest( + kTestChannels[j], static_cast(kNumTimesChannelScanned[j])); + } + chreScanStats->last_subscription_duration_ms_ = kSubscriptionDurationMs; + wifi_offload::ScanRecord scanRecord1; + scanRecord1.time_spent_scanning_ms_ = kScanDurationMs[0]; + scanRecord1.num_channels_scanned_ = kNumChannelsScanned[0]; + scanRecord1.num_entries_aggregated_ = 1; + chreScanStats->scan_records_.push_back(scanRecord1); + wifi_offload::ScanRecord scanRecord2; + scanRecord2.time_spent_scanning_ms_ = kScanDurationMs[1]; + scanRecord2.num_channels_scanned_ = kNumChannelsScanned[1]; + scanRecord2.num_entries_aggregated_ = 1; + chreScanStats->scan_records_.push_back(scanRecord2); + + for (size_t i = 0; i < kRecordLength; i++) { + wifi_offload::RpcLogRecord logRecord; + logRecord.record_type_ = kChreRecordTypeList[i]; + logRecord.timestamp_chre_ms_ = kSystemStartTime + i * kIncrementBetweenEvents; + chreScanStats->rpc_log_records_.push_back(logRecord); + } +} + +void createHidlScanFilterForTest(ScanFilter* scanFilter) { + std::vector nw_info_list; + NetworkInfo nwInfo1; + std::vector ssid1(kSsid1, kSsid1 + kSsid1_size); + nwInfo1.ssid = ssid1; + nwInfo1.flags = kNetworkFlags; + NetworkInfo nwInfo2; + std::vector ssid2(kSsid2, kSsid2 + kSsid2_size); + nwInfo2.ssid = ssid2; + nwInfo2.flags = kNetworkFlags; + nw_info_list.push_back(nwInfo1); + nw_info_list.push_back(nwInfo2); + scanFilter->preferredNetworkInfoList = nw_info_list; + scanFilter->rssiThreshold = kRssiThreshold; +} + +void createHidlScanParamForTest(ScanParam* scanParam) { + scanParam->disconnectedModeScanIntervalMs = kDisconnectedModeScanIntervalMs; + std::vector frequencyList{kFrequency1, kFrequency2}; + scanParam->frequencyList = frequencyList; + std::vector> ssidList; + std::vector ssid1(kSsid1, kSsid1 + kSsid1_size); + std::vector ssid2(kSsid2, kSsid2 + kSsid2_size); + ssidList.push_back(ssid1); + ssidList.push_back(ssid2); + scanParam->ssidList = ssidList; +} + +void createChreScanConfigForTest(wifi_offload::ScanConfig* scanConfig) { + scanConfig->scan_params_.disconnected_mode_scan_interval_ms_ = kDisconnectedModeScanIntervalMs; + wifi_offload::Ssid chreSsid1; + chreSsid1.SetData(&kSsid1[0], kSsid1_size); + wifi_offload::Ssid chreSsid2; + chreSsid2.SetData(&kSsid2[0], kSsid2_size); + scanConfig->scan_params_.ssids_to_scan_.push_back(chreSsid1); + scanConfig->scan_params_.ssids_to_scan_.push_back(chreSsid2); + scanConfig->scan_params_.frequencies_to_scan_mhz_.push_back(kFrequency1); + scanConfig->scan_params_.frequencies_to_scan_mhz_.push_back(kFrequency2); + scanConfig->scan_filter_.min_rssi_threshold_dbm_ = kRssiThreshold; + wifi_offload::PreferredNetwork chreNwInfo1; + chreNwInfo1.security_modes_ = kNetworkFlags; + chreNwInfo1.ssid_.SetData(&kSsid1[0], kSsid1_size); + scanConfig->scan_filter_.networks_to_match_.push_back(std::move(chreNwInfo1)); + wifi_offload::PreferredNetwork chreNwInfo2; + chreNwInfo2.security_modes_ = kNetworkFlags; + chreNwInfo2.ssid_.SetData(&kSsid2[0], kSsid2_size); + scanConfig->scan_filter_.networks_to_match_.push_back(std::move(chreNwInfo2)); +} + +bool validateScanResult(const std::vector& hidlScanResultsTest, + const std::vector chreScanResults) { + if (hidlScanResultsTest.size() != chreScanResults.size()) + return false; + uint32_t i = 0; + for (const auto& hidlScanResult : hidlScanResultsTest) { + if (hidlScanResult.tsf != chreScanResults[i].tsf_) + return false; + if (hidlScanResult.rssi != chreScanResults[i].rssi_dbm_) + return false; + if (hidlScanResult.capability != chreScanResults[i].capability_) + return false; + if (hidlScanResult.frequency != chreScanResults[i].frequency_scanned_mhz_) + return false; + for (int j = 0; j < kBssidSize; j++) { + if (hidlScanResult.bssid[j] != chreScanResults[i].bssid_[j]) + return false; + } + chreWifiSsidListItem chreWifiSsid; + chreScanResults[i].ssid_.ToChreWifiSsidListItem(&chreWifiSsid); + for (size_t k = 0; k < chreWifiSsid.ssidLen; k++) { + if (hidlScanResult.networkInfo.ssid[k] != chreWifiSsid.ssid[k]) + return false; + } + if (hidlScanResult.networkInfo.flags != kNetworkFlags) { + return false; + } + i++; + } + return true; +} + +bool validateScanStats(const ScanStats& hidlScanStats, + const wifi_offload::ScanStats& chreScanStats) { + if (hidlScanStats.subscriptionDurationMs != chreScanStats.last_subscription_duration_ms_) + return false; + if (hidlScanStats.numScansRequestedByWifi != chreScanStats.num_scans_requested_by_nanoapp_) + return false; + if (hidlScanStats.numScansServicedByWifi != chreScanStats.num_scans_serviced_by_hardware_) + return false; + if (hidlScanStats.numScansServicedbyCache != chreScanStats.num_scans_serviced_by_cache_) + return false; + for (uint32_t i = 0; i < kNumChannelsInHistogram; i++) { + if (hidlScanStats.histogramChannelsScanned[i] != + chreScanStats.channel_histogram_.GetChannelScanCount(i)) { + return false; + } + } + if (hidlScanStats.scanRecord.size() != chreScanStats.scan_records_.size()) + return false; + uint32_t i = 0; + for (const auto& scanRecord : hidlScanStats.scanRecord) { + if (scanRecord.durationMs != chreScanStats.scan_records_[i].time_spent_scanning_ms_) + return false; + if (scanRecord.numChannelsScanned != chreScanStats.scan_records_[i].num_channels_scanned_) + return false; + if (scanRecord.numEntriesAggregated != + chreScanStats.scan_records_[i].num_entries_aggregated_) + return false; + i++; + } + if (hidlScanStats.logRecord.size() != chreScanStats.rpc_log_records_.size()) + return false; + i = 0; + + for (const auto& logRecord : hidlScanStats.logRecord) { + if (logRecord.recordName != kHidlRecordNameList[i]) { + return false; + } + if (logRecord.logTimeMs != chreScanStats.rpc_log_records_[i].timestamp_chre_ms_) + return false; + i++; + } + return true; +} + +} // namespace offload_hal_test_utils +} // namespace implementation +} // namespace V1_0 +} // namespace offload +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi_offload/test/offload_hal_test_utils.h b/wifi_offload/test/offload_hal_test_utils.h new file mode 100644 index 00000000..ba82a1c6 --- /dev/null +++ b/wifi_offload/test/offload_hal_test_utils.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef OFFLOAD_HAL_TEST_UTILS_ +#define OFFLOAD_HAL_TEST_UTILS_ + +#include "offload_hal_test_constants.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace offload { +namespace V1_0 { +namespace implementation { +namespace offload_hal_test_utils { + +void createChreScanResultsForTest(std::vector* chreScanResults); +void createChreScanStatsForTest(wifi_offload::ScanStats* chreScanStats); +void createHidlScanFilterForTest(ScanFilter* scanFilter); +void createHidlScanParamForTest(ScanParam* scanParam); +void createChreScanConfigForTest(wifi_offload::ScanConfig* scanConfig); +bool validateScanResult(const std::vector& hidlScanResultsTest, + const std::vector chreScanResults); +bool validateScanStats(const ScanStats& hidlScanStats, + const wifi_offload::ScanStats& chreScanStats); +} // namespace offload_hal_test_utils +} // namespace implementation +} // namespace V1_0 +} // namespace offload +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // OFFLOAD_HAL_TEST_UTILS_ diff --git a/wifi_offload/test/offload_utils_test.cpp b/wifi_offload/test/offload_utils_test.cpp new file mode 100644 index 00000000..7c2e4d52 --- /dev/null +++ b/wifi_offload/test/offload_utils_test.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016, 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 + +#include +#include "offload_hal_test_utils.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace offload { +namespace V1_0 { +namespace implementation { + +using namespace offload_hal_test_constants; + +class OffloadUtilsTest : public ::testing::Test { + protected: + virtual void SetUp() { + } + + void TearDown() override { + } +}; + +TEST_F(OffloadUtilsTest, ConvertScanResultToHidlTest) { + std::vector hidlScanResultsTest; + std::vector chreScanResultsTest; + offload_hal_test_utils::createChreScanResultsForTest(&chreScanResultsTest); + EXPECT_TRUE(offload_utils::ToHidlScanResults(chreScanResultsTest, &hidlScanResultsTest)); + EXPECT_TRUE( + offload_hal_test_utils::validateScanResult(hidlScanResultsTest, chreScanResultsTest)); +} + +TEST_F(OffloadUtilsTest, ConvertScanStatsToHidlTest) { + ScanStats hidlScanStatsTest; + wifi_offload::ScanStats chreScanStatsTest; + offload_hal_test_utils::createChreScanStatsForTest(&chreScanStatsTest); + EXPECT_TRUE(offload_utils::ToHidlScanStats(chreScanStatsTest, &hidlScanStatsTest)); + EXPECT_TRUE(offload_hal_test_utils::validateScanStats(hidlScanStatsTest, chreScanStatsTest)); +} + +TEST_F(OffloadUtilsTest, ConvertScanConfigToChreTest) { + wifi_offload::ScanConfig scanConfigTest; + wifi_offload::ScanConfig scanConfig; + ScanParam scanParamTest; + ScanFilter scanFilterTest; + offload_hal_test_utils::createHidlScanParamForTest(&scanParamTest); + offload_hal_test_utils::createHidlScanFilterForTest(&scanFilterTest); + offload_hal_test_utils::createChreScanConfigForTest(&scanConfig); + EXPECT_TRUE(offload_utils::ToChreScanConfig(scanParamTest, scanFilterTest, &scanConfigTest)); + EXPECT_TRUE(scanConfig == scanConfigTest); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace offload +} // namespace wifi +} // namespace hardware +} // namespace android From 75e7db3fc38b4da1cef11aebde388cac6a4193d8 Mon Sep 17 00:00:00 2001 From: Sohani Rao Date: Wed, 26 Jul 2017 15:05:44 -0700 Subject: [PATCH 2/6] Offload HAL Service: Send messages to CHRE The following messages are to be sent to the nano app in response to invocation of the Offload HAL APIs from the client - subscribe, unsubsuscribe, configure scans CHRE interface will send the following commands to context hub - Get hub info and nano app list requests The callbacks from the socket will handle responses to these requests Bug: 32842314 Test: VTS Change-Id: I441522f5014317b7ac625742ab9782eeba5d78c8 Merged-In: I441522f5014317b7ac625742ab9782eeba5d78c8 --- wifi_offload/chre_interface.cpp | 26 +++++++++++++++++++ wifi_offload/chre_interface.h | 4 +++ wifi_offload/offload_server.cpp | 46 +++++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/wifi_offload/chre_interface.cpp b/wifi_offload/chre_interface.cpp index 456e6682..448a5782 100644 --- a/wifi_offload/chre_interface.cpp +++ b/wifi_offload/chre_interface.cpp @@ -142,6 +142,9 @@ void ChreInterface::reportConnectionEvent(ChreInterfaceCallbacks::ConnectionEven switch (event) { case ChreInterfaceCallbacks::ConnectionEvent::CONNECTED: connectionStatus = true; + if (!getHubInfo() || !getNanoAppList()) { + LOG(WARNING) << "Unable to get platform and nano app info"; + } break; case ChreInterfaceCallbacks::ConnectionEvent::DISCONNECTED: case ChreInterfaceCallbacks::ConnectionEvent::CONNECTION_ABORT: @@ -181,6 +184,29 @@ void ChreInterface::handleMessage(uint32_t messageType, const void* messageData, mServerCallbacks->handleMessage(messageType, message); } +bool ChreInterface::getHubInfo() { + LOG(VERBOSE) << "getHubInfo"; + + FlatBufferBuilder builder(chre_constants::kHubInfoRequestBufLen); + HostProtocolHost::encodeHubInfoRequest(builder); + if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) { + LOG(WARNING) << "Failed to send Hub Info request"; + return false; + } + return true; +} + +bool ChreInterface::getNanoAppList() { + LOG(VERBOSE) << "getNanoAppList"; + FlatBufferBuilder builder(chre_constants::kNanoAppListRequestBufLen); + HostProtocolHost::encodeNanoappListRequest(builder); + + if (!mClient.sendMessage(builder.GetBufferPointer(), builder.GetSize())) { + LOG(WARNING) << "Unable to send Nano app List request"; + return false; + } + return true; +} } // namespace implementation } // namespace V1_0 } // namespace offload diff --git a/wifi_offload/chre_interface.h b/wifi_offload/chre_interface.h index 72420af5..92cfa5b6 100644 --- a/wifi_offload/chre_interface.h +++ b/wifi_offload/chre_interface.h @@ -51,6 +51,10 @@ class SocketCallbacks void handleUnloadNanoappResponse(const ::chre::fbs::UnloadNanoappResponseT& response) override; private: + /* Requests Hub Information, returns true if Hub Info request was sent */ + bool getHubInfo(); + /* Request list of Nano apps, returns true if Nano app List request was sent */ + bool getNanoAppList(); ChreInterface* mParent; }; diff --git a/wifi_offload/offload_server.cpp b/wifi_offload/offload_server.cpp index 88277ec5..56e139a1 100644 --- a/wifi_offload/offload_server.cpp +++ b/wifi_offload/offload_server.cpp @@ -1,8 +1,13 @@ #include "offload_server.h" #include +#include +#include #include "offload_status_util.h" +#include "offload_utils.h" + +using namespace android::hardware::wifi::offload::V1_0::implementation::chre_constants; namespace android { namespace hardware { @@ -21,6 +26,25 @@ OffloadServer::OffloadServer(ChreInterfaceFactory* factory) OffloadStatus OffloadServer::configureScans(const ScanParam& param, const ScanFilter& filter) { LOG(INFO) << "configureScans"; + if (!mChreInterface->isConnected()) { + return createOffloadStatus(OffloadStatusCode::ERROR, + "Not connected to hardware implementation"); + } + wifi_offload::ScanConfig scanConfig; + if (!offload_utils::ToChreScanConfig(param, filter, &scanConfig)) { + return createOffloadStatus(OffloadStatusCode::ERROR, + "Unable to convert scan configuration"); + } + uint8_t buffer[kMaxMessageLen]; + size_t result_size = wifi_offload::fbs::Serialize(scanConfig, buffer, kMaxMessageLen); + if (result_size <= 0) { + return createOffloadStatus(OffloadStatusCode::ERROR, "Scan config serialization failed"); + } + std::vector message(buffer, buffer + result_size); + if (!mChreInterface->sendCommandToApp(wifi_offload::HostMessageType::HOST_CMD_CONFIG_SCANS, + message)) { + return createOffloadStatus(OffloadStatusCode::ERROR, "Unable to send config message"); + } return createOffloadStatus(OffloadStatusCode::OK); } @@ -32,11 +56,31 @@ std::pair OffloadServer::getScanStats() { OffloadStatus OffloadServer::subscribeScanResults(uint32_t delayMs) { LOG(INFO) << "subscribeScanResults with delay:" << delayMs; + if (!mChreInterface->isConnected()) { + return createOffloadStatus(OffloadStatusCode::ERROR, "Not connected to hardware"); + } + uint32_t* buffer = &delayMs; + std::vector message(reinterpret_cast(buffer), + reinterpret_cast(buffer) + kSubscriptionDelayMsBufLen); + if (!mChreInterface->sendCommandToApp( + wifi_offload::HostMessageType::HOST_CMD_SUBSCRIBE_SCAN_RESULTS, message)) { + return createOffloadStatus(OffloadStatusCode::ERROR, "Unable to request scans"); + } return createOffloadStatus(OffloadStatusCode::OK); } bool OffloadServer::unsubscribeScanResults() { + bool result = false; LOG(INFO) << "unsubscribeScanResults"; + if (!mChreInterface->isConnected()) { + LOG(WARNING) << "Failed to send unsubscribe scan results message"; + return false; + } + if (!mChreInterface->sendCommandToApp( + wifi_offload::HostMessageType::HOST_CMD_UNSUBSCRIBE_SCAN_RESULTS, {})) { + LOG(WARNING) << "Failed to send unsubscribe scan results message"; + return false; + } return true; } @@ -46,8 +90,6 @@ bool OffloadServer::setEventCallback(const sp& cb) { if (cb != nullptr) { mEventCallback = cb; result = true; - } else { - LOG(WARNING) << "Invalid callback object"; } return result; } From 0619a41f5d215d0d32a4e3a814765ab9da9c421f Mon Sep 17 00:00:00 2001 From: Sohani Rao Date: Thu, 18 May 2017 12:18:42 -0700 Subject: [PATCH 3/6] Offload HAL Service: Handle messages from Nano app The following messages from Nano app - Error, Scan stats, Scan Results Also invoke the appropriate callback to the client. Bug: 32842314 Test: VTS Change-Id: I562b2bcf149f8eab1cddc094a7b976aa56bdb9c8 Merged-In: I562b2bcf149f8eab1cddc094a7b976aa56bdb9c8 --- wifi_offload/offload_server.cpp | 129 +++++++++++++++++++++++++++++--- wifi_offload/offload_server.h | 9 +++ 2 files changed, 127 insertions(+), 11 deletions(-) diff --git a/wifi_offload/offload_server.cpp b/wifi_offload/offload_server.cpp index 56e139a1..877d420a 100644 --- a/wifi_offload/offload_server.cpp +++ b/wifi_offload/offload_server.cpp @@ -8,6 +8,11 @@ #include "offload_utils.h" using namespace android::hardware::wifi::offload::V1_0::implementation::chre_constants; +using android::hardware::wifi::offload::V1_0::OffloadStatus; + +namespace { +constexpr auto kScanStatsTimeout = std::chrono::milliseconds(500); +} namespace android { namespace hardware { @@ -27,7 +32,7 @@ OffloadServer::OffloadServer(ChreInterfaceFactory* factory) OffloadStatus OffloadServer::configureScans(const ScanParam& param, const ScanFilter& filter) { LOG(INFO) << "configureScans"; if (!mChreInterface->isConnected()) { - return createOffloadStatus(OffloadStatusCode::ERROR, + return createOffloadStatus(OffloadStatusCode::NO_CONNECTION, "Not connected to hardware implementation"); } wifi_offload::ScanConfig scanConfig; @@ -50,14 +55,33 @@ OffloadStatus OffloadServer::configureScans(const ScanParam& param, const ScanFi std::pair OffloadServer::getScanStats() { LOG(INFO) << "getScanStats"; - OffloadStatus status = createOffloadStatus(OffloadStatusCode::OK); - return std::make_pair(status, mScanStats); + mScanStatsStatus = createOffloadStatus(OffloadStatusCode::OK); + if (!mChreInterface->isConnected()) { + return {createOffloadStatus(OffloadStatusCode::NO_CONNECTION, "Unable to send scan stats"), + {}}; + } + if (!mChreInterface->sendCommandToApp(wifi_offload::HostMessageType::HOST_CMD_GET_SCAN_STATS, + {})) { + return {createOffloadStatus(OffloadStatusCode::ERROR, "Unable to send scan stats command"), + {}}; + } + LOG(VERBOSE) << "Sent getScanStats command"; + { + std::unique_lock lock(mScanStatsLock); + auto timeout_status = mScanStatsCond.wait_for(lock, kScanStatsTimeout); + if (timeout_status == std::cv_status::timeout) { + std::lock_guard lock(mOffloadLock); + LOG(WARNING) << "Timeout waiting for scan stats"; + return {createOffloadStatus(OffloadStatusCode::TIMEOUT, "Scan stats not received"), {}}; + } + } + return std::make_pair(mScanStatsStatus, mScanStats); } OffloadStatus OffloadServer::subscribeScanResults(uint32_t delayMs) { LOG(INFO) << "subscribeScanResults with delay:" << delayMs; if (!mChreInterface->isConnected()) { - return createOffloadStatus(OffloadStatusCode::ERROR, "Not connected to hardware"); + return createOffloadStatus(OffloadStatusCode::NO_CONNECTION, "Not connected to hardware"); } uint32_t* buffer = &delayMs; std::vector message(reinterpret_cast(buffer), @@ -70,7 +94,6 @@ OffloadStatus OffloadServer::subscribeScanResults(uint32_t delayMs) { } bool OffloadServer::unsubscribeScanResults() { - bool result = false; LOG(INFO) << "unsubscribeScanResults"; if (!mChreInterface->isConnected()) { LOG(WARNING) << "Failed to send unsubscribe scan results message"; @@ -86,21 +109,29 @@ bool OffloadServer::unsubscribeScanResults() { bool OffloadServer::setEventCallback(const sp& cb) { LOG(INFO) << "Set Event callback"; - bool result = false; - if (cb != nullptr) { - mEventCallback = cb; - result = true; + if (cb == nullptr) { + return false; } - return result; + std::lock_guard lock(mOffloadLock); + mEventCallback = cb; + return true; } void OffloadServer::clearEventCallback() { + std::lock_guard lock(mOffloadLock); if (mEventCallback != nullptr) { mEventCallback.clear(); } LOG(INFO) << "Event callback cleared"; } +void OffloadServer::invokeErrorCallback(const OffloadStatus& status) { + std::lock_guard lock(mOffloadLock); + if (mEventCallback != nullptr) { + mEventCallback->onError(status); + } +} + ChreInterfaceCallbacksImpl::ChreInterfaceCallbacksImpl(OffloadServer* server) : mServer(server) { } @@ -109,12 +140,88 @@ ChreInterfaceCallbacksImpl::~ChreInterfaceCallbacksImpl() { void ChreInterfaceCallbacksImpl::handleConnectionEvents( ChreInterfaceCallbacks::ConnectionEvent event) { - LOG(VERBOSE) << "Connection event received " << (int)event; + switch (event) { + case ChreInterfaceCallbacks::ConnectionEvent::DISCONNECTED: + case ChreInterfaceCallbacks::ConnectionEvent::CONNECTION_ABORT: { + LOG(ERROR) << "Connection to socket lost"; + mServer->invokeErrorCallback( + createOffloadStatus(OffloadStatusCode::NO_CONNECTION, "Connection to socket lost")); + } break; + case ChreInterfaceCallbacks::ConnectionEvent::CONNECTED: { + LOG(INFO) << "Connected to socket"; + mServer->invokeErrorCallback(createOffloadStatus(OffloadStatusCode::OK)); + } break; + default: + LOG(WARNING) << "Invalid connection event received " << (int)event; + break; + } +} + +void OffloadServer::handleScanResult(const std::vector& message) { + std::vector scanResults; + std::vector hidlScanResults; + std::string errorMessage; + if (!wifi_offload::fbs::Deserialize((uint8_t*)message.data(), message.size(), &scanResults)) { + invokeErrorCallback( + createOffloadStatus(OffloadStatusCode::ERROR, "Cannot deserialize scan results")); + return; + } + if (!offload_utils::ToHidlScanResults(scanResults, &hidlScanResults)) { + invokeErrorCallback(createOffloadStatus(OffloadStatusCode::ERROR, + "Cannot convert scan results to HIDL format")); + return; + } + { + std::lock_guard lock(mOffloadLock); + if (mEventCallback != nullptr) { + mEventCallback->onScanResult(hidlScanResults); + } + } +} + +void OffloadServer::handleScanStats(const std::vector& message) { + std::lock_guard lock(mScanStatsLock); + wifi_offload::ScanStats stats; + OffloadStatus status; + // Deserialize scan stats + status = createOffloadStatus(OffloadStatusCode::OK); + LOG(VERBOSE) << "Received scan stats"; + if (!wifi_offload::fbs::Deserialize((uint8_t*)message.data(), message.size(), &stats)) { + status = createOffloadStatus(OffloadStatusCode::ERROR, "Cannot deserailize scan stats"); + } else if (!offload_utils::ToHidlScanStats(stats, &mScanStats)) { + status = createOffloadStatus(OffloadStatusCode::ERROR, + "Cannot convert Scan stats to HIDL format"); + } + mScanStatsStatus = status; + mScanStatsCond.notify_all(); } void ChreInterfaceCallbacksImpl::handleMessage(uint32_t messageType, const std::vector& message) { LOG(VERBOSE) << "Message from Nano app " << messageType; + switch (messageType) { + case wifi_offload::HostMessageType::HOST_MSG_SCAN_RESULTS: { + LOG(INFO) << "Received scan results"; + mServer->handleScanResult(message); + } break; + case wifi_offload::HostMessageType::HOST_MSG_SCAN_STATS: + LOG(VERBOSE) << "Received scan stats from Nano app"; + mServer->handleScanStats(message); + break; + case wifi_offload::HostMessageType::HOST_MSG_ERROR: + LOG(VERBOSE) << "Received error message from Nano app"; + { + std::string errorMessage; + if (offload_utils::ToHidlErrorMessage(message[0], &errorMessage)) { + mServer->invokeErrorCallback( + createOffloadStatus(OffloadStatusCode::ERROR, errorMessage)); + } + } + break; + default: + LOG(WARNING) << "Unknown message received" << messageType; + break; + } } // Methods from ::android::hidl::base::V1_0::IBase follow. diff --git a/wifi_offload/offload_server.h b/wifi_offload/offload_server.h index f10ace16..2b150b16 100644 --- a/wifi_offload/offload_server.h +++ b/wifi_offload/offload_server.h @@ -41,7 +41,16 @@ class OffloadServer { void clearEventCallback(); private: + void invokeErrorCallback(const android::hardware::wifi::offload::V1_0::OffloadStatus& status); + void handleScanResult(const std::vector& message); + void handleScanStats(const std::vector& message); + ScanStats mScanStats; + std::mutex mScanStatsLock; + std::condition_variable mScanStatsCond; + std::mutex mOffloadLock; + OffloadStatus mScanStatsStatus; + std::unique_ptr mChreInterfaceCallbacks; std::unique_ptr mChreInterface; sp mEventCallback; From 708ae27dd028d59b015d022ab3db22db406429fd Mon Sep 17 00:00:00 2001 From: Sohani Rao Date: Fri, 28 Jul 2017 12:39:15 -0700 Subject: [PATCH 4/6] Offload HAL Service: Reset Nano app upon Error Offload HAL service reports all errors to the client. To bring Wifi Nano app to a known state, also send a RESET command to the Nano app. Bug: 32842314 Test: VTS Change-Id: Ie5834b80e545e9099e3492b0354fefc2bc82ef8c Merged-In: Ie5834b80e545e9099e3492b0354fefc2bc82ef8c --- wifi_offload/offload_server.cpp | 29 ++++++++++++++++++++++------- wifi_offload/offload_server.h | 4 +++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/wifi_offload/offload_server.cpp b/wifi_offload/offload_server.cpp index 877d420a..850b9b06 100644 --- a/wifi_offload/offload_server.cpp +++ b/wifi_offload/offload_server.cpp @@ -93,6 +93,17 @@ OffloadStatus OffloadServer::subscribeScanResults(uint32_t delayMs) { return createOffloadStatus(OffloadStatusCode::OK); } +void OffloadServer::resetNanoApp() { + LOG(INFO) << "resetting Nano app"; + if (!mChreInterface->isConnected()) { + LOG(WARNING) << "Unable to reset nano app, not connected"; + return; + } + if (!mChreInterface->sendCommandToApp(wifi_offload::HostMessageType::HOST_CMD_RESET, {})) { + LOG(ERROR) << "Unable to send Reset command to Nano app"; + } +} + bool OffloadServer::unsubscribeScanResults() { LOG(INFO) << "unsubscribeScanResults"; if (!mChreInterface->isConnected()) { @@ -125,7 +136,10 @@ void OffloadServer::clearEventCallback() { LOG(INFO) << "Event callback cleared"; } -void OffloadServer::invokeErrorCallback(const OffloadStatus& status) { +void OffloadServer::invokeErrorCallbackAndResetIfNeeded(const OffloadStatus& status) { + if (status.code != OffloadStatusCode::OK) { + resetNanoApp(); + } std::lock_guard lock(mOffloadLock); if (mEventCallback != nullptr) { mEventCallback->onError(status); @@ -144,12 +158,13 @@ void ChreInterfaceCallbacksImpl::handleConnectionEvents( case ChreInterfaceCallbacks::ConnectionEvent::DISCONNECTED: case ChreInterfaceCallbacks::ConnectionEvent::CONNECTION_ABORT: { LOG(ERROR) << "Connection to socket lost"; - mServer->invokeErrorCallback( + mServer->invokeErrorCallbackAndResetIfNeeded( createOffloadStatus(OffloadStatusCode::NO_CONNECTION, "Connection to socket lost")); } break; case ChreInterfaceCallbacks::ConnectionEvent::CONNECTED: { LOG(INFO) << "Connected to socket"; - mServer->invokeErrorCallback(createOffloadStatus(OffloadStatusCode::OK)); + mServer->invokeErrorCallbackAndResetIfNeeded( + createOffloadStatus(OffloadStatusCode::OK)); } break; default: LOG(WARNING) << "Invalid connection event received " << (int)event; @@ -162,13 +177,13 @@ void OffloadServer::handleScanResult(const std::vector& message) { std::vector hidlScanResults; std::string errorMessage; if (!wifi_offload::fbs::Deserialize((uint8_t*)message.data(), message.size(), &scanResults)) { - invokeErrorCallback( + invokeErrorCallbackAndResetIfNeeded( createOffloadStatus(OffloadStatusCode::ERROR, "Cannot deserialize scan results")); return; } if (!offload_utils::ToHidlScanResults(scanResults, &hidlScanResults)) { - invokeErrorCallback(createOffloadStatus(OffloadStatusCode::ERROR, - "Cannot convert scan results to HIDL format")); + invokeErrorCallbackAndResetIfNeeded(createOffloadStatus( + OffloadStatusCode::ERROR, "Cannot convert scan results to HIDL format")); return; } { @@ -213,7 +228,7 @@ void ChreInterfaceCallbacksImpl::handleMessage(uint32_t messageType, { std::string errorMessage; if (offload_utils::ToHidlErrorMessage(message[0], &errorMessage)) { - mServer->invokeErrorCallback( + mServer->invokeErrorCallbackAndResetIfNeeded( createOffloadStatus(OffloadStatusCode::ERROR, errorMessage)); } } diff --git a/wifi_offload/offload_server.h b/wifi_offload/offload_server.h index 2b150b16..ac7b3469 100644 --- a/wifi_offload/offload_server.h +++ b/wifi_offload/offload_server.h @@ -41,9 +41,11 @@ class OffloadServer { void clearEventCallback(); private: - void invokeErrorCallback(const android::hardware::wifi::offload::V1_0::OffloadStatus& status); + void invokeErrorCallbackAndResetIfNeeded( + const android::hardware::wifi::offload::V1_0::OffloadStatus& status); void handleScanResult(const std::vector& message); void handleScanStats(const std::vector& message); + void resetNanoApp(); ScanStats mScanStats; std::mutex mScanStatsLock; From 105360ed450aabbdd1de98b8e94e8a411fca1d51 Mon Sep 17 00:00:00 2001 From: Sohani Rao Date: Thu, 18 May 2017 18:56:33 -0700 Subject: [PATCH 5/6] Offload HAL Service: Enable errors for warnings Update compile flags for this module so that warnings will report errors during compilation. Also fixed one unused variable. Bug: 32842314 Test: VTS Change-Id: Ic48071c86bc81c93c44a4b0645134dc028f96b9e Merged-In: Ic48071c86bc81c93c44a4b0645134dc028f96b9e --- wifi_offload/Android.bp | 2 +- wifi_offload/Offload.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wifi_offload/Android.bp b/wifi_offload/Android.bp index 8ff578f5..289ae26b 100644 --- a/wifi_offload/Android.bp +++ b/wifi_offload/Android.bp @@ -24,7 +24,7 @@ cc_library_static { "offload_status_util.cpp", "offload_utils.cpp", ], - cflags: ["-Wall", "-Wextra"], + cflags: ["-Wall", "-Wextra", "-Werror"], shared_libs: [ "libbase", "libhidlbase", diff --git a/wifi_offload/Offload.h b/wifi_offload/Offload.h index 4510f680..d5e9e6db 100644 --- a/wifi_offload/Offload.h +++ b/wifi_offload/Offload.h @@ -24,7 +24,7 @@ class HidlDeathHandler : public android::hardware::hidl_death_recipient { // Death notification for callbacks. void serviceDied(uint64_t cookie, - const android::wp &who) override { + const android::wp& /* who */) override { cb_.clear(); cb_function_(cookie); } From 404b3242a9c74b378f50607feeea58d3542833cb Mon Sep 17 00:00:00 2001 From: Sohani Rao Date: Wed, 23 Aug 2017 16:37:25 -0700 Subject: [PATCH 6/6] Offload HAL service: Fix running unit tests Update the location from which runtest.sh will fetch the unit test binary. The binary is now located in vendor data. Bug: 32842314 Test: VTS and Unit tests Change-Id: I13bba845e121a31f4763584e593fdda374701dd7 --- wifi_offload/test/runtest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wifi_offload/test/runtest.sh b/wifi_offload/test/runtest.sh index f8dbd7e6..b2a2ce82 100755 --- a/wifi_offload/test/runtest.sh +++ b/wifi_offload/test/runtest.sh @@ -35,5 +35,5 @@ adb wait-for-device adb remount adb sync -adb shell /data/nativetest/wifi-offload-service-unit-tests/wifi-offload-service-unit-tests -adb shell /data/nativetest64/wifi-offload-service-unit-tests/wifi-offload-service-unit-tests +adb shell /data/nativetest/vendor/wifi-offload-service-unit-tests/wifi-offload-service-unit-tests +adb shell /data/nativetest64/vendor/wifi-offload-service-unit-tests/wifi-offload-service-unit-tests