1/* 2 * Copyright (C) 2017 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 "chre/apps/wifi_offload/scan_result.h" 18#include "chre/apps/wifi_offload/channel_histogram.h" 19#include "chre/apps/wifi_offload/utility.h" 20 21namespace wifi_offload { 22namespace { 23 24SecurityMode ConvertSecurityModeChreToOffload(int chre_security_mode) { 25 switch (chre_security_mode) { 26 case CHRE_WIFI_SECURITY_MODE_OPEN: 27 return SecurityMode::OPEN; 28 case CHRE_WIFI_SECURITY_MODE_WEP: 29 return SecurityMode::WEP; 30 case CHRE_WIFI_SECURITY_MODE_PSK: 31 return SecurityMode::PSK; 32 case CHRE_WIFI_SECURITY_MODE_EAP: 33 return SecurityMode::EAP; 34 default: 35 return SecurityMode::UNKNOWN; 36 } 37} 38 39} // namespace 40 41ScanResult::ScanResult() 42 : security_modes_(SecurityMode::UNKNOWN), 43 capability_(Capability::UNKNOWN), 44 frequency_scanned_mhz_(0), 45 rssi_dbm_(-128), 46 tsf_(0) { 47 std::memset(bssid_, 0, sizeof(bssid_)); 48} 49 50ScanResult::ScanResult(const ScanResult &other) 51 : ssid_(other.ssid_), 52 security_modes_(other.security_modes_), 53 capability_(other.capability_), 54 frequency_scanned_mhz_(other.frequency_scanned_mhz_), 55 rssi_dbm_(other.rssi_dbm_), 56 tsf_(other.tsf_) { 57 std::memcpy(bssid_, other.bssid_, sizeof(bssid_)); 58} 59 60ScanResult::ScanResult(const chreWifiScanResult &chre_scan_result) { 61 UpdateFromChreWifiScanResult(chre_scan_result); 62} 63 64bool ScanResult::operator==(const ScanResult &other) const { 65 if (this == &other) { 66 return true; 67 } 68 return std::memcmp(bssid_, other.bssid_, sizeof(bssid_)) == 0 && 69 ssid_ == other.ssid_ && security_modes_ == other.security_modes_ && 70 capability_ == other.capability_ && 71 frequency_scanned_mhz_ == other.frequency_scanned_mhz_ && 72 rssi_dbm_ == other.rssi_dbm_ && tsf_ == other.tsf_; 73} 74 75flatbuffers::Offset<ScanResult::FbsType> ScanResult::Serialize( 76 flatbuffers::FlatBufferBuilder *builder) const { 77 auto ssid_offset = ssid_.Serialize(builder); 78 auto bssid_offset = builder->CreateVector(bssid_, kBssidSize); 79 return fbs::CreateScanResult(*builder, ssid_offset, security_modes_, 80 bssid_offset, capability_, 81 frequency_scanned_mhz_, rssi_dbm_, tsf_); 82} 83 84bool ScanResult::Deserialize(const ScanResult::FbsType &fbs_result) { 85 if (fbs_result.ssid() == nullptr || !ssid_.Deserialize(*fbs_result.ssid())) { 86 LOGE("Failed to deserialize ScanResult. Null or incomplete members."); 87 return false; 88 } 89 90 security_modes_ = fbs_result.security_modes(); 91 if (security_modes_ & ~SecurityMode::ALL_SECURITY_MODES_MASK) { 92 LOGE("Failed to deserialize ScanResult. Invalid security mode."); 93 return false; 94 } 95 96 if (fbs_result.bssid() == nullptr || 97 fbs_result.bssid()->size() != kBssidSize) { 98 LOGE("Failed to deserialize ScanResult. Null or incomplete members."); 99 return false; 100 } 101 for (uint8_t i = 0; i < kBssidSize; i++) { 102 bssid_[i] = fbs_result.bssid()->Get(i); 103 } 104 105 capability_ = fbs_result.capability(); 106 if ((capability_ == Capability::UNKNOWN) || 107 (capability_ & ~Capability::ALL_CAPABILITIES_MASK)) { 108 LOGE("Failed to deserialize ScanResult. Invalid network capability."); 109 return false; 110 } 111 112 frequency_scanned_mhz_ = fbs_result.frequency_scanned_mhz(); 113 if (!ChannelHistogram::IsSupportedFrequency(frequency_scanned_mhz_)) { 114 LOGE("Failed to deserialize ScanResult. Invalid channel frequency."); 115 return false; 116 } 117 118 rssi_dbm_ = fbs_result.rssi_dbm(); 119 if (rssi_dbm_ > 0) { 120 LOGE("Failed to deserialize ScanResult. Positive rssi value."); 121 return false; 122 } 123 124 tsf_ = fbs_result.tsf(); 125 return true; 126} 127 128void ScanResult::Log() const { 129 LOGI("ScanResult:"); 130 ssid_.Log(); 131 LOGI(" security modes: 0x%" PRIx8, security_modes_); 132 utility::LogBssid(bssid_); 133 LOGI(" capability: 0x%" PRIx16, capability_); 134 LOGI(" scanned frequency: %" PRIu32, frequency_scanned_mhz_); 135 LOGI(" rssi: %" PRId8 "dBm", rssi_dbm_); 136 LOGI(" tsf: %" PRIu64, tsf_); 137} 138 139void ScanResult::UpdateFromChreWifiScanResult( 140 const chreWifiScanResult &chre_scan_result) { 141 ssid_.SetData(chre_scan_result.ssid, chre_scan_result.ssidLen); 142 143 security_modes_ = 0; 144 for (const auto chre_security_mode : 145 {CHRE_WIFI_SECURITY_MODE_OPEN, CHRE_WIFI_SECURITY_MODE_WEP, 146 CHRE_WIFI_SECURITY_MODE_PSK, CHRE_WIFI_SECURITY_MODE_EAP}) { 147 if (chre_scan_result.securityMode & chre_security_mode) { 148 security_modes_ |= ConvertSecurityModeChreToOffload(chre_security_mode); 149 } 150 } 151 152 std::memcpy(bssid_, chre_scan_result.bssid, CHRE_WIFI_BSSID_LEN); 153 // TODO: make sure capability definition between two versions is the same 154 // (802.11:7.3.1.4 vs. 802.11:8.4.1.4) 155 capability_ = chre_scan_result.capabilityInfo; 156 if (chre_scan_result.channelWidth == CHRE_WIFI_CHANNEL_WIDTH_20_MHZ) { 157 frequency_scanned_mhz_ = chre_scan_result.primaryChannel; 158 } else { 159 // TODO: (b/62870147) Support other possible channel widths 160 LOGW("Scan result channel width not supported %" PRIu8, 161 chre_scan_result.channelWidth); 162 } 163 164 rssi_dbm_ = chre_scan_result.rssi; 165 tsf_ = 0; // tsf value not available 166} 167 168} // namespace wifi_offload 169