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 23namespace wifi_offload { 24namespace utility { 25namespace { 26 27// The length of a string SSID with null-terminator. 28constexpr 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. 30constexpr size_t kBssidStrLen = 18; 31 32bool 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 49bool 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 62const 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 75int 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 91void LogSsid(const uint8_t *ssid, uint8_t ssid_len) { 92 const char *ssid_str = "<non-printable>"; 93 char ssid_buffer[kMaxSsidStrLen]; 94 if (ssid_len == 0) { 95 ssid_str = "<empty>"; 96 } else if (ParseSsidToStr(ssid, ssid_len, ssid_buffer, kMaxSsidStrLen)) { 97 ssid_str = ssid_buffer; 98 } else { 99 // ssid has non-printable ASCII chars, parse in hex format 100 char ssid_hex_buffer[CHRE_WIFI_SSID_MAX_LEN * 3]; 101 char *buf_ptr = ssid_hex_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_hex_buffer; 107 } 108 LOGI(" ssid: %s", ssid_str); 109} 110 111void 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 120void 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 136const 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