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
ToHidlRecordName(const wifi_offload::RpcLogRecord::RpcLogRecordType & chreRecordType,android::hardware::wifi::offload::V1_0::RecordName * hidlRecordName)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
ToChreSecurityMode(uint8_t hidlSecurityMode)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
ToHidlSecurityMode(uint8_t chreSecurityMode)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
ToHidlScanResult(const wifi_offload::ScanResult & chreScanResult,ScanResult * hidlScanResult)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
ToHidlScanResults(const std::vector<wifi_offload::ScanResult> & chreScanResults,std::vector<ScanResult> * hidlScanResults)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
ToHidlScanStats(const wifi_offload::ScanStats & chreScanStats,ScanStats * hidlScanStats)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
ToChreScanConfig(const ScanParam & param,const ScanFilter & filter,wifi_offload::ScanConfig * scanConfig)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
ToHidlErrorMessage(uint32_t errorCode,std::string * errorMessage)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