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