Skip to content

Commit

Permalink
Add firmware version to the status API.
Browse files Browse the repository at this point in the history
  • Loading branch information
patfair committed Dec 29, 2023
1 parent 0b4c57e commit 7563507
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 4 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ $ curl http://10.0.100.2:8081/status
},
"red2": null,
"red3": null
}
},
"version": "1.2.3"
}
```
A null value for a team station indicates that no team is assigned.
Expand Down Expand Up @@ -135,7 +136,8 @@ $ curl http://10.12.34.1:8081/status
"ssid": "1234",
"hashedWpaKey": "d40e29b90743ddf71c75bfaedab1333e23bf43eb29f5c8c1ba55756e96e99d84",
"wpaKeySalt": "DzCKbEIu53vCmf0p",
"status": "ACTIVE"
"status": "ACTIVE",
"version": "1.2.3"
}
```
See the access point API documentation regarding the `hashedWpaKey` and `wpaKeySalt` fields.
Expand Down
4 changes: 4 additions & 0 deletions radio/radio_ap.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ type Radio struct {
// Map of team station names to their current status.
StationStatuses map[string]*StationStatus `json:"stationStatuses"`

// Version of the radio software.
Version string `json:"version"`

// Queue for receiving and buffering configuration requests.
ConfigurationRequestChannel chan ConfigurationRequest `json:"-"`

Expand All @@ -52,6 +55,7 @@ func NewRadio() *Radio {
log.Fatal("Unable to determine radio hardware type; exiting.")
}
log.Printf("Detected radio hardware type: %v", radio.Type)
radio.determineAndSetVersion()

// Initialize the device and station interface names that are dependent on the hardware type.
switch radio.Type {
Expand Down
8 changes: 7 additions & 1 deletion radio/radio_ap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func TestNewRadio(t *testing.T) {
func TestRadio_isStarted(t *testing.T) {
fakeShell := newFakeShell(t)
shell = fakeShell
fakeShell.commandOutput["sh -c source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION"] = ""
radio := NewRadio()

// Radio is not started.
Expand All @@ -96,6 +97,7 @@ func TestRadio_setInitialState(t *testing.T) {
fakeTree.valuesForGet["system.@system[0].model"] = "VH-109(AP)"
fakeShell := newFakeShell(t)
shell = fakeShell
fakeShell.commandOutput["cat /etc/config/vh_firmware"] = ""
radio := NewRadio()

fakeTree.valuesForGet["wireless.wifi1.channel"] = "23"
Expand All @@ -122,6 +124,7 @@ func TestRadio_handleConfigurationRequestVividHosting(t *testing.T) {
fakeShell := newFakeShell(t)
shell = fakeShell
wifiReloadBackoffDuration = 10 * time.Millisecond
fakeShell.commandOutput["cat /etc/config/vh_firmware"] = ""
radio := NewRadio()

fakeShell.commandOutput["wifi reload wifi1"] = ""
Expand Down Expand Up @@ -195,6 +198,7 @@ func TestRadio_handleConfigurationRequestLinksys(t *testing.T) {
fakeShell := newFakeShell(t)
shell = fakeShell
wifiReloadBackoffDuration = 100 * time.Millisecond
fakeShell.commandOutput["sh -c source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION"] = ""
radio := NewRadio()

fakeShell.commandOutput["wifi reload radio0"] = ""
Expand Down Expand Up @@ -293,6 +297,7 @@ func TestRadio_handleConfigurationRequestErrors(t *testing.T) {
shell = fakeShell
retryBackoffDuration = 10 * time.Millisecond
wifiReloadBackoffDuration = 10 * time.Millisecond
fakeShell.commandOutput["cat /etc/config/vh_firmware"] = ""
radio := NewRadio()

// wifi reload fails.
Expand Down Expand Up @@ -355,11 +360,12 @@ func TestRadio_handleConfigurationRequestErrors(t *testing.T) {
func TestRadio_updateStationMonitoring(t *testing.T) {
fakeShell := newFakeShell(t)
shell = fakeShell
fakeShell.commandOutput["sh -c source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION"] = ""
radio := NewRadio()

// No teams assigned.
radio.updateMonitoring()
assert.Empty(t, fakeShell.commandsRun)
assert.Equal(t, 1, len(fakeShell.commandsRun))

// Some teams assigned.
fakeShell.reset()
Expand Down
19 changes: 19 additions & 0 deletions radio/radio_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"log"
"math/rand"
"regexp"
"strings"
"time"
)

Expand Down Expand Up @@ -99,6 +100,24 @@ func TriggerFirmwareUpdate(firmwarePath string) {
log.Println("Started sysupgrade successfully.")
}

// determineAndSetVersion determines the firmware version of the radio.
func (radio *Radio) determineAndSetVersion() {
model, _ := uciTree.GetLast("system", "@system[0]", "model")
var version string
var err error
if strings.Contains(model, "VH") {
version, err = shell.runCommand("cat", "/etc/config/vh_firmware")
} else {
version, err = shell.runCommand("sh", "-c", "source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION")
}
if err != nil {
log.Printf("Error determining firmware version: %v", err)
radio.Version = "unknown"
} else {
radio.Version = strings.TrimSpace(version)
}
}

func (radio *Radio) handleConfigurationRequest(request ConfigurationRequest) error {
// If there are multiple requests queued up, only consider the latest one.
numExtraRequests := len(radio.ConfigurationRequestChannel)
Expand Down
40 changes: 40 additions & 0 deletions radio/radio_common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,43 @@ func TestTriggerFirmwareUpdate(t *testing.T) {
TriggerFirmwareUpdate("some-file")
assert.Contains(t, fakeShell.commandsRun, "sysupgrade -n some-file")
}

func TestRadio_determineAndSetVersion(t *testing.T) {
fakeTree := newFakeUciTree()
uciTree = fakeTree
fakeShell := newFakeShell(t)
shell = fakeShell

// Vivid-Hosting success case.
fakeTree.valuesForGet["system.@system[0].model"] = "VH-109(AP)"
fakeShell.commandOutput["cat /etc/config/vh_firmware"] = "\tVH version 1.2.3 \n"
radio := Radio{}
radio.determineAndSetVersion()
assert.Equal(t, "VH version 1.2.3", radio.Version)

// Vivid-Hosting error case.
fakeTree.reset()
fakeTree.valuesForGet["system.@system[0].model"] = "VH-109(AP)"
fakeShell.reset()
fakeShell.commandErrors["cat /etc/config/vh_firmware"] = errors.New("oops")
radio = Radio{}
radio.determineAndSetVersion()
assert.Equal(t, "unknown", radio.Version)

// Linksys success case.
fakeTree.reset()
fakeTree.valuesForGet["system.@system[0].model"] = ""
fakeShell.commandOutput["sh -c source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION"] = "\tLinksys v2.3.4 \n"
radio = Radio{}
radio.determineAndSetVersion()
assert.Equal(t, "Linksys v2.3.4", radio.Version)

// Linksys error case.
fakeTree.reset()
fakeTree.valuesForGet["system.@system[0].model"] = ""
fakeShell.reset()
fakeShell.commandErrors["sh -c source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION"] = errors.New("oops")
radio = Radio{}
radio.determineAndSetVersion()
assert.Equal(t, "unknown", radio.Version)
}
8 changes: 7 additions & 1 deletion radio/radio_robot.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ type Radio struct {
// Enum representing the current configuration stage of the radio.
Status radioStatus `json:"status"`

// Version of the radio software.
Version string `json:"version"`

// Queue for receiving and buffering configuration requests.
ConfigurationRequestChannel chan ConfigurationRequest `json:"-"`
}
Expand All @@ -66,10 +69,13 @@ const (

// NewRadio creates a new Radio instance and initializes its fields to default values.
func NewRadio() *Radio {
return &Radio{
radio := Radio{
Status: statusBooting,
ConfigurationRequestChannel: make(chan ConfigurationRequest, configurationRequestBufferSize),
}
radio.determineAndSetVersion()

return &radio
}

// isStarted returns true if the Wi-Fi interface is up and running.
Expand Down
6 changes: 6 additions & 0 deletions radio/radio_robot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func TestNewRadio(t *testing.T) {
func TestRadio_isStarted(t *testing.T) {
fakeShell := newFakeShell(t)
shell = fakeShell
fakeShell.commandOutput["sh -c source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION"] = ""
radio := NewRadio()

// Radio is not started.
Expand All @@ -40,6 +41,9 @@ func TestRadio_setInitialState(t *testing.T) {
rand.Seed(0)
fakeTree := newFakeUciTree()
uciTree = fakeTree
fakeShell := newFakeShell(t)
shell = fakeShell
fakeShell.commandOutput["sh -c source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION"] = ""
radio := NewRadio()

fakeTree.valuesForGet["wireless.@wifi-iface[0].ssid"] = "12345"
Expand Down Expand Up @@ -78,6 +82,7 @@ func TestRadio_handleConfigurationRequest(t *testing.T) {
fakeShell := newFakeShell(t)
shell = fakeShell
wifiReloadBackoffDuration = 10 * time.Millisecond
fakeShell.commandOutput["sh -c source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION"] = ""
radio := NewRadio()

// Configure to team radio mode.
Expand Down Expand Up @@ -166,6 +171,7 @@ func TestRadio_handleConfigurationRequestErrors(t *testing.T) {
shell = fakeShell
retryBackoffDuration = 10 * time.Millisecond
wifiReloadBackoffDuration = 10 * time.Millisecond
fakeShell.commandOutput["sh -c source /etc/openwrt_release && echo $DISTRIB_DESCRIPTION"] = ""
radio := NewRadio()

// wifi reload fails.
Expand Down

0 comments on commit 7563507

Please sign in to comment.