$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); $var = '/var/local/emhttp/var.ini'; $cfg = '/boot/config/wireless.cfg'; $ssl = '/etc/rc.d/rc.ssl.input'; $tmp = '/var/tmp/attr'; $wifi = is_readable($cfg) ? (array)parse_ini_file($cfg,true) : []; $attr = is_readable($tmp) ? (array)parse_ini_file($tmp,true) : []; $md5 = md5(json_encode($attr),true); $cmd = $_POST['cmd'] ?? ''; $masks = [ '255.0.0.0' => '8', '255.255.0.0' => '16', '255.255.128.0' => '17', '255.255.192.0' => '18', '255.255.224.0' => '19', '255.255.240.0' => '20', '255.255.248.0' => '21', '255.255.252.0' => '22', '255.255.254.0' => '23', '255.255.255.0' => '24', '255.255.255.128' => '25', '255.255.255.192' => '26', '255.255.255.224' => '27', '255.255.255.240' => '28', '255.255.255.248' => '29', '255.255.255.252' => '30' ]; // add translations $_SERVER['REQUEST_URI'] = 'settings'; require_once "$docroot/webGui/include/Translations.php"; require_once "$docroot/webGui/include/Helpers.php"; function escapeSSID($text) { return str_replace('"', '\"', $text); } function scanWifi($port) { $wlan = []; exec("iw ".escapeshellarg($port)." scan | grep -P '^BSS|freq:|signal:|SSID:|Authentication suites:' | sed -r ':a;N;\$!ba;s/\\n\\s+/ /g'", $scan); foreach ($scan as $row) { $attr = preg_split('/ (freq|signal|SSID|\* Authentication suites): /', $row); // skip incomplete info if (count($attr) < 4 || (count($attr) == 4 && str_contains($row, 'Authentication suites:'))) continue; $network = $attr[3]; // skip nullified networks if (str_starts_with($network, '\\x00')) continue; if (empty($wlan[$network])) { $wlan[$network] = $attr; // store MAC address only $wlan[$network][0] = substr($wlan[$network][0],4,17); // identify open network $wlan[$network][4] ??= 'open'; } else { // group radio frequencies $wlan[$network][1] .= ' '.$attr[1]; } } return $wlan; } function saveWifi() { global $cfg, $wifi; $text = []; foreach ($wifi as $network => $block) { $text[] = "[$network]"; foreach ($block as $key => $value) $text[] = "$key=\"$value\""; } file_put_contents_atomic($cfg,implode("\n",$text)."\n"); } function saveAttr() { global $tmp, $attr, $md5; $text = []; if (md5(json_encode($attr),true) === $md5) return; foreach ($attr as $network => $block) { $text[] = "[$network]"; foreach ($block as $key => $value) $text[] = "$key=\"$value\""; } file_put_contents_atomic($tmp,implode("\n",$text)."\n"); } switch ($cmd) { case 'list': $load = $_POST['load'] ?? false; $title = _('Connect to WiFi network'); $port = array_key_first($wifi); $carrier = "/sys/class/net/$port/carrier"; $echo = $wlan = []; foreach ($wifi as $network => $block) { if ($network == $port) continue; $wlan[$network][0] = $block['ATTR1'] ?? ''; $wlan[$network][1] = $block['ATTR4'] ?? ''; $wlan[$network][2] = $block['ATTR2'] ?? ''; $wlan[$network][3] = $network; $wlan[$network][4] = $block['ATTR3'] ?? $block['SECURITY'] ?? ''; } if (!$load) $wlan = array_replace_recursive($wlan, scanWifi($port)); if (count($wlan)) { try { $up = @file_get_contents($carrier) == 1; } catch (Exception $e) { $up = false; } $alive = $up ? exec("iw ".escapeshellarg($port)." link 2>/dev/null | grep -Pom1 'SSID: \K.+'") : ''; $state = $up ? _('Connected') : _('Disconnected'); $color = $up ? 'blue' : 'red'; foreach ($wlan as $network => $block) { $attr[$network]['ATTR1'] = $block[0] ?? ''; $attr[$network]['ATTR2'] = $block[2] ?? ''; $attr[$network]['ATTR3'] = $block[4] ?? ''; $attr[$network]['ATTR4'] = $block[1] ?? ''; if (isset($wifi[$network]['GROUP'])) { if ($network == $alive || $wifi[$network]['GROUP'] == 'active') { $echo['active'][] = "