mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-10 06:06:47 -04:00
Factor access point and switch out into their own 'network' package.
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/Team254/cheesy-arena/game"
|
||||
"github.com/Team254/cheesy-arena/led"
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
"github.com/Team254/cheesy-arena/network"
|
||||
"github.com/Team254/cheesy-arena/partner"
|
||||
"github.com/Team254/cheesy-arena/plc"
|
||||
"github.com/Team254/cheesy-arena/vaultled"
|
||||
@@ -44,8 +45,8 @@ const (
|
||||
type Arena struct {
|
||||
Database *model.Database
|
||||
EventSettings *model.EventSettings
|
||||
accessPoint *AccessPoint
|
||||
networkSwitch *NetworkSwitch
|
||||
accessPoint *network.AccessPoint
|
||||
networkSwitch *network.Switch
|
||||
Plc plc.Plc
|
||||
TbaClient *partner.TbaClient
|
||||
AllianceStations map[string]*AllianceStation
|
||||
@@ -142,9 +143,9 @@ 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 = network.NewAccessPoint(settings.ApAddress, settings.ApUsername, settings.ApPassword,
|
||||
settings.ApTeamChannel, settings.ApAdminChannel, settings.ApAdminWpaKey)
|
||||
arena.networkSwitch = NewNetworkSwitch(settings.SwitchAddress, settings.SwitchPassword)
|
||||
arena.networkSwitch = network.NewSwitch(settings.SwitchAddress, settings.SwitchPassword)
|
||||
arena.Plc.SetAddress(settings.PlcAddress)
|
||||
arena.TbaClient = partner.NewTbaClient(settings.TbaEventCode, settings.TbaSecretId, settings.TbaSecret)
|
||||
|
||||
|
||||
@@ -473,8 +473,10 @@ func TestSetupNetwork(t *testing.T) {
|
||||
|
||||
// Verify the setup ran by checking the log for the expected failure messages.
|
||||
arena.EventSettings.NetworkSecurityEnabled = true
|
||||
arena.accessPoint.port = 10022
|
||||
arena.networkSwitch.port = 10023
|
||||
arena.EventSettings.ApAddress = "invalid"
|
||||
arena.EventSettings.SwitchAddress = "invalid"
|
||||
arena.Database.SaveEventSettings(arena.EventSettings)
|
||||
arena.LoadSettings()
|
||||
arena.LoadMatch(&model.Match{Type: "test"})
|
||||
var writer bytes.Buffer
|
||||
log.SetOutput(&writer)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"github.com/Team254/cheesy-arena/game"
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
"github.com/Team254/cheesy-arena/network"
|
||||
"log"
|
||||
"net"
|
||||
"regexp"
|
||||
@@ -50,7 +51,6 @@ type DriverStationConnection struct {
|
||||
}
|
||||
|
||||
var allianceStationPositionMap = map[string]byte{"R1": 0, "R2": 1, "R3": 2, "B1": 3, "B2": 4, "B3": 5}
|
||||
var driverStationTcpListenAddress = "10.0.100.5" // The DS will try to connect to this address only.
|
||||
|
||||
// Opens a UDP connection for communicating to the driver station.
|
||||
func newDriverStationConnection(teamId int, allianceStation string, tcpConn net.Conn) (*DriverStationConnection, error) {
|
||||
@@ -271,10 +271,10 @@ func (dsConn *DriverStationConnection) decodeStatusPacket(data [36]byte) {
|
||||
|
||||
// Listens for TCP connection requests to Cheesy Arena from driver stations.
|
||||
func (arena *Arena) listenForDriverStations() {
|
||||
l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", driverStationTcpListenAddress, driverStationTcpListenPort))
|
||||
l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", network.ServerIpAddress, driverStationTcpListenPort))
|
||||
if err != nil {
|
||||
log.Printf("Error opening driver station TCP socket: %v", err.Error())
|
||||
log.Printf("Change IP address to %s and restart Cheesy Arena to fix.", driverStationTcpListenAddress)
|
||||
log.Printf("Change IP address to %s and restart Cheesy Arena to fix.", network.ServerIpAddress)
|
||||
return
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package field
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena/network"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net"
|
||||
"testing"
|
||||
@@ -162,11 +163,11 @@ func TestDecodeStatusPacket(t *testing.T) {
|
||||
func TestListenForDriverStations(t *testing.T) {
|
||||
arena := setupTestArena(t)
|
||||
|
||||
oldAddress := driverStationTcpListenAddress
|
||||
driverStationTcpListenAddress = "127.0.0.1"
|
||||
oldAddress := network.ServerIpAddress
|
||||
network.ServerIpAddress = "127.0.0.1"
|
||||
go arena.listenForDriverStations()
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
driverStationTcpListenAddress = oldAddress // Put it back to avoid affecting other tests.
|
||||
network.ServerIpAddress = oldAddress // Put it back to avoid affecting other tests.
|
||||
|
||||
// Connect with an invalid initial packet.
|
||||
tcpConn, err := net.Dial("tcp", "127.0.0.1:1750")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Methods for configuring a Linksys WRT1900ACS access point running OpenWRT for team SSIDs and VLANs.
|
||||
|
||||
package field
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -30,7 +30,8 @@ type AccessPoint struct {
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
func NewAccessPoint(address, username, password string, teamChannel, adminChannel int, adminWpaKey string) *AccessPoint {
|
||||
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}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2014 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package field
|
||||
package network
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Methods for configuring a Cisco Switch 3500-series switch for team VLANs.
|
||||
|
||||
package field
|
||||
package network
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
@@ -27,25 +27,27 @@ const (
|
||||
blue3Vlan = 60
|
||||
)
|
||||
|
||||
type NetworkSwitch struct {
|
||||
type Switch struct {
|
||||
address string
|
||||
port int
|
||||
password string
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
func NewNetworkSwitch(address, password string) *NetworkSwitch {
|
||||
return &NetworkSwitch{address: address, port: switchTelnetPort, password: password}
|
||||
var ServerIpAddress = "10.0.100.5" // The DS will try to connect to this address only.
|
||||
|
||||
func NewSwitch(address, password string) *Switch {
|
||||
return &Switch{address: address, port: switchTelnetPort, password: password}
|
||||
}
|
||||
|
||||
// Sets up wired networks for the given set of teams.
|
||||
func (ns *NetworkSwitch) ConfigureTeamEthernet(red1, red2, red3, blue1, blue2, blue3 *model.Team) error {
|
||||
func (sw *Switch) ConfigureTeamEthernet(red1, red2, red3, blue1, blue2, blue3 *model.Team) error {
|
||||
// Make sure multiple configurations aren't being set at the same time.
|
||||
ns.mutex.Lock()
|
||||
defer ns.mutex.Unlock()
|
||||
sw.mutex.Lock()
|
||||
defer sw.mutex.Unlock()
|
||||
|
||||
// Determine what new team VLANs are needed and build the commands to set them up.
|
||||
oldTeamVlans, err := ns.getTeamVlans()
|
||||
oldTeamVlans, err := sw.getTeamVlans()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -69,8 +71,8 @@ func (ns *NetworkSwitch) ConfigureTeamEthernet(red1, red2, red3, blue1, blue2, b
|
||||
"access-list 1%d permit udp any eq bootpc any eq bootps\n"+
|
||||
"interface Vlan%d\nip address 10.%d.%d.61 255.255.255.0\n",
|
||||
team.Id/100, team.Id%100, team.Id/100, team.Id%100, vlan, vlan, team.Id/100, team.Id%100, team.Id/100,
|
||||
team.Id%100, vlan, vlan, team.Id/100, team.Id%100, driverStationTcpListenAddress, vlan, vlan,
|
||||
team.Id/100, team.Id%100)
|
||||
team.Id%100, vlan, vlan, team.Id/100, team.Id%100, ServerIpAddress, vlan, vlan, team.Id/100,
|
||||
team.Id%100)
|
||||
}
|
||||
}
|
||||
replaceTeamVlan(red1, red1Vlan)
|
||||
@@ -89,7 +91,7 @@ func (ns *NetworkSwitch) ConfigureTeamEthernet(red1, red2, red3, blue1, blue2, b
|
||||
// Build and run the overall command to do everything in a single telnet session.
|
||||
command := removeTeamVlansCommand + addTeamVlansCommand
|
||||
if len(command) > 0 {
|
||||
_, err = ns.runConfigCommand(removeTeamVlansCommand + addTeamVlansCommand)
|
||||
_, err = sw.runConfigCommand(removeTeamVlansCommand + addTeamVlansCommand)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -99,9 +101,9 @@ func (ns *NetworkSwitch) ConfigureTeamEthernet(red1, red2, red3, blue1, blue2, b
|
||||
}
|
||||
|
||||
// Returns a map of currently-configured teams to VLANs.
|
||||
func (ns *NetworkSwitch) getTeamVlans() (map[int]int, error) {
|
||||
func (sw *Switch) getTeamVlans() (map[int]int, error) {
|
||||
// Get the entire config dump.
|
||||
config, err := ns.runCommand("show running-config\n")
|
||||
config, err := sw.runCommand("show running-config\n")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -128,9 +130,9 @@ func (ns *NetworkSwitch) getTeamVlans() (map[int]int, error) {
|
||||
|
||||
// Logs into the switch via Telnet and runs the given command in user exec mode. Reads the output and
|
||||
// returns it as a string.
|
||||
func (ns *NetworkSwitch) runCommand(command string) (string, error) {
|
||||
func (sw *Switch) runCommand(command string) (string, error) {
|
||||
// Open a Telnet connection to the switch.
|
||||
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", ns.address, ns.port))
|
||||
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", sw.address, sw.port))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -138,7 +140,7 @@ func (ns *NetworkSwitch) runCommand(command string) (string, error) {
|
||||
|
||||
// Login to the AP, send the command, and log out all at once.
|
||||
writer := bufio.NewWriter(conn)
|
||||
_, err = writer.WriteString(fmt.Sprintf("%s\nenable\n%s\nterminal length 0\n%sexit\n", ns.password, ns.password,
|
||||
_, err = writer.WriteString(fmt.Sprintf("%s\nenable\n%s\nterminal length 0\n%sexit\n", sw.password, sw.password,
|
||||
command))
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -159,6 +161,6 @@ func (ns *NetworkSwitch) runCommand(command string) (string, error) {
|
||||
|
||||
// Logs into the switch via Telnet and runs the given command in global configuration mode. Reads the output
|
||||
// and returns it as a string.
|
||||
func (ns *NetworkSwitch) runConfigCommand(command string) (string, error) {
|
||||
return ns.runCommand(fmt.Sprintf("config terminal\n%send\ncopy running-config startup-config\n\n", command))
|
||||
func (sw *Switch) runConfigCommand(command string) (string, error) {
|
||||
return sw.runCommand(fmt.Sprintf("config terminal\n%send\ncopy running-config startup-config\n\n", command))
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2014 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package field
|
||||
package network
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -14,27 +14,27 @@ import (
|
||||
)
|
||||
|
||||
func TestConfigureSwitch(t *testing.T) {
|
||||
ns := NewNetworkSwitch("127.0.0.1", "password")
|
||||
ns.port = 9050
|
||||
sw := NewSwitch("127.0.0.1", "password")
|
||||
sw.port = 9050
|
||||
var command string
|
||||
|
||||
// Should do nothing if current configuration is blank.
|
||||
mockTelnet(t, ns.port, "", &command)
|
||||
assert.Nil(t, ns.ConfigureTeamEthernet(nil, nil, nil, nil, nil, nil))
|
||||
mockTelnet(t, sw.port, "", &command)
|
||||
assert.Nil(t, sw.ConfigureTeamEthernet(nil, nil, nil, nil, nil, nil))
|
||||
assert.Equal(t, "", command)
|
||||
|
||||
// Should remove any existing teams but not other SSIDs.
|
||||
ns.port += 1
|
||||
mockTelnet(t, ns.port,
|
||||
sw.port += 1
|
||||
mockTelnet(t, sw.port,
|
||||
"interface Vlan100\nip address 10.0.100.2\ninterface Vlan50\nip address 10.2.54.61\n", &command)
|
||||
assert.Nil(t, ns.ConfigureTeamEthernet(nil, nil, nil, nil, nil, nil))
|
||||
assert.Nil(t, sw.ConfigureTeamEthernet(nil, nil, nil, nil, nil, nil))
|
||||
assert.Equal(t, "password\nenable\npassword\nterminal length 0\nconfig terminal\ninterface Vlan50\nno ip"+
|
||||
" address\nno access-list 150\nend\ncopy running-config startup-config\n\nexit\n", command)
|
||||
|
||||
// Should configure new teams and leave existing ones alone if still needed.
|
||||
ns.port += 1
|
||||
mockTelnet(t, ns.port, "interface Vlan50\nip address 10.2.54.61\n", &command)
|
||||
assert.Nil(t, ns.ConfigureTeamEthernet(nil, &model.Team{Id: 1114}, nil, nil, &model.Team{Id: 254}, nil))
|
||||
sw.port += 1
|
||||
mockTelnet(t, sw.port, "interface Vlan50\nip address 10.2.54.61\n", &command)
|
||||
assert.Nil(t, sw.ConfigureTeamEthernet(nil, &model.Team{Id: 1114}, nil, nil, &model.Team{Id: 254}, nil))
|
||||
assert.Equal(t, "password\nenable\npassword\nterminal length 0\nconfig terminal\n"+
|
||||
"ip dhcp excluded-address 10.11.14.1 10.11.14.100\nno ip dhcp pool dhcp20\nip dhcp pool dhcp20\n"+
|
||||
"network 10.11.14.0 255.255.255.0\ndefault-router 10.11.14.61\nlease 7\nno access-list 120\n"+
|
||||
Reference in New Issue
Block a user