| /* |
| * 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 |