1 /* 2 * Copyright (C) 2016, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "offload_utils.h" 18 19 #include <android-base/logging.h> 20 #include <chre/apps/wifi_offload/error_codes.h> 21 22 namespace { 23 24 bool ToHidlRecordName(const wifi_offload::RpcLogRecord::RpcLogRecordType& chreRecordType, 25 android::hardware::wifi::offload::V1_0::RecordName* hidlRecordName) { 26 bool result = true; 27 switch (chreRecordType) { 28 case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_INIT: 29 *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::CMD_INT; 30 break; 31 case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_CONFIG_SCANS: 32 *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::CMD_CONFIG_SCANS; 33 break; 34 case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_SUBSCRIBE_SCAN_RESULTS: 35 *hidlRecordName = 36 android::hardware::wifi::offload::V1_0::RecordName::CMD_SUBSCRIBE_SCAN_RESULTS; 37 break; 38 case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_UNSUBSCRIBE_SCAN_RESULTS: 39 *hidlRecordName = 40 android::hardware::wifi::offload::V1_0::RecordName::CMD_UNSUBSCRIBE_SCAN_RESULTS; 41 break; 42 case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_GET_SCAN_STATS: 43 *hidlRecordName = 44 android::hardware::wifi::offload::V1_0::RecordName::CMD_GET_SCAN_STATS; 45 break; 46 case wifi_offload::RpcLogRecord::RpcLogRecordType::CMD_RESET: 47 *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::CMD_RESET; 48 break; 49 case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_RECVD_SCAN_RESULT_ASYNC: 50 *hidlRecordName = 51 android::hardware::wifi::offload::V1_0::RecordName::EVENT_RECVD_SCAN_RESULT_ASYNC; 52 break; 53 case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_RECVD_SCAN_RESULT: 54 *hidlRecordName = 55 android::hardware::wifi::offload::V1_0::RecordName::EVENT_RECVD_SCAN_RESULT; 56 break; 57 case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_SCAN_RESULT: 58 *hidlRecordName = 59 android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_SCAN_RESULT; 60 break; 61 case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_ABORT: 62 *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_ABORT; 63 break; 64 case wifi_offload::RpcLogRecord::RpcLogRecordType::EVENT_SENT_ERROR: 65 *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::EVENT_SENT_ERROR; 66 break; 67 case wifi_offload::RpcLogRecord::RpcLogRecordType::REQ_SCAN: 68 *hidlRecordName = android::hardware::wifi::offload::V1_0::RecordName::REQ_SCAN; 69 break; 70 default: 71 result = false; 72 break; 73 } 74 return result; 75 } 76 77 uint8_t ToChreSecurityMode(uint8_t hidlSecurityMode) { 78 uint8_t chreSecurityMode = 0; 79 if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::OPEN) { 80 chreSecurityMode |= wifi_offload::SecurityMode::OPEN; 81 } 82 if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::WEP) { 83 chreSecurityMode |= wifi_offload::SecurityMode::WEP; 84 } 85 if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::PSK) { 86 chreSecurityMode |= wifi_offload::SecurityMode::PSK; 87 } 88 if (hidlSecurityMode & android::hardware::wifi::offload::V1_0::SecurityMode::EAP) { 89 chreSecurityMode |= wifi_offload::SecurityMode::EAP; 90 } 91 return chreSecurityMode; 92 } 93 94 uint8_t ToHidlSecurityMode(uint8_t chreSecurityMode) { 95 uint8_t hidlSecurityMode = 0; 96 if (chreSecurityMode & wifi_offload::SecurityMode::OPEN) { 97 hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::OPEN; 98 } 99 if (chreSecurityMode & wifi_offload::SecurityMode::WEP) { 100 hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::WEP; 101 } 102 if (chreSecurityMode & wifi_offload::SecurityMode::PSK) { 103 hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::PSK; 104 } 105 if (chreSecurityMode & wifi_offload::SecurityMode::EAP) { 106 hidlSecurityMode |= android::hardware::wifi::offload::V1_0::SecurityMode::EAP; 107 } 108 return hidlSecurityMode; 109 } 110 111 } // namespace 112 113 namespace android { 114 namespace hardware { 115 namespace wifi { 116 namespace offload { 117 namespace V1_0 { 118 namespace implementation { 119 namespace offload_utils { 120 121 bool ToHidlScanResult(const wifi_offload::ScanResult& chreScanResult, ScanResult* hidlScanResult) { 122 if (hidlScanResult == nullptr) { 123 return false; 124 } 125 hidlScanResult->tsf = chreScanResult.tsf_; 126 hidlScanResult->capability = chreScanResult.capability_; 127 hidlScanResult->rssi = chreScanResult.rssi_dbm_; 128 hidlScanResult->frequency = chreScanResult.frequency_scanned_mhz_; 129 memcpy(&hidlScanResult->bssid[0], &chreScanResult.bssid_[0], 130 wifi_offload::ScanResult::kBssidSize); 131 chreWifiSsidListItem chreWifiSsid; 132 chreScanResult.ssid_.ToChreWifiSsidListItem(&chreWifiSsid); 133 std::vector<uint8_t> ssid; 134 for (size_t i = 0; i < chreWifiSsid.ssidLen; i++) { 135 ssid.push_back(chreWifiSsid.ssid[i]); 136 } 137 hidlScanResult->networkInfo.ssid = ssid; 138 hidlScanResult->networkInfo.flags = ToHidlSecurityMode(chreScanResult.security_modes_); 139 return true; 140 } 141 142 bool ToHidlScanResults(const std::vector<wifi_offload::ScanResult>& chreScanResults, 143 std::vector<ScanResult>* hidlScanResults) { 144 LOG(VERBOSE) << "ScanResults from CHRE, size=" << chreScanResults.size(); 145 for (const auto& scan_result_from_nano_app : chreScanResults) { 146 ScanResult hidl_scan_result; 147 if (!ToHidlScanResult(scan_result_from_nano_app, &hidl_scan_result)) { 148 return false; 149 } 150 hidlScanResults->push_back(hidl_scan_result); 151 } 152 return true; 153 } 154 155 bool ToHidlScanStats(const wifi_offload::ScanStats& chreScanStats, ScanStats* hidlScanStats) { 156 hidlScanStats->subscriptionDurationMs = chreScanStats.last_subscription_duration_ms_; 157 hidlScanStats->numScansRequestedByWifi = chreScanStats.num_scans_requested_by_nanoapp_; 158 hidlScanStats->numScansServicedByWifi = chreScanStats.num_scans_serviced_by_hardware_; 159 hidlScanStats->numScansServicedbyCache = chreScanStats.num_scans_serviced_by_cache_; 160 std::vector<ScanRecord> hidlScanRecords; 161 for (const auto& chreScanRecord : chreScanStats.scan_records_) { 162 ScanRecord hidlScanRecord; 163 hidlScanRecord.durationMs = chreScanRecord.time_spent_scanning_ms_; 164 hidlScanRecord.numChannelsScanned = chreScanRecord.num_channels_scanned_; 165 hidlScanRecord.numEntriesAggregated = chreScanRecord.num_entries_aggregated_; 166 hidlScanRecords.push_back(hidlScanRecord); 167 } 168 hidlScanStats->scanRecord = hidlScanRecords; 169 std::vector<LogRecord> logRecords; 170 for (const auto& chreLogRecord : chreScanStats.rpc_log_records_) { 171 LogRecord logRecord; 172 if (!ToHidlRecordName(chreLogRecord.record_type_, &logRecord.recordName)) { 173 return false; 174 } 175 logRecord.logTimeMs = chreLogRecord.timestamp_chre_ms_; 176 logRecords.push_back(logRecord); 177 } 178 hidlScanStats->logRecord = logRecords; 179 for (size_t i = 0; i < hidlScanStats->histogramChannelsScanned.elementCount(); i++) { 180 hidlScanStats->histogramChannelsScanned[i] = 181 chreScanStats.channel_histogram_.GetChannelScanCount(i); 182 } 183 return true; 184 } 185 186 bool ToChreScanConfig(const ScanParam& param, const ScanFilter& filter, 187 wifi_offload::ScanConfig* scanConfig) { 188 scanConfig->scan_params_.disconnected_mode_scan_interval_ms_ = 189 param.disconnectedModeScanIntervalMs; 190 for (const auto& ssid : param.ssidList) { 191 wifi_offload::Ssid chreSsid; 192 chreSsid.SetData(ssid.data(), ssid.size()); 193 scanConfig->scan_params_.ssids_to_scan_.push_back(chreSsid); 194 } 195 for (const auto& freq : param.frequencyList) { 196 scanConfig->scan_params_.frequencies_to_scan_mhz_.push_back(freq); 197 } 198 scanConfig->scan_filter_.min_rssi_threshold_dbm_ = filter.rssiThreshold; 199 for (const auto& nwInfo : filter.preferredNetworkInfoList) { 200 wifi_offload::PreferredNetwork chreNwInfo; 201 chreNwInfo.security_modes_ = ToChreSecurityMode(nwInfo.flags); 202 chreNwInfo.ssid_.SetData(nwInfo.ssid.data(), nwInfo.ssid.size()); 203 scanConfig->scan_filter_.networks_to_match_.push_back(std::move(chreNwInfo)); 204 } 205 return true; 206 } 207 208 bool ToHidlErrorMessage(uint32_t errorCode, std::string* errorMessage) { 209 bool reportError = true; 210 switch (errorCode) { 211 case wifi_offload::ErrorCode::FAILED_TO_ALLOCATE_MESSAGE_BUFFER: 212 *errorMessage = "Failed to allocate message buffer"; 213 break; 214 case wifi_offload::ErrorCode::FAILED_TO_SERIALIZE_MESSAGE: 215 *errorMessage = "Failed to serialize message"; 216 break; 217 case wifi_offload::ErrorCode::FAILED_TO_SEND_MESSAGE: 218 *errorMessage = "Failed to send message"; 219 break; 220 case wifi_offload::ErrorCode::FAILED_TO_DESERIALIZE_SCAN_CONFIG: 221 *errorMessage = "Failed to deserialize scan config"; 222 break; 223 case wifi_offload::ErrorCode::INVALID_SUBSCRIBE_MESSAGE_SIZE: 224 *errorMessage = "Invalid subscribe message size"; 225 break; 226 case wifi_offload::ErrorCode::SCAN_CONFIG_NOT_INITIALIZED: 227 *errorMessage = "Scan config not initialized"; 228 break; 229 case wifi_offload::ErrorCode::UNSPECIFIED_HOST_ENDPOINT: 230 *errorMessage = "Unspecified host end point"; 231 break; 232 case wifi_offload::ErrorCode::FAILED_TO_SEND_SCAN_RESULTS: 233 *errorMessage = "Failed to send scan results"; 234 break; 235 case wifi_offload::ErrorCode::FAILED_TO_SEND_SCAN_STATS: 236 *errorMessage = "Failed to send scan stats"; 237 break; 238 case wifi_offload::ErrorCode::ONDEMAND_SCAN_NOT_SUPPORTED: 239 *errorMessage = "On demand scans not supported"; 240 break; 241 case wifi_offload::ErrorCode::FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST: 242 *errorMessage = "Failed to send on demand scan request"; 243 break; 244 case wifi_offload::ErrorCode::FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST_ASYNC: 245 *errorMessage = "Failed to send on demand scan request async"; 246 break; 247 case wifi_offload::ErrorCode::OUT_OF_ORDER_SCAN_RESULTS: 248 *errorMessage = "Out of order scan results"; 249 break; 250 case wifi_offload::ErrorCode::INCOMPLETE_SCAN_RESULTS_BEFORE_SCAN_REQUEST: 251 *errorMessage = "Incomplete scan results before scan request"; 252 break; 253 case wifi_offload::ErrorCode::FAILED_TO_SET_SCAN_TIMER: 254 *errorMessage = "Failed to set scan timer"; 255 break; 256 case wifi_offload::ErrorCode::SCAN_MONITORING_NOT_SUPPORTED: 257 *errorMessage = "Scan Monitoring not supported"; 258 break; 259 case wifi_offload::ErrorCode::FAILED_TO_START_SCAN_MONITORING: 260 *errorMessage = "Failed to start scan monitoring"; 261 reportError = false; 262 break; 263 case wifi_offload::ErrorCode::FAILED_TO_STOP_SCAN_MONITORING: 264 *errorMessage = "Failed to stop scan monitoring"; 265 reportError = false; 266 break; 267 case wifi_offload::ErrorCode::FAILED_TO_CONFIGURE_SCAN_MONITORING_ASYNC: 268 *errorMessage = "Failed to configure scan monitoring async"; 269 reportError = false; 270 break; 271 default: 272 *errorMessage = "Invalid error code"; 273 reportError = false; 274 break; 275 } 276 return reportError; 277 } 278 279 } // namespace offload_utils 280 } // namespace implementation 281 } // namespace V1_0 282 } // namespace offload 283 } // namespace wifi 284 } // namespace hardware 285 } // namespace android 286