From 55a8eb85ebb84e7a397f1a7628743a162a1eb08f Mon Sep 17 00:00:00 2001 From: billz Date: Sun, 5 Nov 2023 10:05:16 +0000 Subject: [PATCH] Initial commit --- src/RaspAP/Parsers/IwParser.php | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/RaspAP/Parsers/IwParser.php diff --git a/src/RaspAP/Parsers/IwParser.php b/src/RaspAP/Parsers/IwParser.php new file mode 100644 index 00000000..324935cf --- /dev/null +++ b/src/RaspAP/Parsers/IwParser.php @@ -0,0 +1,85 @@ + + * @license https://github.com/raspap/raspap-webgui/blob/master/LICENSE + * @see https://wireless.wiki.kernel.org/en/users/Documentation/iw + */ + +declare(strict_types=1); + +namespace RaspAP\Parsers; + +class IwParser { + private $iw_output; + + public function __construct(string $interface = 'wlan0') { + + // Resolve physical device for selected interface + $iface = escapeshellarg($interface); + exec("iw dev | awk -v iface=".$iface." '/^phy#/ { phy = $0 } $1 == \"Interface\" { interface = $2 } interface == iface { print phy }'", $return); + $phy = $return[0]; + + // Fetch 'iw info' output for phy + $this->iw_output = shell_exec("iw $phy info"); + } + + public function parseIwList() { + + /** + * (no IR): the AP won't Initiate Radiation until a DFS scan (or similar) is complete on these bands. + * (radar detection): the specified channels are shared with radar equipment. + * (disabled): self-explanatory. + */ + $excluded = array( + "(no IR, radar detection)", + "(radar detection)", + "(disabled)", + "(no IR)" + ); + $excluded_pattern = implode('|', array_map('preg_quote', $excluded)); + $pattern = '/\*\s+(\d+)\s+MHz \[(\d+)\] \(([\d.]+) dBm\)\s(?!' .$excluded_pattern. ')/'; + $supportedFrequencies = []; + + // Match iw_output containing supported frequencies + preg_match_all($pattern, $this->iw_output, $matches, PREG_SET_ORDER, 0); + + foreach ($matches as $match) { + $frequency = [ + 'MHz' => (int)$match[1], + 'Channel' => (int)$match[2], + 'dBm' => (float)$match[3], + ]; + $supportedFrequencies[] = $frequency; + } + return $supportedFrequencies; + } + + /** + * Converts an ieee80211 frequency to a channel value + * Adapted from iw source + * @param int $freq + * @see https://git.kernel.org/pub/scm/linux/kernel/git/jberg/iw.git/tree/util.c + */ + public function ieee80211_frequency_to_channel(int $freq) + { + /* see 802.11-2007 17.3.8.3.2 and Annex J */ + if ($freq == 2484) { + return 14; + } else if ($freq < 2484) { + return ($freq - 2407) / 5; + } else if ($freq >= 4910 && $freq <= 4980) { + return ($freq - 4000) / 5; + } else if ($freq <= 45000) { /* DMG band lower limit */ + return ($freq - 5000) / 5; + } else if ($freq >= 58320 && $freq <= 64800) { + return ($freq - 56160) / 2160; + } else { + return 0; + } + } +} +