Skip to content

Commit c038024

Browse files
committed
Wifi (macOS): improve performance of SSID detection on Sequoia
Fix #1597 Thanks @torma616 for the information
1 parent df49a01 commit c038024

File tree

1 file changed

+39
-74
lines changed

1 file changed

+39
-74
lines changed

src/detection/wifi/wifi_apple.m

Lines changed: 39 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -21,44 +21,41 @@ @interface CWInterface()
2121
return CFBridgingRelease(result);
2222
}
2323

24-
static NSDictionary* getWifiInfoBySystemProfiler(NSString* ifName)
24+
static bool queryIpconfig(const char* ifName, FFstrbuf* result)
2525
{
26-
// Warning: costs about 2s on my machine
27-
static NSArray* spData;
28-
static bool inited;
29-
if (!inited)
30-
{
31-
inited = true;
32-
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
33-
if (ffProcessAppendStdOut(&buffer, (char* const[]) {
34-
"system_profiler",
35-
"SPAirPortDataType",
36-
"-xml",
37-
"-detailLevel",
38-
"basic",
39-
NULL
40-
}) != NULL)
41-
return nil;
42-
43-
spData = [NSPropertyListSerialization propertyListWithData:[NSData dataWithBytes:buffer.chars length:buffer.length]
44-
options:NSPropertyListImmutable
45-
format:nil
46-
error:nil];
47-
}
26+
return ffProcessAppendStdOut(result, (char* const[]) {
27+
"/usr/sbin/ipconfig",
28+
"getsummary",
29+
(char* const) ifName,
30+
NULL
31+
}) == NULL;
32+
}
4833

49-
if (spData)
50-
{
51-
for (NSDictionary* data in spData[0][@"_items"])
52-
{
53-
for (NSDictionary* inf in data[@"spairport_airport_interfaces"])
54-
{
55-
if ([ifName isEqualToString:inf[@"_name"]])
56-
return inf[@"spairport_current_network_information"];
57-
}
58-
}
59-
}
34+
static bool getWifiInfoByIpconfig(FFstrbuf* ipconfig, const char* prefix, FFstrbuf* result)
35+
{
36+
// `ipconfig getsummary <interface>` returns a string like this:
37+
// <dictionary> {
38+
// BSSID : <redacted>
39+
// IPv4 : <array> {
40+
// ...
41+
// }
42+
// IPv6 : <array> {
43+
// ...
44+
// }
45+
// InterfaceType : WiFi
46+
// LinkStatusActive : TRUE
47+
// NetworkID : XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
48+
// SSID : XXXXXX
49+
// Security : WPA2_PSK
50+
// }
6051

61-
return NULL;
52+
const char* start = memmem(ipconfig->chars, ipconfig->length, prefix, strlen(prefix));
53+
if (!start) return false;
54+
start += strlen(prefix);
55+
const char* end = strchr(start, '\n');
56+
if (!end) return false;
57+
ffStrbufSetNS(result, (uint32_t) (end - start), start);
58+
return false;
6259
}
6360

6461
const char* ffDetectWifi(FFlist* result)
@@ -93,21 +90,23 @@ @interface CWInterface()
9390
continue;
9491

9592
NSDictionary* apple = nil; // For getWifiInfoByApple80211
96-
NSDictionary* sp = nil; // For getWifiInfoBySystemProfiler
93+
FF_STRBUF_AUTO_DESTROY ipconfig = ffStrbufCreate();
9794

9895
if (inf.ssid) // https://developer.apple.com/forums/thread/732431
9996
ffStrbufAppendS(&item->conn.ssid, inf.ssid.UTF8String);
10097
else if (apple || (apple = getWifiInfoByApple80211(inf)))
10198
ffStrbufAppendS(&item->conn.ssid, [apple[@"SSID_STR"] UTF8String]);
102-
else if (sp || (sp = getWifiInfoBySystemProfiler(inf.interfaceName)))
103-
ffStrbufAppendS(&item->conn.ssid, [sp[@"_name"] UTF8String]);
99+
else if (ipconfig.length || (queryIpconfig(item->inf.description.chars, &ipconfig)))
100+
getWifiInfoByIpconfig(&ipconfig, "\n SSID : ", &item->conn.ssid);
104101
else
105102
ffStrbufSetStatic(&item->conn.ssid, "<unknown ssid>"); // https://developer.apple.com/forums/thread/732431
106103

