/* * 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 <android-base/logging.h> #include <chre/apps/wifi_offload/error_codes.h> 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<uint8_t> 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<wifi_offload::ScanResult>& chreScanResults, std::vector<ScanResult>* 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<ScanRecord> 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<LogRecord> 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