| /* |
| * 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 "chre/apps/wifi_offload/scan_result.h" |
| #include "chre/apps/wifi_offload/channel_histogram.h" |
| #include "chre/apps/wifi_offload/utility.h" |
| |
| namespace wifi_offload { |
| namespace { |
| |
| SecurityMode ConvertSecurityModeChreToOffload(int chre_security_mode) { |
| switch (chre_security_mode) { |
| case CHRE_WIFI_SECURITY_MODE_OPEN: |
| return SecurityMode::OPEN; |
| case CHRE_WIFI_SECURITY_MODE_WEP: |
| return SecurityMode::WEP; |
| case CHRE_WIFI_SECURITY_MODE_PSK: |
| return SecurityMode::PSK; |
| case CHRE_WIFI_SECURITY_MODE_EAP: |
| return SecurityMode::EAP; |
| default: |
| return SecurityMode::UNKNOWN; |
| } |
| } |
| |
| } // namespace |
| |
| ScanResult::ScanResult() |
| : security_modes_(SecurityMode::UNKNOWN), |
| capability_(Capability::UNKNOWN), |
| frequency_scanned_mhz_(0), |
| rssi_dbm_(-128), |
| tsf_(0) { |
| std::memset(bssid_, 0, sizeof(bssid_)); |
| } |
| |
| ScanResult::ScanResult(const ScanResult &other) |
| : ssid_(other.ssid_), |
| security_modes_(other.security_modes_), |
| capability_(other.capability_), |
| frequency_scanned_mhz_(other.frequency_scanned_mhz_), |
| rssi_dbm_(other.rssi_dbm_), |
| tsf_(other.tsf_) { |
| std::memcpy(bssid_, other.bssid_, sizeof(bssid_)); |
| } |
| |
| ScanResult::ScanResult(const chreWifiScanResult &chre_scan_result) { |
| UpdateFromChreWifiScanResult(chre_scan_result); |
| } |
| |
| bool ScanResult::operator==(const ScanResult &other) const { |
| if (this == &other) { |
| return true; |
| } |
| return std::memcmp(bssid_, other.bssid_, sizeof(bssid_)) == 0 && |
| ssid_ == other.ssid_ && security_modes_ == other.security_modes_ && |
| capability_ == other.capability_ && |
| frequency_scanned_mhz_ == other.frequency_scanned_mhz_ && |
| rssi_dbm_ == other.rssi_dbm_ && tsf_ == other.tsf_; |
| } |
| |
| flatbuffers::Offset<ScanResult::FbsType> ScanResult::Serialize( |
| flatbuffers::FlatBufferBuilder *builder) const { |
| auto ssid_offset = ssid_.Serialize(builder); |
| auto bssid_offset = builder->CreateVector(bssid_, kBssidSize); |
| return fbs::CreateScanResult(*builder, ssid_offset, security_modes_, |
| bssid_offset, capability_, |
| frequency_scanned_mhz_, rssi_dbm_, tsf_); |
| } |
| |
| bool ScanResult::Deserialize(const ScanResult::FbsType &fbs_result) { |
| if (fbs_result.ssid() == nullptr || !ssid_.Deserialize(*fbs_result.ssid())) { |
| LOGE("Failed to deserialize ScanResult. Null or incomplete members."); |
| return false; |
| } |
| |
| security_modes_ = fbs_result.security_modes(); |
| if (security_modes_ & ~SecurityMode::ALL_SECURITY_MODES_MASK) { |
| LOGE("Failed to deserialize ScanResult. Invalid security mode."); |
| return false; |
| } |
| |
| if (fbs_result.bssid() == nullptr || |
| fbs_result.bssid()->size() != kBssidSize) { |
| LOGE("Failed to deserialize ScanResult. Null or incomplete members."); |
| return false; |
| } |
| for (uint8_t i = 0; i < kBssidSize; i++) { |
| bssid_[i] = fbs_result.bssid()->Get(i); |
| } |
| |
| capability_ = fbs_result.capability(); |
| if ((capability_ == Capability::UNKNOWN) || |
| (capability_ & ~Capability::ALL_CAPABILITIES_MASK)) { |
| LOGE("Failed to deserialize ScanResult. Invalid network capability."); |
| return false; |
| } |
| |
| frequency_scanned_mhz_ = fbs_result.frequency_scanned_mhz(); |
| if (!ChannelHistogram::IsSupportedFrequency(frequency_scanned_mhz_)) { |
| LOGE("Failed to deserialize ScanResult. Invalid channel frequency."); |
| return false; |
| } |
| |
| rssi_dbm_ = fbs_result.rssi_dbm(); |
| if (rssi_dbm_ > 0) { |
| LOGE("Failed to deserialize ScanResult. Positive rssi value."); |
| return false; |
| } |
| |
| tsf_ = fbs_result.tsf(); |
| return true; |
| } |
| |
| void ScanResult::Log() const { |
| LOGI("ScanResult:"); |
| ssid_.Log(); |
| LOGI(" security modes: 0x%" PRIx8, security_modes_); |
| utility::LogBssid(bssid_); |
| LOGI(" capability: 0x%" PRIx16, capability_); |
| LOGI(" scanned frequency: %" PRIu32, frequency_scanned_mhz_); |
| LOGI(" rssi: %" PRId8 "dBm", rssi_dbm_); |
| LOGI(" tsf: %" PRIu64, tsf_); |
| } |
| |
| void ScanResult::UpdateFromChreWifiScanResult( |
| const chreWifiScanResult &chre_scan_result) { |
| ssid_.SetData(chre_scan_result.ssid, chre_scan_result.ssidLen); |
| |
| security_modes_ = 0; |
| for (const auto chre_security_mode : |
| {CHRE_WIFI_SECURITY_MODE_OPEN, CHRE_WIFI_SECURITY_MODE_WEP, |
| CHRE_WIFI_SECURITY_MODE_PSK, CHRE_WIFI_SECURITY_MODE_EAP}) { |
| if (chre_scan_result.securityMode & chre_security_mode) { |
| security_modes_ |= ConvertSecurityModeChreToOffload(chre_security_mode); |
| } |
| } |
| |
| std::memcpy(bssid_, chre_scan_result.bssid, CHRE_WIFI_BSSID_LEN); |
| // TODO: make sure capability definition between two versions is the same |
| // (802.11:7.3.1.4 vs. 802.11:8.4.1.4) |
| capability_ = chre_scan_result.capabilityInfo; |
| if (chre_scan_result.channelWidth == CHRE_WIFI_CHANNEL_WIDTH_20_MHZ) { |
| frequency_scanned_mhz_ = chre_scan_result.primaryChannel; |
| } else { |
| // TODO: (b/62870147) Support other possible channel widths |
| LOGW("Scan result channel width not supported %" PRIu8, |
| chre_scan_result.channelWidth); |
| } |
| |
| rssi_dbm_ = chre_scan_result.rssi; |
| tsf_ = 0; // tsf value not available |
| } |
| |
| } // namespace wifi_offload |