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 "chre/util/nanoapp/wifi.h"
18 
19 #ifdef CHRE_IS_NANOAPP_BUILD
20 #include "util/nanoapp/log.h"
21 #else
22 #include "chre/platform/log.h"
23 #endif  // CHRE_IS_NANOAPP_BUILD
24 
25 #include <cctype>
26 #include <cinttypes>
27 #include <cstdio>
28 #include <cstring>
29 
30 namespace chre {
31 
logChreWifiResult(const chreWifiScanResult & result,bool logSsidOnly)32 void logChreWifiResult(const chreWifiScanResult &result, bool logSsidOnly) {
33   const char *ssidStr = "<non-printable>";
34   char ssidBuffer[kMaxSsidStrLen];
35   if (result.ssidLen == 0) {
36     ssidStr = "<empty>";
37   } else if (parseSsidToStr(ssidBuffer, sizeof(ssidBuffer), result.ssid,
38                             result.ssidLen)) {
39     ssidStr = ssidBuffer;
40   }
41 
42   LOGI("Found network with SSID: %s", ssidStr);
43   if (!logSsidOnly) {
44     const char *bssidStr = "<non-printable>";
45     char bssidBuffer[kBssidStrLen];
46     if (parseBssidToStr(result.bssid, bssidBuffer, sizeof(bssidBuffer))) {
47       bssidStr = bssidBuffer;
48     }
49 
50     LOGI("  age (ms): %" PRIu32, result.ageMs);
51     LOGI("  capability info: %" PRIx16, result.capabilityInfo);
52     LOGI("  bssid: %s", bssidStr);
53     LOGI("  flags: %" PRIx8, result.flags);
54     LOGI("  rssi: %" PRId8 "dBm", result.rssi);
55     LOGI("  band: %s (%" PRIu8 ")", parseChreWifiBand(result.band),
56          result.band);
57     LOGI("  primary channel: %" PRIu32, result.primaryChannel);
58     LOGI("  center frequency primary: %" PRIu32, result.centerFreqPrimary);
59     LOGI("  center frequency secondary: %" PRIu32, result.centerFreqSecondary);
60     LOGI("  channel width: %" PRIu8, result.channelWidth);
61     LOGI("  security mode: %" PRIx8, result.securityMode);
62   }
63 }
64 
parseSsidToStr(char * buffer,size_t bufferLen,const uint8_t * ssid,uint8_t ssidLen)65 bool parseSsidToStr(char *buffer, size_t bufferLen, const uint8_t *ssid,
66                     uint8_t ssidLen) {
67   // Ensure that there is enough space in the buffer to copy the SSID and
68   // null-terminate it.
69   bool success = (bufferLen >= static_cast<size_t>(ssidLen + 1));
70 
71   if (success) {
72     // Verify that the ssid is entirely printable characters and ASCII spaces.
73     for (uint8_t i = 0; i < ssidLen; i++) {
74       if (!isgraph(ssid[i]) && ssid[i] != ' ') {
75         success = false;
76         break;
77       }
78     }
79   }
80 
81   if (success) {
82     // Copy the SSID to the buffer and null-terminate.
83     memcpy(buffer, ssid, ssidLen + 1);
84     buffer[ssidLen] = '\0';
85   }
86 
87   return success;
88 }
89 
parseBssidToStr(const uint8_t bssid[CHRE_WIFI_BSSID_LEN],char * buffer,size_t bufferLen)90 bool parseBssidToStr(const uint8_t bssid[CHRE_WIFI_BSSID_LEN], char *buffer,
91                      size_t bufferLen) {
92   const char *kFormat = "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8
93                         ":%02" PRIx8 ":%02" PRIx8;
94 
95   bool success = false;
96   if (bufferLen >= kBssidStrLen) {
97     success = true;
98     snprintf(buffer, bufferLen, kFormat, bssid[0], bssid[1], bssid[2], bssid[3],
99              bssid[4], bssid[5]);
100   }
101 
102   return success;
103 }
104 
parseChreWifiBand(uint8_t band)105 const char *parseChreWifiBand(uint8_t band) {
106   switch (band) {
107     case CHRE_WIFI_BAND_2_4_GHZ:
108       return "2.4GHz";
109     case CHRE_WIFI_BAND_MASK_5_GHZ:
110       return "5GHz";
111     default:
112       return "<invalid>";
113   }
114 }
115 
116 }  // namespace chre
117