mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 21:56:50 -04:00
Make WiFi channels configurable (fixes #50).
This commit is contained in:
@@ -15,6 +15,9 @@ CREATE TABLE event_settings (
|
||||
apaddress VARCHAR(255),
|
||||
apusername VARCHAR(255),
|
||||
appassword VARCHAR(255),
|
||||
apteamchannel int,
|
||||
apadminchannel int,
|
||||
apadminwpakey VARCHAR(255),
|
||||
switchaddress VARCHAR(255),
|
||||
switchpassword VARCHAR(255),
|
||||
bandwidthmonitoringenabled bool,
|
||||
|
||||
@@ -27,19 +27,23 @@ const (
|
||||
)
|
||||
|
||||
type AccessPoint struct {
|
||||
address string
|
||||
port int
|
||||
username string
|
||||
password string
|
||||
address string
|
||||
port int
|
||||
username string
|
||||
password string
|
||||
teamChannel int
|
||||
adminChannel int
|
||||
adminWpaKey string
|
||||
}
|
||||
|
||||
func NewAccessPoint(address, username, password string) *AccessPoint {
|
||||
return &AccessPoint{address: address, port: accessPointSshPort, username: username, password: password}
|
||||
func NewAccessPoint(address, username, password string, teamChannel, adminChannel int, adminWpaKey string) *AccessPoint {
|
||||
return &AccessPoint{address: address, port: accessPointSshPort, username: username, password: password,
|
||||
teamChannel: teamChannel, adminChannel: adminChannel, adminWpaKey: adminWpaKey}
|
||||
}
|
||||
|
||||
// Sets up wireless networks for the given set of teams.
|
||||
func (ap *AccessPoint) ConfigureTeamWifi(red1, red2, red3, blue1, blue2, blue3 *model.Team) error {
|
||||
config, err := generateAccessPointConfig(red1, red2, red3, blue1, blue2, blue3)
|
||||
config, err := ap.generateAccessPointConfig(red1, red2, red3, blue1, blue2, blue3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -47,6 +51,15 @@ func (ap *AccessPoint) ConfigureTeamWifi(red1, red2, red3, blue1, blue2, blue3 *
|
||||
return ap.runCommand(command)
|
||||
}
|
||||
|
||||
func (ap *AccessPoint) ConfigureAdminWifi() error {
|
||||
config, err := ap.generateAccessPointConfig(nil, nil, nil, nil, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
command := fmt.Sprintf("cat <<ENDCONFIG > /etc/config/wireless && wifi radio1\n%sENDCONFIG\n", config)
|
||||
return ap.runCommand(command)
|
||||
}
|
||||
|
||||
// Logs into the access point via SSH and runs the given shell command.
|
||||
func (ap *AccessPoint) runCommand(command string) error {
|
||||
// Open an SSH connection to the AP.
|
||||
@@ -69,7 +82,7 @@ func (ap *AccessPoint) runCommand(command string) error {
|
||||
return session.Run(command)
|
||||
}
|
||||
|
||||
func generateAccessPointConfig(red1, red2, red3, blue1, blue2, blue3 *model.Team) (string, error) {
|
||||
func (ap *AccessPoint) generateAccessPointConfig(red1, red2, red3, blue1, blue2, blue3 *model.Team) (string, error) {
|
||||
// Determine what new SSIDs are needed.
|
||||
networks := make(map[int]*model.Team)
|
||||
var err error
|
||||
@@ -97,8 +110,14 @@ func generateAccessPointConfig(red1, red2, red3, blue1, blue2, blue3 *model.Team
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data := struct {
|
||||
Networks map[int]*model.Team
|
||||
TeamChannel int
|
||||
AdminChannel int
|
||||
AdminWpaKey string
|
||||
}{networks, ap.teamChannel, ap.adminChannel, ap.adminWpaKey}
|
||||
var configFile bytes.Buffer
|
||||
err = template.Execute(&configFile, networks)
|
||||
err = template.Execute(&configFile, data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -17,26 +18,31 @@ func TestConfigureAccessPoint(t *testing.T) {
|
||||
ssidRe := regexp.MustCompile("option ssid '([-\\w ]+)'")
|
||||
wpaKeyRe := regexp.MustCompile("option key '([-\\w ]+)'")
|
||||
vlanRe := regexp.MustCompile("option network 'vlan(\\d+)'")
|
||||
channelRe := regexp.MustCompile("option channel '(\\d+)'")
|
||||
ap := AccessPoint{teamChannel: 1234, adminChannel: 4321, adminWpaKey: "blorpy"}
|
||||
|
||||
// Should not configure any team SSIDs if there are no teams.
|
||||
config, _ := generateAccessPointConfig(nil, nil, nil, nil, nil, nil)
|
||||
config, _ := ap.generateAccessPointConfig(nil, nil, nil, nil, nil, nil)
|
||||
assert.NotContains(t, config, "option device 'radio0'")
|
||||
ssids := ssidRe.FindAllStringSubmatch(config, -1)
|
||||
wpaKeys := wpaKeyRe.FindAllStringSubmatch(config, -1)
|
||||
vlans := vlanRe.FindAllStringSubmatch(config, -1)
|
||||
channels := channelRe.FindAllStringSubmatch(config, -1)
|
||||
assert.Equal(t, "Cheesy Arena", ssids[0][1])
|
||||
assert.Equal(t, "1234Five", wpaKeys[0][1])
|
||||
assert.Equal(t, ap.adminWpaKey, wpaKeys[0][1])
|
||||
assert.Equal(t, "100", vlans[0][1])
|
||||
assert.Equal(t, strconv.Itoa(ap.adminChannel), channels[0][1])
|
||||
assert.Equal(t, strconv.Itoa(ap.teamChannel), channels[1][1])
|
||||
|
||||
// Should configure two SSID for two teams.
|
||||
config, _ = generateAccessPointConfig(&model.Team{Id: 254, WpaKey: "aaaaaaaa"}, nil, nil, nil, nil,
|
||||
config, _ = ap.generateAccessPointConfig(&model.Team{Id: 254, WpaKey: "aaaaaaaa"}, nil, nil, nil, nil,
|
||||
&model.Team{Id: 1114, WpaKey: "bbbbbbbb"})
|
||||
assert.Equal(t, 2, len(radioRe.FindAllString(config, -1)))
|
||||
ssids = ssidRe.FindAllStringSubmatch(config, -1)
|
||||
wpaKeys = wpaKeyRe.FindAllStringSubmatch(config, -1)
|
||||
vlans = vlanRe.FindAllStringSubmatch(config, -1)
|
||||
assert.Equal(t, "Cheesy Arena", ssids[0][1])
|
||||
assert.Equal(t, "1234Five", wpaKeys[0][1])
|
||||
assert.Equal(t, ap.adminWpaKey, wpaKeys[0][1])
|
||||
assert.Equal(t, "100", vlans[0][1])
|
||||
assert.Equal(t, "254", ssids[1][1])
|
||||
assert.Equal(t, "aaaaaaaa", wpaKeys[1][1])
|
||||
@@ -46,7 +52,7 @@ func TestConfigureAccessPoint(t *testing.T) {
|
||||
assert.Equal(t, "60", vlans[2][1])
|
||||
|
||||
// Should configure all SSIDs for six teams.
|
||||
config, _ = generateAccessPointConfig(&model.Team{Id: 1, WpaKey: "11111111"},
|
||||
config, _ = ap.generateAccessPointConfig(&model.Team{Id: 1, WpaKey: "11111111"},
|
||||
&model.Team{Id: 2, WpaKey: "22222222"}, &model.Team{Id: 3, WpaKey: "33333333"},
|
||||
&model.Team{Id: 4, WpaKey: "44444444"}, &model.Team{Id: 5, WpaKey: "55555555"},
|
||||
&model.Team{Id: 6, WpaKey: "66666666"})
|
||||
@@ -55,7 +61,7 @@ func TestConfigureAccessPoint(t *testing.T) {
|
||||
wpaKeys = wpaKeyRe.FindAllStringSubmatch(config, -1)
|
||||
vlans = vlanRe.FindAllStringSubmatch(config, -1)
|
||||
assert.Equal(t, "Cheesy Arena", ssids[0][1])
|
||||
assert.Equal(t, "1234Five", wpaKeys[0][1])
|
||||
assert.Equal(t, ap.adminWpaKey, wpaKeys[0][1])
|
||||
assert.Equal(t, "100", vlans[0][1])
|
||||
assert.Equal(t, "1", ssids[1][1])
|
||||
assert.Equal(t, "11111111", wpaKeys[1][1])
|
||||
@@ -77,7 +83,7 @@ func TestConfigureAccessPoint(t *testing.T) {
|
||||
assert.Equal(t, "60", vlans[6][1])
|
||||
|
||||
// Should reject a missing WPA key.
|
||||
_, err := generateAccessPointConfig(&model.Team{Id: 254}, nil, nil, nil, nil, nil)
|
||||
_, err := ap.generateAccessPointConfig(&model.Team{Id: 254}, nil, nil, nil, nil, nil)
|
||||
if assert.NotNil(t, err) {
|
||||
assert.Contains(t, err.Error(), "Invalid WPA key")
|
||||
}
|
||||
|
||||
@@ -148,12 +148,18 @@ func (arena *Arena) LoadSettings() error {
|
||||
arena.EventSettings = settings
|
||||
|
||||
// Initialize the components that depend on settings.
|
||||
arena.accessPoint = NewAccessPoint(settings.ApAddress, settings.ApUsername, settings.ApPassword)
|
||||
arena.accessPoint = NewAccessPoint(settings.ApAddress, settings.ApUsername, settings.ApPassword,
|
||||
settings.ApTeamChannel, settings.ApAdminChannel, settings.ApAdminWpaKey)
|
||||
arena.networkSwitch = NewNetworkSwitch(settings.SwitchAddress, settings.SwitchPassword)
|
||||
arena.Plc.SetAddress(settings.PlcAddress)
|
||||
arena.TbaClient = partner.NewTbaClient(settings.TbaEventCode, settings.TbaSecretId, settings.TbaSecret)
|
||||
arena.StemTvClient = partner.NewStemTvClient(settings.StemTvEventCode)
|
||||
|
||||
err = arena.accessPoint.ConfigureAdminWifi()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ type EventSettings struct {
|
||||
ApAddress string
|
||||
ApUsername string
|
||||
ApPassword string
|
||||
ApTeamChannel int
|
||||
ApAdminChannel int
|
||||
ApAdminWpaKey string
|
||||
SwitchAddress string
|
||||
SwitchPassword string
|
||||
BandwidthMonitoringEnabled bool
|
||||
@@ -44,6 +47,9 @@ func (database *Database) GetEventSettings() (*EventSettings, error) {
|
||||
eventSettings.SelectionRound2Order = "L"
|
||||
eventSettings.SelectionRound3Order = ""
|
||||
eventSettings.TBADownloadEnabled = true
|
||||
eventSettings.ApTeamChannel = 157
|
||||
eventSettings.ApAdminChannel = 11
|
||||
eventSettings.ApAdminWpaKey = "1234Five"
|
||||
|
||||
err = database.eventSettingsMap.Insert(eventSettings)
|
||||
if err != nil {
|
||||
|
||||
@@ -14,8 +14,8 @@ func TestEventSettingsReadWrite(t *testing.T) {
|
||||
eventSettings, err := db.GetEventSettings()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, EventSettings{Id: 0, Name: "Untitled Event", DisplayBackgroundColor: "#00ff00",
|
||||
NumElimAlliances: 8, SelectionRound2Order: "L", SelectionRound3Order: "", TBADownloadEnabled: true},
|
||||
*eventSettings)
|
||||
NumElimAlliances: 8, SelectionRound2Order: "L", SelectionRound3Order: "", TBADownloadEnabled: true,
|
||||
ApTeamChannel: 157, ApAdminChannel: 11, ApAdminWpaKey: "1234Five"}, *eventSettings)
|
||||
|
||||
eventSettings.Name = "Chezy Champs"
|
||||
eventSettings.DisplayBackgroundColor = "#ff00ff"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
config wifi-device 'radio1'
|
||||
option type 'mac80211'
|
||||
option channel '11'
|
||||
option channel '{{.AdminChannel}}'
|
||||
option hwmode '11g'
|
||||
option path 'soc/soc:pcie-controller/pci0000:00/0000:00:02.0/0000:02:00.0'
|
||||
option htmode 'HT20'
|
||||
@@ -15,7 +15,7 @@ config wifi-iface
|
||||
option encryption 'psk2+ccmp'
|
||||
option network 'vlan100'
|
||||
option ssid 'Cheesy Arena'
|
||||
option key '1234Five'
|
||||
option key '{{.AdminWpaKey}}'
|
||||
option macaddr '62:38:e0:12:6b:17'
|
||||
|
||||
config wifi-device 'radio0'
|
||||
@@ -23,13 +23,13 @@ config wifi-device 'radio0'
|
||||
option hwmode '11a'
|
||||
option path 'soc/soc:pcie-controller/pci0000:00/0000:00:01.0/0000:01:00.0'
|
||||
option txpower '23'
|
||||
option channel '157'
|
||||
option channel '{{.TeamChannel}}'
|
||||
option country 'US'
|
||||
option htmode 'HT20'
|
||||
option basic_rates '6500,7200'
|
||||
option short_gi_20 '0'
|
||||
|
||||
{{range $vlan, $team := .}}
|
||||
{{range $vlan, $team := .Networks}}
|
||||
config wifi-iface
|
||||
option device 'radio0'
|
||||
option mode 'ap'
|
||||
|
||||
@@ -180,6 +180,37 @@
|
||||
<input type="password" class="form-control" name="apPassword" value="{{.ApPassword}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-5 control-label">AP Team Channel (5GHz)</label>
|
||||
<div class="col-lg-7">
|
||||
<select class="form-control" name="apTeamChannel" value="{{.ApTeamChannel}}">
|
||||
<option{{if eq .ApTeamChannel 36}} selected{{end}}>36</option>
|
||||
<option{{if eq .ApTeamChannel 40}} selected{{end}}>40</option>
|
||||
<option{{if eq .ApTeamChannel 44}} selected{{end}}>44</option>
|
||||
<option{{if eq .ApTeamChannel 48}} selected{{end}}>48</option>
|
||||
<option{{if eq .ApTeamChannel 149}} selected{{end}}>149</option>
|
||||
<option{{if eq .ApTeamChannel 153}} selected{{end}}>153</option>
|
||||
<option{{if eq .ApTeamChannel 157}} selected{{end}}>157</option>
|
||||
<option{{if eq .ApTeamChannel 161}} selected{{end}}>161</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-5 control-label">AP Admin Channel (2.4GHz)</label>
|
||||
<div class="col-lg-7">
|
||||
<select class="form-control" name="apAdminChannel" value="{{.ApAdminChannel}}">
|
||||
<option{{if eq .ApAdminChannel 1}} selected{{end}}>1</option>
|
||||
<option{{if eq .ApAdminChannel 6}} selected{{end}}>6</option>
|
||||
<option{{if eq .ApAdminChannel 11}} selected{{end}}>11</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-5 control-label">AP Admin WPA Key</label>
|
||||
<div class="col-lg-7">
|
||||
<input type="password" class="form-control" name="apAdminWpaKey" value="{{.ApAdminWpaKey}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-5 control-label">Switch Address</label>
|
||||
<div class="col-lg-7">
|
||||
|
||||
@@ -61,6 +61,9 @@ func (web *Web) settingsPostHandler(w http.ResponseWriter, r *http.Request) {
|
||||
eventSettings.ApAddress = r.PostFormValue("apAddress")
|
||||
eventSettings.ApUsername = r.PostFormValue("apUsername")
|
||||
eventSettings.ApPassword = r.PostFormValue("apPassword")
|
||||
eventSettings.ApTeamChannel, _ = strconv.Atoi(r.PostFormValue("apTeamChannel"))
|
||||
eventSettings.ApAdminChannel, _ = strconv.Atoi(r.PostFormValue("apAdminChannel"))
|
||||
eventSettings.ApAdminWpaKey = r.PostFormValue("apAdminWpaKey")
|
||||
eventSettings.SwitchAddress = r.PostFormValue("switchAddress")
|
||||
eventSettings.SwitchPassword = r.PostFormValue("switchPassword")
|
||||
eventSettings.BandwidthMonitoringEnabled = r.PostFormValue("bandwidthMonitoringEnabled") == "on"
|
||||
|
||||
Reference in New Issue
Block a user