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 <algorithm>
18 #include <cctype>
19
20 #include "chre/apps/wifi_offload/utility.h"
21 #include "chre/apps/wifi_offload/wifi_offload.h"
22
23 namespace wifi_offload {
24 namespace utility {
25 namespace {
26
27 // The length of a string SSID with null-terminator.
28 constexpr size_t kMaxSsidStrLen = CHRE_WIFI_SSID_MAX_LEN + 1;
29 // The length of a formatted BSSID string in XX:XX:XX:XX:XX:XX\0 format.
30 constexpr size_t kBssidStrLen = 18;
31
ParseSsidToStr(const uint8_t * ssid,size_t ssid_len,char * ssid_str,size_t ssid_str_len)32 bool ParseSsidToStr(const uint8_t *ssid, size_t ssid_len, char *ssid_str,
33 size_t ssid_str_len) {
34 if (ssid_str_len < ssid_len + 1) {
35 return false;
36 }
37 // Verify that the ssid is entirely printable characters and ASCII spaces.
38 for (uint8_t i = 0; i < ssid_len; i++) {
39 if (!std::isgraph(ssid[i]) && ssid[i] != ' ') {
40 return false;
41 }
42 }
43
44 std::memcpy(ssid_str, ssid, ssid_len);
45 ssid_str[ssid_len] = '\0';
46 return true;
47 }
48
ParseBssidToStr(const uint8_t bssid[CHRE_WIFI_BSSID_LEN],char * bssid_str,size_t bssid_str_len)49 bool ParseBssidToStr(const uint8_t bssid[CHRE_WIFI_BSSID_LEN], char *bssid_str,
50 size_t bssid_str_len) {
51 if (bssid_str_len < kBssidStrLen) {
52 return false;
53 }
54
55 const char *kFormat = "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8
56 ":%02" PRIx8 ":%02" PRIx8;
57 std::snprintf(bssid_str, bssid_str_len, kFormat, bssid[0], bssid[1], bssid[2],
58 bssid[3], bssid[4], bssid[5]);
59 return true;
60 }
61
ParseChreWifiBand(uint8_t band)62 const char *ParseChreWifiBand(uint8_t band) {
63 switch (band) {
64 case CHRE_WIFI_BAND_2_4_GHZ:
65 return "2.4GHz";
66 case CHRE_WIFI_BAND_5_GHZ:
67 return "5GHz";
68 default:
69 return "<invalid>";
70 }
71 }
72
73 } // namespace
74
Ieee80211FrequencyToChannel(int freq)75 int Ieee80211FrequencyToChannel(int freq) {
76 /* see 802.11-2007 17.3.8.3.2 and Annex J */
77 if (freq == 2484)
78 return 14;
79 else if (freq < 2484)
80 return (freq - 2407) / 5;
81 else if (freq >= 4910 && freq <= 4980)
82 return (freq - 4000) / 5;
83 else if (freq <= 45000) /* DMG band lower limit */
84 return (freq - 5000) / 5;
85 else if (freq >= 58320 && freq <= 64800)
86 return (freq - 56160) / 2160;
87 else
88 return 0;
89 }
90
LogSsid(const uint8_t * ssid,uint8_t ssid_len)91 void LogSsid(const uint8_t *ssid, uint8_t ssid_len) {
92 const char *ssid_str = "<non-printable>";
93 char ssid_buffer[std::max<size_t>(kMaxSsidStrLen,
94 CHRE_WIFI_SSID_MAX_LEN * 3)];
95 if (ssid_len == 0) {
96 ssid_str = "<empty>";
97 } else if (ParseSsidToStr(ssid, ssid_len, ssid_buffer, kMaxSsidStrLen)) {
98 ssid_str = ssid_buffer;
99 } else {
100 // ssid has non-printable ASCII chars, parse in hex format
101 char *buf_ptr = ssid_buffer;
102 for (size_t i = 0; i < ssid_len; i++) {
103 buf_ptr += std::sprintf(buf_ptr, "%02" PRIx8 ":", ssid[i]);
104 }
105 buf_ptr[-1] = '\0';
106 ssid_str = ssid_buffer;
107 }
108 LOGI(" ssid: %s", ssid_str);
109 }
110
LogBssid(const uint8_t * bssid)111 void LogBssid(const uint8_t *bssid) {
112 const char *bssid_str = "<non-printable>";
113 char bssidBuffer[kBssidStrLen];
114 if (ParseBssidToStr(bssid, bssidBuffer, kBssidStrLen)) {
115 bssid_str = bssidBuffer;
116 }
117 LOGI(" bssid: %s", bssid_str);
118 }
119
LogChreScanResult(const chreWifiScanResult & result)120 void LogChreScanResult(const chreWifiScanResult &result) {
121 LOGI("chreWifiScanResult:");
122 LogSsid(result.ssid, result.ssidLen);
123 LOGI(" age (ms): %" PRIu32, result.ageMs);
124 LOGI(" capability info: 0x%" PRIx16, result.capabilityInfo);
125 LogBssid(result.bssid);
126 LOGI(" flags: 0x%" PRIx8, result.flags);
127 LOGI(" rssi: %" PRId8 "dBm", result.rssi);
128 LOGI(" band: %s (%" PRIu8 ")", ParseChreWifiBand(result.band), result.band);
129 LOGI(" primary channel: %" PRIu32, result.primaryChannel);
130 LOGI(" center frequency primary: %" PRIu32, result.centerFreqPrimary);
131 LOGI(" center frequency secondary: %" PRIu32, result.centerFreqSecondary);
132 LOGI(" channel width: %" PRIu8, result.channelWidth);
133 LOGI(" security mode: %" PRIu8, result.securityMode);
134 }
135
GetErrorCodeName(ErrorCode error_code)136 const char *GetErrorCodeName(ErrorCode error_code) {
137 switch (error_code) {
138 case SUCCESS:
139 return "SUCCESS";
140 case FAILED_TO_ALLOCATE_MESSAGE_BUFFER:
141 return "FAILED_TO_ALLOCATE_MESSAGE_BUFFER";
142 case FAILED_TO_SERIALIZE_MESSAGE:
143 return "FAILED_TO_SERIALIZE_MESSAGE";
144 case FAILED_TO_SEND_MESSAGE:
145 return "FAILED_TO_SEND_MESSAGE";
146 case FAILED_TO_DESERIALIZE_SCAN_CONFIG:
147 return "FAILED_TO_DESERIALIZE_SCAN_CONFIG";
148 case INVALID_SUBSCRIBE_MESSAGE_SIZE:
149 return "INVALID_SUBSCRIBE_MESSAGE_SIZE";
150 case SCAN_CONFIG_NOT_INITIALIZED:
151 return "SCAN_CONFIG_NOT_INITIALIZED";
152 case UNSPECIFIED_HOST_ENDPOINT:
153 return "UNSPECIFIED_HOST_ENDPOINT";
154 case FAILED_TO_SEND_SCAN_RESULTS:
155 return "FAILED_TO_SEND_SCAN_RESULTS";
156 case FAILED_TO_SEND_SCAN_STATS:
157 return "FAILED_TO_SEND_SCAN_STATS";
158 case SCAN_MONITORING_NOT_SUPPORTED:
159 return "SCAN_MONITORING_NOT_SUPPORTED";
160 case FAILED_TO_START_SCAN_MONITORING:
161 return "FAILED_TO_START_SCAN_MONITORING";
162 case FAILED_TO_STOP_SCAN_MONITORING:
163 return "FAILED_TO_STOP_SCAN_MONITORING";
164 case FAILED_TO_CONFIGURE_SCAN_MONITORING_ASYNC:
165 return "FAILED_TO_CONFIGURE_SCAN_MONITORING_ASYNC";
166 case ONDEMAND_SCAN_NOT_SUPPORTED:
167 return "ONDEMAND_SCAN_NOT_SUPPORTED";
168 case FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST:
169 return "FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST";
170 case FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST_ASYNC:
171 return "FAILED_TO_SEND_ONDEMAND_SCAN_REQUEST_ASYNC";
172 case OUT_OF_ORDER_SCAN_RESULTS:
173 return "OUT_OF_ORDER_SCAN_RESULTS";
174 case INCOMPLETE_SCAN_RESULTS_BEFORE_SCAN_REQUEST:
175 return "INCOMPLETE_SCAN_RESULTS_BEFORE_SCAN_REQUEST";
176 case FAILED_TO_SET_SCAN_TIMER:
177 return "FAILED_TO_SET_SCAN_TIMER";
178 default:
179 return "UNKNOWN_ERROR";
180 }
181 }
182
183 } // namespace utility
184 } // namespace wifi_offload
185