blob: b4dcc0a725033e2ad3984344bb7ba5837788a83b [file] [log] [blame]
Roshan Piuse65edb12016-11-22 13:02:01 -08001/*
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 <android-base/logging.h>
18#include <utils/SystemClock.h>
19
20#include "hidl_struct_util.h"
21
22namespace android {
23namespace hardware {
24namespace wifi {
25namespace V1_0 {
26namespace implementation {
27namespace hidl_struct_util {
28
29uint8_t ConvertHidlReportEventFlagToLegacy(
30 StaBackgroundScanBucketEventReportSchemeMask hidl_flag) {
31 using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
32 switch (hidl_flag) {
33 case HidlFlag::EACH_SCAN:
34 return REPORT_EVENTS_EACH_SCAN;
35 case HidlFlag::FULL_RESULTS:
36 return REPORT_EVENTS_FULL_RESULTS;
37 case HidlFlag::NO_BATCH:
38 return REPORT_EVENTS_NO_BATCH;
39 };
40}
41
42bool convertHidlScanParamsToLegacy(
43 const StaBackgroundScanParameters& hidl_scan_params,
44 legacy_hal::wifi_scan_cmd_params* legacy_scan_params) {
45 if (!legacy_scan_params) {
46 return false;
47 }
48 legacy_scan_params->base_period = hidl_scan_params.basePeriodInMs;
49 legacy_scan_params->max_ap_per_scan = hidl_scan_params.maxApPerScan;
50 legacy_scan_params->report_threshold_percent =
51 hidl_scan_params.reportThresholdPercent;
52 legacy_scan_params->report_threshold_num_scans =
53 hidl_scan_params.reportThresholdNumScans;
54 // TODO(b/33194311): Expose these max limits in the HIDL interface.
55 if (hidl_scan_params.buckets.size() > MAX_BUCKETS) {
56 return false;
57 }
58 legacy_scan_params->num_buckets = hidl_scan_params.buckets.size();
59 for (uint32_t bucket_idx = 0; bucket_idx < hidl_scan_params.buckets.size();
60 bucket_idx++) {
61 const StaBackgroundScanBucketParameters& hidl_bucket_spec =
62 hidl_scan_params.buckets[bucket_idx];
63 legacy_hal::wifi_scan_bucket_spec& legacy_bucket_spec =
64 legacy_scan_params->buckets[bucket_idx];
65 legacy_bucket_spec.bucket = bucket_idx;
66 legacy_bucket_spec.band =
67 static_cast<legacy_hal::wifi_band>(hidl_bucket_spec.band);
68 legacy_bucket_spec.period = hidl_bucket_spec.periodInMs;
69 legacy_bucket_spec.max_period = hidl_bucket_spec.exponentialMaxPeriodInMs;
70 legacy_bucket_spec.base = hidl_bucket_spec.exponentialBase;
71 legacy_bucket_spec.step_count = hidl_bucket_spec.exponentialStepCount;
72 legacy_bucket_spec.report_events = 0;
73 using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
74 for (const auto flag :
75 {HidlFlag::EACH_SCAN, HidlFlag::FULL_RESULTS, HidlFlag::NO_BATCH}) {
76 if (hidl_bucket_spec.eventReportScheme &
77 static_cast<std::underlying_type<HidlFlag>::type>(flag)) {
78 legacy_bucket_spec.report_events |=
79 ConvertHidlReportEventFlagToLegacy(flag);
80 }
81 }
82 // TODO(b/33194311): Expose these max limits in the HIDL interface.
83 if (hidl_bucket_spec.frequencies.size() > MAX_CHANNELS) {
84 return false;
85 }
86 legacy_bucket_spec.num_channels = hidl_bucket_spec.frequencies.size();
87 for (uint32_t freq_idx = 0; freq_idx < hidl_bucket_spec.frequencies.size();
88 freq_idx++) {
89 legacy_bucket_spec.channels[freq_idx].channel =
90 hidl_bucket_spec.frequencies[freq_idx];
91 }
92 }
93 return true;
94}
95
96bool convertLegacyIeBlobToHidl(const uint8_t* ie_blob,
97 uint32_t ie_blob_len,
98 std::vector<WifiInformationElement>* hidl_ies) {
99 if (!ie_blob || !hidl_ies) {
100 return false;
101 }
102 const uint8_t* ies_begin = ie_blob;
103 const uint8_t* ies_end = ie_blob + ie_blob_len;
104 const uint8_t* next_ie = ies_begin;
105 using wifi_ie = legacy_hal::wifi_information_element;
106 constexpr size_t kIeHeaderLen = sizeof(wifi_ie);
107 // Each IE should atleast have the header (i.e |id| & |len| fields).
108 while (next_ie + kIeHeaderLen <= ies_end) {
109 const wifi_ie& legacy_ie = (*reinterpret_cast<const wifi_ie*>(next_ie));
110 uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len;
111 if (next_ie + curr_ie_len > ies_end) {
112 return false;
113 }
114 WifiInformationElement hidl_ie;
115 hidl_ie.id = legacy_ie.id;
116 hidl_ie.data =
117 std::vector<uint8_t>(legacy_ie.data, legacy_ie.data + legacy_ie.len);
118 hidl_ies->push_back(std::move(hidl_ie));
119 next_ie += curr_ie_len;
120 }
121 // Ensure that the blob has been fully consumed.
122 return (next_ie == ies_end);
123}
124
125bool convertLegacyScanResultToHidl(
126 const legacy_hal::wifi_scan_result& legacy_scan_result,
127 bool has_ie_data,
128 StaScanResult* hidl_scan_result) {
129 if (!hidl_scan_result) {
130 return false;
131 }
132 hidl_scan_result->timeStampInUs = legacy_scan_result.ts;
133 hidl_scan_result->ssid = std::vector<uint8_t>(
134 legacy_scan_result.ssid,
135 legacy_scan_result.ssid + sizeof(legacy_scan_result.ssid));
136 memcpy(hidl_scan_result->bssid.data(),
137 legacy_scan_result.bssid,
138 hidl_scan_result->bssid.size());
139 hidl_scan_result->frequency = legacy_scan_result.channel;
140 hidl_scan_result->rssi = legacy_scan_result.rssi;
141 hidl_scan_result->beaconPeriodInMs = legacy_scan_result.beacon_period;
142 hidl_scan_result->capability = legacy_scan_result.capability;
143 if (has_ie_data) {
144 std::vector<WifiInformationElement> ies;
145 if (!convertLegacyIeBlobToHidl(
146 reinterpret_cast<const uint8_t*>(legacy_scan_result.ie_data),
147 legacy_scan_result.ie_length,
148 &ies)) {
149 return false;
150 }
151 hidl_scan_result->informationElements = std::move(ies);
152 }
153 return true;
154}
155
156bool convertLegacyCachedScanResultsToHidl(
157 const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result,
158 StaScanData* hidl_scan_data) {
159 if (!hidl_scan_data) {
160 return false;
161 }
162 hidl_scan_data->flags = legacy_cached_scan_result.flags;
163 hidl_scan_data->bucketsScanned = legacy_cached_scan_result.buckets_scanned;
164
165 CHECK(legacy_cached_scan_result.num_results >= 0 &&
166 legacy_cached_scan_result.num_results <= MAX_AP_CACHE_PER_SCAN);
167 std::vector<StaScanResult> hidl_scan_results;
168 for (int32_t result_idx = 0;
169 result_idx < legacy_cached_scan_result.num_results;
170 result_idx++) {
171 StaScanResult hidl_scan_result;
172 if (!convertLegacyScanResultToHidl(
173 legacy_cached_scan_result.results[result_idx],
174 false,
175 &hidl_scan_result)) {
176 return false;
177 }
178 hidl_scan_results.push_back(hidl_scan_result);
179 }
180 hidl_scan_data->results = std::move(hidl_scan_results);
181 return true;
182}
183
184bool convertLegacyVectorOfCachedScanResultsToHidl(
185 const std::vector<legacy_hal::wifi_cached_scan_results>&
186 legacy_cached_scan_results,
187 std::vector<StaScanData>* hidl_scan_datas) {
188 if (!hidl_scan_datas) {
189 return false;
190 }
191 for (const auto& legacy_cached_scan_result : legacy_cached_scan_results) {
192 StaScanData hidl_scan_data;
193 if (!convertLegacyCachedScanResultsToHidl(legacy_cached_scan_result,
194 &hidl_scan_data)) {
195 return false;
196 }
197 hidl_scan_datas->push_back(hidl_scan_data);
198 }
199 return true;
200}
201
202bool convertLegacyLinkLayerStatsToHidl(
203 const legacy_hal::LinkLayerStats& legacy_stats,
204 StaLinkLayerStats* hidl_stats) {
205 if (!hidl_stats) {
206 return false;
207 }
208 // iface legacy_stats conversion.
209 hidl_stats->iface.beaconRx = legacy_stats.iface.beacon_rx;
210 hidl_stats->iface.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
211 hidl_stats->iface.wmeBePktStats.rxMpdu =
212 legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
213 hidl_stats->iface.wmeBePktStats.txMpdu =
214 legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
215 hidl_stats->iface.wmeBePktStats.lostMpdu =
216 legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
217 hidl_stats->iface.wmeBePktStats.retries =
218 legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
219 hidl_stats->iface.wmeBkPktStats.rxMpdu =
220 legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
221 hidl_stats->iface.wmeBkPktStats.txMpdu =
222 legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
223 hidl_stats->iface.wmeBkPktStats.lostMpdu =
224 legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
225 hidl_stats->iface.wmeBkPktStats.retries =
226 legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
227 hidl_stats->iface.wmeViPktStats.rxMpdu =
228 legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
229 hidl_stats->iface.wmeViPktStats.txMpdu =
230 legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
231 hidl_stats->iface.wmeViPktStats.lostMpdu =
232 legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
233 hidl_stats->iface.wmeViPktStats.retries =
234 legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
235 hidl_stats->iface.wmeVoPktStats.rxMpdu =
236 legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
237 hidl_stats->iface.wmeVoPktStats.txMpdu =
238 legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
239 hidl_stats->iface.wmeVoPktStats.lostMpdu =
240 legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
241 hidl_stats->iface.wmeVoPktStats.retries =
242 legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
243 // radio legacy_stats conversion.
244 hidl_stats->radio.onTimeInMs = legacy_stats.radio.on_time;
245 hidl_stats->radio.txTimeInMs = legacy_stats.radio.tx_time;
246 hidl_stats->radio.rxTimeInMs = legacy_stats.radio.rx_time;
247 hidl_stats->radio.onTimeInMsForScan = legacy_stats.radio.on_time_scan;
248 hidl_stats->radio.txTimeInMsPerLevel = legacy_stats.radio_tx_time_per_levels;
249 // Timestamp in the HAL wrapper here since it's not provided in the legacy
250 // HAL API.
251 hidl_stats->timeStampInMs = uptimeMillis();
252 return true;
253}
254} // namespace hidl_struct_util
255} // namespace implementation
256} // namespace V1_0
257} // namespace wifi
258} // namespace hardware
259} // namespace android