Merge pull request #465 from billz/802.11ac

802.11ac config
This commit is contained in:
Bill Zimmerman 2020-01-01 10:58:22 -08:00 committed by GitHub
commit bc8ed88d93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 167 additions and 61 deletions

View File

@ -0,0 +1,17 @@
<?php
require('../../includes/csrf.php');
include_once('../../includes/config.php');
exec('cat '. RASPI_HOSTAPD_CONFIG, $hostapdconfig);
$arrConfig = array();
foreach ($hostapdconfig as $hostapdconfigline) {
if (strlen($hostapdconfigline) === 0) {
continue;
}
$arrLine = explode("=", $hostapdconfigline) ;
$arrConfig[$arrLine[0]]=$arrLine[1];
};
$channel = intval($arrConfig['channel']);
echo json_encode($channel);

View File

@ -91,31 +91,30 @@ function loadCurrentSettings(strInterface) {
} }
function saveNetworkSettings(int) { function saveNetworkSettings(int) {
var frmInt = $('#frm-'+int).find(':input'); var frmInt = $('#frm-'+int).find(':input');
var arrFormData = {}; var arrFormData = {};
$.each(frmInt,function(i3,v3){ $.each(frmInt,function(i3,v3){
if($(v3).attr('type') == 'radio') { if($(v3).attr('type') == 'radio') {
arrFormData[$(v3).attr('id')] = $(v3).prop('checked'); arrFormData[$(v3).attr('id')] = $(v3).prop('checked');
} else { } else {
arrFormData[$(v3).attr('id')] = $(v3).val(); arrFormData[$(v3).attr('id')] = $(v3).val();
} }
}); });
arrFormData['interface'] = int; arrFormData['interface'] = int;
$.post('ajax/networking/save_int_config.php',arrFormData,function(data){ $.post('ajax/networking/save_int_config.php',arrFormData,function(data){
var jsonData = JSON.parse(data); var jsonData = JSON.parse(data);
$('#msgNetworking').html(msgShow(jsonData['return'],jsonData['output'])); $('#msgNetworking').html(msgShow(jsonData['return'],jsonData['output']));
}); });
} }
function applyNetworkSettings() { function applyNetworkSettings() {
var int = $(this).data('int'); var int = $(this).data('int');
arrFormData = {}; arrFormData = {};
arrFormData['generate'] = ''; arrFormData['generate'] = '';
$.post('ajax/networking/gen_int_config.php',arrFormData,function(data){ $.post('ajax/networking/gen_int_config.php',arrFormData,function(data){
console.log(data); var jsonData = JSON.parse(data);
var jsonData = JSON.parse(data); $('#msgNetworking').html(msgShow(jsonData['return'],jsonData['output']));
$('#msgNetworking').html(msgShow(jsonData['return'],jsonData['output'])); });
});
} }
$(document).on("click", ".js-add-dhcp-static-lease", function(e) { $(document).on("click", ".js-add-dhcp-static-lease", function(e) {
@ -126,7 +125,6 @@ $(document).on("click", ".js-add-dhcp-static-lease", function(e) {
if (mac == "" || ip == "") { if (mac == "" || ip == "") {
return; return;
} }
var row = $("#js-dhcp-static-lease-row").html() var row = $("#js-dhcp-static-lease-row").html()
.replace("{{ mac }}", mac) .replace("{{ mac }}", mac)
.replace("{{ ip }}", ip); .replace("{{ ip }}", ip);
@ -147,12 +145,10 @@ $(document).on("submit", ".js-dhcp-settings-form", function(e) {
function setupBtns() { function setupBtns() {
$('#btnSummaryRefresh').click(function(){getAllInterfaces();}); $('#btnSummaryRefresh').click(function(){getAllInterfaces();});
$('.intsave').click(function(){ $('.intsave').click(function(){
var int = $(this).data('int'); var int = $(this).data('int');
saveNetworkSettings(int); saveNetworkSettings(int);
}); });
$('.intapply').click(function(){ $('.intapply').click(function(){
applyNetworkSettings(); applyNetworkSettings();
}); });
@ -173,6 +169,8 @@ function contentLoaded() {
getAllInterfaces(); getAllInterfaces();
setupTabs(); setupTabs();
setupBtns(); setupBtns();
case "hostapd_conf":
loadChannel();
break; break;
} }
} }
@ -190,6 +188,61 @@ function loadWifiStations(refresh) {
$(".js-reload-wifi-stations").on("click", loadWifiStations(true)); $(".js-reload-wifi-stations").on("click", loadWifiStations(true));
function loadChannel() {
$.get('ajax/networking/get_channel.php',function(data){
jsonData = JSON.parse(data);
loadChannelSelect(jsonData);
});
}
/*
Sets the wirelss channel select options based on hw_mode and country_code.
Methodology: In North America up to channel 11 is the maximum allowed WiFi 2.4Ghz channel,
except for the US that allows channel 12 & 13 in low power mode with additional restrictions.
Canada allows channel 12 in low power mode. Because it's unsure if low powered mode can be
supported the channels are not selectable for those countries. Also Uzbekistan and Colombia
allow up to channel 11 as maximum channel on the 2.4Ghz WiFi band.
Source: https://en.wikipedia.org/wiki/List_of_WLAN_channels
Additional: https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git
*/
function loadChannelSelect(selected) {
// Fetch wireless regulatory data
$.getJSON("config/wireless.json", function(json) {
var hw_mode = $('#cbxhwmode').val();
var country_code = $('#cbxcountries').val();
var channel_select = $('#cbxchannel');
var data = json["wireless_regdb"];
var selectablechannels = Array.range(1,14);
// Assign array of countries to valid frequencies (channels)
var countries_2_4Ghz_max11ch = data["2_4GHz_max11ch"].countries;
var countries_2_4Ghz_max14ch = data["2_4GHz_max14ch"].countries;
var countries_5Ghz_max48ch = data["5Ghz_max48ch"].countries;
// Map selected hw_mode and country to determine channel list
if (($.inArray(country_code, countries_2_4Ghz_max11ch) !== -1) && (hw_mode !== 'ac') ) {
selectablechannels = data["2_4GHz_max11ch"].channels;
} else if (($.inArray(country_code, countries_2_4Ghz_max14ch) !== -1) && (hw_mode === 'b')) {
selectablechannels = data["2_4GHz_max14ch"].channels;
} else if (($.inArray(country_code, countries_5Ghz_max48ch) !== -1) && (hw_mode === 'ac')) {
selectablechannels = data["5Ghz_max48ch"].channels;
}
// Set channel select with available values
var selected = (typeof selected === 'undefined') ? selectablechannels[0] : selected;
channel_select.empty();
$.each(selectablechannels, function(key,value) {
channel_select.append($("<option></option>").attr("value", value).text(value));
});
channel_select.val(selected);
});
}
// Static Array method
Array.range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);
$(document).on("click", ".js-toggle-password", function(e) { $(document).on("click", ".js-toggle-password", function(e) {
var button = $(e.target) var button = $(e.target)
var field = $(button.data("target")); var field = $(button.data("target"));

View File

@ -22,6 +22,9 @@ define('RASPI_OPENVPN_SERVER_CONFIG', '/etc/openvpn/server/server.conf');
define('RASPI_TORPROXY_CONFIG', '/etc/tor/torrc'); define('RASPI_TORPROXY_CONFIG', '/etc/tor/torrc');
define('RASPI_LIGHTTPD_CONFIG', '/etc/lighttpd/lighttpd.conf'); define('RASPI_LIGHTTPD_CONFIG', '/etc/lighttpd/lighttpd.conf');
// Constants for CRDA wireless regulatory domain
define('RASPI_5GHZ_ISO_ALPHA2', array('US'));
// Optional services, set to true to enable. // Optional services, set to true to enable.
define('RASPI_WIFICLIENT_ENABLED', true); define('RASPI_WIFICLIENT_ENABLED', true);
define('RASPI_HOTSPOT_ENABLED', true); define('RASPI_HOTSPOT_ENABLED', true);

View File

@ -9,8 +9,8 @@ channel=1
hw_mode=g hw_mode=g
wpa_passphrase=ChangeMe wpa_passphrase=ChangeMe
interface=wlan0 interface=wlan0
wpa=1 wpa=2
wpa_pairwise=TKIP wpa_pairwise=CCMP
country_code= country_code=
## Rapberry Pi 3 specific to on board WLAN/WiFi ## Rapberry Pi 3 specific to on board WLAN/WiFi
#ieee80211n=1 # 802.11n support (Raspberry Pi 3) #ieee80211n=1 # 802.11n support (Raspberry Pi 3)
@ -18,4 +18,5 @@ country_code=
#ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40] # (Raspberry Pi 3) #ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40] # (Raspberry Pi 3)
## RaspAP wireless client AP mode ## RaspAP wireless client AP mode
#interface=uap0 #interface=uap0

17
config/wireless.json Normal file
View File

@ -0,0 +1,17 @@
{"wireless_regdb": {
"debug": "off",
"2_4GHz_max11ch": {
"countries": [ "AG", "BS", "BB", "BZ", "CR", "CU", "DM", "DO", "SV", "GD", "GT",
"HT", "HN", "JM", "MX", "NI", "PA", "KN", "LC", "VC", "TT", "US", "CA", "UZ", "CO" ],
"channels": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]
},
"2_4GHz_max14ch": {
"countries": [ "JP" ],
"channels": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
},
"5Ghz_max48ch": {
"countries": [ "US" ],
"channels": [ 36, 40, 44, 48 ]
}
}}

View File

@ -142,19 +142,22 @@ function isAssoc($arr)
/** /**
* *
* Display a selector field for a form. Arguments are: * Display a selector field for a form. Arguments are:
* $name: Field name * @param string $name: Field name
* $options: Array of options * @param array $options: Array of options
* $selected: Selected option (optional) * @param string $selected: Selected option (optional)
* If $options is an associative array this should be the key * @param string $id: $options is an associative array this should be the key
* * @param string $event: onChange event (optional)
* @param string $disabled (optional)
*/ */
function SelectorOptions($name, $options, $selected = null, $id = null) function SelectorOptions($name, $options, $selected = null, $id = null, $event = null, $disabled = null)
{ {
echo '<select class="form-control" name="'.htmlspecialchars($name, ENT_QUOTES).'"'; echo '<select class="form-control" name="'.htmlspecialchars($name, ENT_QUOTES).'"';
if (isset($id)) { if (isset($id)) {
echo ' id="' . htmlspecialchars($id, ENT_QUOTES) .'"'; echo ' id="' . htmlspecialchars($id, ENT_QUOTES) .'"';
} }
if (isset($event)) {
echo ' onChange="' . htmlspecialchars($event, ENT_QUOTES).'()"';
}
echo '>' , PHP_EOL; echo '>' , PHP_EOL;
foreach ($options as $opt => $label) { foreach ($options as $opt => $label) {
$select = ''; $select = '';
@ -162,8 +165,10 @@ function SelectorOptions($name, $options, $selected = null, $id = null)
if ($key == $selected) { if ($key == $selected) {
$select = ' selected="selected"'; $select = ' selected="selected"';
} }
if ($key == $disabled) {
echo '<option value="'.htmlspecialchars($key, ENT_QUOTES).'"'.$select.'>'. $disabled = ' disabled';
}
echo '<option value="'.htmlspecialchars($key, ENT_QUOTES).'"'.$select.$disabled.'>'.
htmlspecialchars($label, ENT_QUOTES).'</option>' , PHP_EOL; htmlspecialchars($label, ENT_QUOTES).'</option>' , PHP_EOL;
} }

View File

@ -15,8 +15,9 @@ function DisplayHostAPDConfig()
'a' => '802.11a - 5 GHz', 'a' => '802.11a - 5 GHz',
'b' => '802.11b - 2.4 GHz', 'b' => '802.11b - 2.4 GHz',
'g' => '802.11g - 2.4 GHz', 'g' => '802.11g - 2.4 GHz',
'n' => '802.11n - 2.4 GHz' 'n' => '802.11n - 2.4 GHz',
]; 'ac' => '802.11.ac - 5 GHz'
];
$arrSecurity = array(1 => 'WPA', 2 => 'WPA2', 3 => 'WPA+WPA2', 'none' => _("None")); $arrSecurity = array(1 => 'WPA', 2 => 'WPA2', 3 => 'WPA+WPA2', 'none' => _("None"));
$arrEncType = array('TKIP' => 'TKIP', 'CCMP' => 'CCMP', 'TKIP CCMP' => 'TKIP+CCMP'); $arrEncType = array('TKIP' => 'TKIP', 'CCMP' => 'CCMP', 'TKIP CCMP' => 'TKIP+CCMP');
$managedModeEnabled = false; $managedModeEnabled = false;
@ -93,7 +94,7 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
return false; return false;
} }
if (intval($_POST['channel']) < 1 || intval($_POST['channel']) > 14) { if (intval($_POST['channel']) < 1 || intval($_POST['channel']) > 48) {
error_log("Attempting to set channel to '".$_POST['channel']."'"); error_log("Attempting to set channel to '".$_POST['channel']."'");
return false; return false;
} }
@ -180,6 +181,7 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
if ($good_input) { if ($good_input) {
// Fixed values // Fixed values
$country_code = $_POST['country_code'];
$config = 'driver=nl80211'.PHP_EOL; $config = 'driver=nl80211'.PHP_EOL;
$config.= 'ctrl_interface='.RASPI_HOSTAPD_CTRL_INTERFACE.PHP_EOL; $config.= 'ctrl_interface='.RASPI_HOSTAPD_CTRL_INTERFACE.PHP_EOL;
$config.= 'ctrl_interface_group=0'.PHP_EOL; $config.= 'ctrl_interface_group=0'.PHP_EOL;
@ -193,6 +195,20 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
$config.= 'ieee80211n=1'.PHP_EOL; $config.= 'ieee80211n=1'.PHP_EOL;
// Enable basic Quality of service // Enable basic Quality of service
$config.= 'wmm_enabled=1'.PHP_EOL; $config.= 'wmm_enabled=1'.PHP_EOL;
} elseif ($_POST['hw_mode'] === 'ac') {
$config.= 'hw_mode=a'.PHP_EOL.PHP_EOL;
$config.= '# N'.PHP_EOL;
$config.= 'ieee80211n=1'.PHP_EOL;
$config.= 'require_ht=1'.PHP_EOL;
$config.= 'ht_capab=[MAX-AMSDU-3839][HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]'.PHP_EOL.PHP_EOL;
$config.= '# AC'.PHP_EOL;
$config.= 'ieee80211ac=1'.PHP_EOL;
$config.= 'require_vht=1'.PHP_EOL;
$config.= 'ieee80211d=0'.PHP_EOL;
$config.= 'ieee80211h=0'.PHP_EOL;
$config.= 'vht_capab=[MAX-AMSDU-3839][SHORT-GI-80]'.PHP_EOL;
$config.= 'vht_oper_chwidth=1'.PHP_EOL;
$config.= 'vht_oper_centr_freq_seg0_idx=42'.PHP_EOL.PHP_EOL;
} else { } else {
$config.= 'hw_mode='.$_POST['hw_mode'].PHP_EOL; $config.= 'hw_mode='.$_POST['hw_mode'].PHP_EOL;
$config.= 'ieee80211n=0'.PHP_EOL; $config.= 'ieee80211n=0'.PHP_EOL;

View File

@ -49,38 +49,32 @@
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="cbxhwmode"><?php echo _("Wireless Mode") ;?></label> <label for="cbxhwmode"><?php echo _("Wireless Mode") ;?></label>
<?php <?php
$countries_5Ghz_max48ch = RASPI_5GHZ_ISO_ALPHA2;
$selectedHwMode = $arrConfig['hw_mode']; $selectedHwMode = $arrConfig['hw_mode'];
if (isset($arrConfig['ieee80211n'])) { if (isset($arrConfig['ieee80211n'])) {
if (strval($arrConfig['ieee80211n']) === '1') { if (strval($arrConfig['ieee80211n']) === '1') {
$selectedHwMode = 'n'; $selectedHwMode = 'n';
} }
} }
if (isset($arrConfig['ieee80211ac'])) {
SelectorOptions('hw_mode', $arr80211Standard, $selectedHwMode, 'cbxhwmode'); ?> if (strval($arrConfig['ieee80211ac']) === '1') {
$selectedHwMode = 'ac';
}
}
if (!in_array($arrConfig['country_code'], $countries_5Ghz_max48ch)) {
$hwModeDisabled = 'ac';
if ($selectedHwMode === $hwModeDisabled) {
unset($selectedHwMode);
}
}
SelectorOptions('hw_mode', $arr80211Standard, $selectedHwMode, 'cbxhwmode', 'loadChannelSelect', $hwModeDisabled); ?>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="cbxchannel"><?php echo _("Channel"); ?></label> <label for="cbxchannel"><?php echo _("Channel"); ?></label>
<?php <?php
$selectablechannels = range(1, 13); $selectablechannels = Array();
$countries_2_4Ghz_max11ch = array('AG', 'BS', 'BB', 'BZ', 'CR', 'CU', 'DM', 'DO', 'SV', 'GD', 'GT',
'HT', 'HN', 'JM', 'MX', 'NI', 'PA', 'KN', 'LC', 'VC', 'TT',
'US', 'CA', 'UZ', 'CO');
$countries_2_4Ghz_max14ch = array('JP');
if (in_array($arrConfig['country_code'], $countries_max11channels)) {
// In North America till channel 11 is the maximum allowed wi-fi 2.4Ghz channel.
// Except for the US that allows channel 12 & 13 in low power mode with additional restrictions.
// Canada that allows channel 12 in low power mode. Because it's unsure if low powered mode
// can be supported the channels are not selectable for those countries.
// source: https://en.wikipedia.org/wiki/List_of_WLAN_channels#Interference_concerns
// Also Uzbekistan and Colombia allow to select till channel 11 as maximum channel on the 2.4Ghz wi-fi band.
$selectablechannels = range(1, 11);
} elseif (in_array($arrConfig['country_code'], $countries_2_4Ghz_max14ch)) {
if ($arrConfig['hw_mode'] === 'b') {
$selectablechannels = range(1, 14);
}
}
SelectorOptions('channel', $selectablechannels, intval($arrConfig['channel']), 'cbxchannel'); ?> SelectorOptions('channel', $selectablechannels, intval($arrConfig['channel']), 'cbxchannel'); ?>
</div> </div>
</div> </div>
@ -180,7 +174,7 @@
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="cbxcountries"><?php echo _("Country Code"); ?></label> <label for="cbxcountries"><?php echo _("Country Code"); ?></label>
<input type="hidden" id="selected_country" value="<?php echo htmlspecialchars($arrConfig['country_code'], ENT_QUOTES); ?>"> <input type="hidden" id="selected_country" value="<?php echo htmlspecialchars($arrConfig['country_code'], ENT_QUOTES); ?>">
<select class="form-control" id="cbxcountries" name="country_code"> <select class="form-control" id="cbxcountries" name="country_code" onchange="loadChannelSelect()">
<option value="AF">Afghanistan</option> <option value="AF">Afghanistan</option>
<option value="AX">Åland Islands</option> <option value="AX">Åland Islands</option>
<option value="AL">Albania</option> <option value="AL">Albania</option>