107104
if (inf.bssid)
108105
ffStrbufAppendS(&item->conn.bssid, inf.bssid.UTF8String);
109106
else if (apple || (apple = getWifiInfoByApple80211(inf)))
110107
ffStrbufAppendS(&item->conn.bssid, [apple[@"BSSID"] UTF8String]);
108+
else if (ipconfig.length || (queryIpconfig(item->inf.description.chars, &ipconfig)))
109+
getWifiInfoByIpconfig(&ipconfig, "\n BSSID : ", &item->conn.bssid);
111110

112111
switch(inf.activePHYMode)
113112
{
@@ -138,22 +137,6 @@ @interface CWInterface()
138137
default:
139138
if (inf.activePHYMode < 8)
140139
ffStrbufAppendF(&item->conn.protocol, "Unknown (%ld)", inf.activePHYMode);
141-
else if (sp || (sp = getWifiInfoBySystemProfiler(inf.interfaceName)))
142-
{
143-
ffStrbufSetS(&item->conn.protocol, [sp[@"spairport_network_phymode"] UTF8String]);
144-
if (ffStrbufStartsWithS(&item->conn.protocol, "802.11"))
145-
{
146-
const char* subProtocol = item->conn.protocol.chars + strlen("802.11");
147-
if (ffStrEquals(subProtocol, "be"))
148-
ffStrbufSetStatic(&item->conn.protocol, "802.11be (Wi-Fi 7)");
149-
else if (ffStrEquals(subProtocol, "ax"))
150-
ffStrbufSetStatic(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
151-
else if (ffStrEquals(subProtocol, "ac"))
152-
ffStrbufSetStatic(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
153-
else if (ffStrEquals(subProtocol, "n"))
154-
ffStrbufSetStatic(&item->conn.protocol, "802.11n (Wi-Fi 4)");
155-
}
156-
}
157140
break;
158141
}
159142
item->conn.signalQuality = (double) (inf.rssiValue >= -50 ? 100 : inf.rssiValue <= -100 ? 0 : (inf.rssiValue + 100) * 2);
@@ -266,26 +249,8 @@ @interface CWInterface()
266249
}
267250
}
268251
}
269-
else if (sp || (sp = getWifiInfoBySystemProfiler(inf.interfaceName)))
270-
{
271-
ffStrbufSetS(&item->conn.security, [sp[@"spairport_security_mode"] UTF8String]);
272-
ffStrbufSubstrAfterFirstS(&item->conn.security, "_mode_");
273-
if (ffStrbufEqualS(&item->conn.security, "none"))
274-
ffStrbufSetStatic(&item->conn.security, "Insecure");
275-
else
276-
{
277-
ffStrbufReplaceAllC(&item->conn.security, '_', ' ');
278-
if (ffStrbufStartsWithS(&item->conn.security, "wpa"))
279-
{
280-
item->conn.security.chars[0] = 'W';
281-
item->conn.security.chars[1] = 'P';
282-
item->conn.security.chars[2] = 'A';
283-
char* sub = strchr(item->conn.security.chars, ' ');
284-
if (sub && sub[1])
285-
sub[1] = (char) toupper(sub[1]);
286-
}
287-
}
288-
}
252+
else if (ipconfig.length || (queryIpconfig(item->inf.description.chars, &ipconfig)))
253+
getWifiInfoByIpconfig(&ipconfig, "\n Security : ", &item->conn.security);
289254
break;
290255
default:
291256
ffStrbufAppendF(&item->conn.security, "Unknown (%ld)", inf.security);

0 commit comments

Comments
 (0)