xref: /aosp_15_r20/system/chre/apps/wifi_offload/scan_result.cc (revision 84e339476a462649f82315436d70fd732297a399)
1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker  *
4*84e33947SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker  *
8*84e33947SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker  *
10*84e33947SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker  * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker  */
16*84e33947SAndroid Build Coastguard Worker 
17*84e33947SAndroid Build Coastguard Worker #include "chre/apps/wifi_offload/scan_result.h"
18*84e33947SAndroid Build Coastguard Worker #include "chre/apps/wifi_offload/channel_histogram.h"
19*84e33947SAndroid Build Coastguard Worker #include "chre/apps/wifi_offload/utility.h"
20*84e33947SAndroid Build Coastguard Worker 
21*84e33947SAndroid Build Coastguard Worker namespace wifi_offload {
22*84e33947SAndroid Build Coastguard Worker namespace {
23*84e33947SAndroid Build Coastguard Worker 
ConvertSecurityModeChreToOffload(int chre_security_mode)24*84e33947SAndroid Build Coastguard Worker SecurityMode ConvertSecurityModeChreToOffload(int chre_security_mode) {
25*84e33947SAndroid Build Coastguard Worker   switch (chre_security_mode) {
26*84e33947SAndroid Build Coastguard Worker     case CHRE_WIFI_SECURITY_MODE_OPEN:
27*84e33947SAndroid Build Coastguard Worker       return SecurityMode::OPEN;
28*84e33947SAndroid Build Coastguard Worker     case CHRE_WIFI_SECURITY_MODE_WEP:
29*84e33947SAndroid Build Coastguard Worker       return SecurityMode::WEP;
30*84e33947SAndroid Build Coastguard Worker     case CHRE_WIFI_SECURITY_MODE_PSK:
31*84e33947SAndroid Build Coastguard Worker       return SecurityMode::PSK;
32*84e33947SAndroid Build Coastguard Worker     case CHRE_WIFI_SECURITY_MODE_EAP:
33*84e33947SAndroid Build Coastguard Worker       return SecurityMode::EAP;
34*84e33947SAndroid Build Coastguard Worker     default:
35*84e33947SAndroid Build Coastguard Worker       return SecurityMode::UNKNOWN;
36*84e33947SAndroid Build Coastguard Worker   }
37*84e33947SAndroid Build Coastguard Worker }
38*84e33947SAndroid Build Coastguard Worker 
39*84e33947SAndroid Build Coastguard Worker }  // namespace
40*84e33947SAndroid Build Coastguard Worker 
ScanResult()41*84e33947SAndroid Build Coastguard Worker ScanResult::ScanResult()
42*84e33947SAndroid Build Coastguard Worker     : security_modes_(SecurityMode::UNKNOWN),
43*84e33947SAndroid Build Coastguard Worker       capability_(Capability::UNKNOWN),
44*84e33947SAndroid Build Coastguard Worker       frequency_scanned_mhz_(0),
45*84e33947SAndroid Build Coastguard Worker       rssi_dbm_(-128),
46*84e33947SAndroid Build Coastguard Worker       tsf_(0) {
47*84e33947SAndroid Build Coastguard Worker   std::memset(bssid_, 0, sizeof(bssid_));
48*84e33947SAndroid Build Coastguard Worker }
49*84e33947SAndroid Build Coastguard Worker 
ScanResult(const ScanResult & other)50*84e33947SAndroid Build Coastguard Worker ScanResult::ScanResult(const ScanResult &other)
51*84e33947SAndroid Build Coastguard Worker     : ssid_(other.ssid_),
52*84e33947SAndroid Build Coastguard Worker       security_modes_(other.security_modes_),
53*84e33947SAndroid Build Coastguard Worker       capability_(other.capability_),
54*84e33947SAndroid Build Coastguard Worker       frequency_scanned_mhz_(other.frequency_scanned_mhz_),
55*84e33947SAndroid Build Coastguard Worker       rssi_dbm_(other.rssi_dbm_),
56*84e33947SAndroid Build Coastguard Worker       tsf_(other.tsf_) {
57*84e33947SAndroid Build Coastguard Worker   std::memcpy(bssid_, other.bssid_, sizeof(bssid_));
58*84e33947SAndroid Build Coastguard Worker }
59*84e33947SAndroid Build Coastguard Worker 
ScanResult(const chreWifiScanResult & chre_scan_result)60*84e33947SAndroid Build Coastguard Worker ScanResult::ScanResult(const chreWifiScanResult &chre_scan_result) {
61*84e33947SAndroid Build Coastguard Worker   UpdateFromChreWifiScanResult(chre_scan_result);
62*84e33947SAndroid Build Coastguard Worker }
63*84e33947SAndroid Build Coastguard Worker 
operator ==(const ScanResult & other) const64*84e33947SAndroid Build Coastguard Worker bool ScanResult::operator==(const ScanResult &other) const {
65*84e33947SAndroid Build Coastguard Worker   if (this == &other) {
66*84e33947SAndroid Build Coastguard Worker     return true;
67*84e33947SAndroid Build Coastguard Worker   }
68*84e33947SAndroid Build Coastguard Worker   return std::memcmp(bssid_, other.bssid_, sizeof(bssid_)) == 0 &&
69*84e33947SAndroid Build Coastguard Worker          ssid_ == other.ssid_ && security_modes_ == other.security_modes_ &&
70*84e33947SAndroid Build Coastguard Worker          capability_ == other.capability_ &&
71*84e33947SAndroid Build Coastguard Worker          frequency_scanned_mhz_ == other.frequency_scanned_mhz_ &&
72*84e33947SAndroid Build Coastguard Worker          rssi_dbm_ == other.rssi_dbm_ && tsf_ == other.tsf_;
73*84e33947SAndroid Build Coastguard Worker }
74*84e33947SAndroid Build Coastguard Worker 
Serialize(flatbuffers::FlatBufferBuilder * builder) const75*84e33947SAndroid Build Coastguard Worker flatbuffers::Offset<ScanResult::FbsType> ScanResult::Serialize(
76*84e33947SAndroid Build Coastguard Worker     flatbuffers::FlatBufferBuilder *builder) const {
77*84e33947SAndroid Build Coastguard Worker   auto ssid_offset = ssid_.Serialize(builder);
78*84e33947SAndroid Build Coastguard Worker   auto bssid_offset = builder->CreateVector(bssid_, kBssidSize);
79*84e33947SAndroid Build Coastguard Worker   return fbs::CreateScanResult(*builder, ssid_offset, security_modes_,
80*84e33947SAndroid Build Coastguard Worker                                bssid_offset, capability_,
81*84e33947SAndroid Build Coastguard Worker                                frequency_scanned_mhz_, rssi_dbm_, tsf_);
82*84e33947SAndroid Build Coastguard Worker }
83*84e33947SAndroid Build Coastguard Worker 
Deserialize(const ScanResult::FbsType & fbs_result)84*84e33947SAndroid Build Coastguard Worker bool ScanResult::Deserialize(const ScanResult::FbsType &fbs_result) {
85*84e33947SAndroid Build Coastguard Worker   if (fbs_result.ssid() == nullptr || !ssid_.Deserialize(*fbs_result.ssid())) {
86*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to deserialize ScanResult. Null or incomplete members.");
87*84e33947SAndroid Build Coastguard Worker     return false;
88*84e33947SAndroid Build Coastguard Worker   }
89*84e33947SAndroid Build Coastguard Worker 
90*84e33947SAndroid Build Coastguard Worker   security_modes_ = fbs_result.security_modes();
91*84e33947SAndroid Build Coastguard Worker   if (security_modes_ & ~SecurityMode::ALL_SECURITY_MODES_MASK) {
92*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to deserialize ScanResult. Invalid security mode.");
93*84e33947SAndroid Build Coastguard Worker     return false;
94*84e33947SAndroid Build Coastguard Worker   }
95*84e33947SAndroid Build Coastguard Worker 
96*84e33947SAndroid Build Coastguard Worker   if (fbs_result.bssid() == nullptr ||
97*84e33947SAndroid Build Coastguard Worker       fbs_result.bssid()->size() != kBssidSize) {
98*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to deserialize ScanResult. Null or incomplete members.");
99*84e33947SAndroid Build Coastguard Worker     return false;
100*84e33947SAndroid Build Coastguard Worker   }
101*84e33947SAndroid Build Coastguard Worker   for (uint8_t i = 0; i < kBssidSize; i++) {
102*84e33947SAndroid Build Coastguard Worker     bssid_[i] = fbs_result.bssid()->Get(i);
103*84e33947SAndroid Build Coastguard Worker   }
104*84e33947SAndroid Build Coastguard Worker 
105*84e33947SAndroid Build Coastguard Worker   capability_ = fbs_result.capability();
106*84e33947SAndroid Build Coastguard Worker   if ((capability_ == Capability::UNKNOWN) ||
107*84e33947SAndroid Build Coastguard Worker       (capability_ & ~Capability::ALL_CAPABILITIES_MASK)) {
108*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to deserialize ScanResult. Invalid network capability.");
109*84e33947SAndroid Build Coastguard Worker     return false;
110*84e33947SAndroid Build Coastguard Worker   }
111*84e33947SAndroid Build Coastguard Worker 
112*84e33947SAndroid Build Coastguard Worker   frequency_scanned_mhz_ = fbs_result.frequency_scanned_mhz();
113*84e33947SAndroid Build Coastguard Worker   if (!ChannelHistogram::IsSupportedFrequency(frequency_scanned_mhz_)) {
114*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to deserialize ScanResult. Invalid channel frequency.");
115*84e33947SAndroid Build Coastguard Worker     return false;
116*84e33947SAndroid Build Coastguard Worker   }
117*84e33947SAndroid Build Coastguard Worker 
118*84e33947SAndroid Build Coastguard Worker   rssi_dbm_ = fbs_result.rssi_dbm();
119*84e33947SAndroid Build Coastguard Worker   if (rssi_dbm_ > 0) {
120*84e33947SAndroid Build Coastguard Worker     LOGE("Failed to deserialize ScanResult. Positive rssi value.");
121*84e33947SAndroid Build Coastguard Worker     return false;
122*84e33947SAndroid Build Coastguard Worker   }
123*84e33947SAndroid Build Coastguard Worker 
124*84e33947SAndroid Build Coastguard Worker   tsf_ = fbs_result.tsf();
125*84e33947SAndroid Build Coastguard Worker   return true;
126*84e33947SAndroid Build Coastguard Worker }
127*84e33947SAndroid Build Coastguard Worker 
Log() const128*84e33947SAndroid Build Coastguard Worker void ScanResult::Log() const {
129*84e33947SAndroid Build Coastguard Worker   LOGI("ScanResult:");
130*84e33947SAndroid Build Coastguard Worker   ssid_.Log();
131*84e33947SAndroid Build Coastguard Worker   LOGI("  security modes: 0x%" PRIx8, security_modes_);
132*84e33947SAndroid Build Coastguard Worker   utility::LogBssid(bssid_);
133*84e33947SAndroid Build Coastguard Worker   LOGI("  capability: 0x%" PRIx16, capability_);
134*84e33947SAndroid Build Coastguard Worker   LOGI("  scanned frequency: %" PRIu32, frequency_scanned_mhz_);
135*84e33947SAndroid Build Coastguard Worker   LOGI("  rssi: %" PRId8 "dBm", rssi_dbm_);
136*84e33947SAndroid Build Coastguard Worker   LOGI("  tsf: %" PRIu64, tsf_);
137*84e33947SAndroid Build Coastguard Worker }
138*84e33947SAndroid Build Coastguard Worker 
UpdateFromChreWifiScanResult(const chreWifiScanResult & chre_scan_result)139*84e33947SAndroid Build Coastguard Worker void ScanResult::UpdateFromChreWifiScanResult(
140*84e33947SAndroid Build Coastguard Worker     const chreWifiScanResult &chre_scan_result) {
141*84e33947SAndroid Build Coastguard Worker   ssid_.SetData(chre_scan_result.ssid, chre_scan_result.ssidLen);
142*84e33947SAndroid Build Coastguard Worker 
143*84e33947SAndroid Build Coastguard Worker   security_modes_ = 0;
144*84e33947SAndroid Build Coastguard Worker   for (const auto chre_security_mode :
145*84e33947SAndroid Build Coastguard Worker        {CHRE_WIFI_SECURITY_MODE_OPEN, CHRE_WIFI_SECURITY_MODE_WEP,
146*84e33947SAndroid Build Coastguard Worker         CHRE_WIFI_SECURITY_MODE_PSK, CHRE_WIFI_SECURITY_MODE_EAP}) {
147*84e33947SAndroid Build Coastguard Worker     if (chre_scan_result.securityMode & chre_security_mode) {
148*84e33947SAndroid Build Coastguard Worker       security_modes_ |= ConvertSecurityModeChreToOffload(chre_security_mode);
149*84e33947SAndroid Build Coastguard Worker     }
150*84e33947SAndroid Build Coastguard Worker   }
151*84e33947SAndroid Build Coastguard Worker 
152*84e33947SAndroid Build Coastguard Worker   std::memcpy(bssid_, chre_scan_result.bssid, CHRE_WIFI_BSSID_LEN);
153*84e33947SAndroid Build Coastguard Worker   // TODO: make sure capability definition between two versions is the same
154*84e33947SAndroid Build Coastguard Worker   // (802.11:7.3.1.4 vs. 802.11:8.4.1.4)
155*84e33947SAndroid Build Coastguard Worker   capability_ = chre_scan_result.capabilityInfo;
156*84e33947SAndroid Build Coastguard Worker   if (chre_scan_result.channelWidth == CHRE_WIFI_CHANNEL_WIDTH_20_MHZ) {
157*84e33947SAndroid Build Coastguard Worker     frequency_scanned_mhz_ = chre_scan_result.primaryChannel;
158*84e33947SAndroid Build Coastguard Worker   } else {
159*84e33947SAndroid Build Coastguard Worker     // TODO: (b/62870147) Support other possible channel widths
160*84e33947SAndroid Build Coastguard Worker     LOGW("Scan result channel width not supported %" PRIu8,
161*84e33947SAndroid Build Coastguard Worker          chre_scan_result.channelWidth);
162*84e33947SAndroid Build Coastguard Worker   }
163*84e33947SAndroid Build Coastguard Worker 
164*84e33947SAndroid Build Coastguard Worker   rssi_dbm_ = chre_scan_result.rssi;
165*84e33947SAndroid Build Coastguard Worker   tsf_ = 0;  // tsf value not available
166*84e33947SAndroid Build Coastguard Worker }
167*84e33947SAndroid Build Coastguard Worker 
168*84e33947SAndroid Build Coastguard Worker }  // namespace wifi_offload
169