diff --git a/Makefile b/Makefile index 4ba546a..891a9ce 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +LINT_ARGS ?= ./... export GO111MODULE := on build: bin/server @@ -13,7 +14,7 @@ test: tidy go test -mod=vendor -v ./... lint: - @PATH=$(PATH):./bin/gometalinter gometalinter -e '.*/pkg/mod' -e ".*/go/src" --vendor $(LINT_ARGS) ./... + @golangci-lint run -e '.*/pkg/mod' -e ".*/go/src" --enable-all $(LINT_ARGS) tidy: go mod tidy @@ -24,8 +25,8 @@ vendor: tidy install-devtools: vendor # Install modd GO111MODULE=off go get -u github.com/cortesi/modd/cmd/modd - # Install Gometalinter - bash misc/gometalinter/install.sh -b ./bin/gometalinter + # Install golangci-lint + GO111MODULE=off go get -u github.com/golangci/golangci-lint/cmd/golangci-lint clean: rm -rf ./bin diff --git a/doc/prepa-dev.md b/doc/prepa-dev.md index 578699f..2ae7b91 100644 --- a/doc/prepa-dev.md +++ b/doc/prepa-dev.md @@ -15,4 +15,10 @@ 2. Lancer le serveur ```shell make watch + ``` + +3. (Optionnel mais recommandé) Installer le hook Git `pre-commit` + ```shell + rm -f .git/hooks/pre-commit.sample + ln -s "$PWD/misc/git-hooks/pre-commit" .git/hooks/pre-commit ``` \ No newline at end of file diff --git a/emlid/browser_connected.go b/emlid/browser_connected.go new file mode 100644 index 0000000..8f0182d --- /dev/null +++ b/emlid/browser_connected.go @@ -0,0 +1,17 @@ +package emlid + +const ( + // EventBrowserConnected is emitted after the initial connection to the + // ReachView endpoint + eventBrowserConnected = "browser connected" +) + +// sendBrowserConnected notifies the ReachView endpoint +// of a new connection. +// See misc/reachview/update_main.js line 297 +func (c *Client) sendBrowserConnected() error { + payload := map[string]string{ + "data": "I'm connected", + } + return c.Emit(eventBrowserConnected, payload) +} diff --git a/emlid/client.go b/emlid/client.go new file mode 100644 index 0000000..093d1b4 --- /dev/null +++ b/emlid/client.go @@ -0,0 +1,144 @@ +package emlid + +import ( + "sync" + + "forge.cadoles.com/Pyxis/golang-socketio" + "forge.cadoles.com/Pyxis/golang-socketio/transport" + "github.com/mitchellh/mapstructure" + "github.com/pkg/errors" +) + +// Client is a ReachRS websocket API client +type Client struct { + opts *Options + conn *gosocketio.Client +} + +// EventHandler is an event handler +type EventHandler func(data interface{}) + +// Connect connects the client to the ReachView endpoint +// This method is not safe to call by different coroutines +func (c *Client) Connect() error { + + var err error + var wg sync.WaitGroup + + wg.Add(1) + + transport := &transport.WebsocketTransport{ + PingInterval: c.opts.PingInterval, + PingTimeout: c.opts.PingTimeout, + ReceiveTimeout: c.opts.ReceiveTimeout, + SendTimeout: c.opts.SendTimeout, + BufferSize: c.opts.BufferSize, + } + + c.Logf("connecting to '%s'", c.opts.Endpoint) + conn, err := gosocketio.Dial(c.opts.Endpoint, transport) + if err != nil { + return errors.Wrap(err, "error while connecting to endpoint") + } + + c.conn = conn + + err = conn.On(gosocketio.OnConnection, func(h *gosocketio.Channel) { + conn.Off(gosocketio.OnError) + c.Logf("connected with sid '%s'", h.Id()) + err = c.sendBrowserConnected() + wg.Done() + }) + if err != nil { + return errors.Wrap(err, "error while attaching to connection event") + } + + err = conn.On(gosocketio.OnError, func(h *gosocketio.Channel) { + c.Logf("error") + err = errors.Errorf("an unknown error occured") + c.conn = nil + wg.Done() + }) + if err != nil { + return errors.Wrap(err, "error while attaching to error event") + } + + wg.Wait() + + return err +} + +// Close closes the current connection to the ReachView endpoint +func (c *Client) Close() { + if c.conn == nil { + return + } + c.conn.Close() + c.conn = nil +} + +// Emit a new event with the given data +func (c *Client) Emit(event string, data interface{}) error { + c.Logf("emit '%s' event", event) + if err := c.conn.Emit(event, data); err != nil { + return errors.Wrapf(err, "error while emitting '%s' event", event) + } + c.Logf("'%s' event sent", event) + return nil +} + +// On binds and event handler to the given event +func (c *Client) On(event string, handler interface{}) error { + return c.conn.On(event, handler) +} + +// Off remove the handler bound to the given event +func (c *Client) Off(event string) { + c.conn.Off(event) +} + +// ReqResp emits an event with the given data and waits for a response +func (c *Client) ReqResp(requestEvent string, requestData interface{}, responseEvent string, res interface{}) error { + + var err error + var wg sync.WaitGroup + + wg.Add(1) + + err = c.conn.On(responseEvent, func(_ *gosocketio.Channel, data interface{}) { + err = mapstructure.Decode(data, res) + c.conn.Off(responseEvent) + wg.Done() + }) + if err != nil { + return errors.Wrapf(err, "error while binding to '%s' event", responseEvent) + } + + if err := c.Emit(requestEvent, requestData); err != nil { + return errors.Wrapf(err, "error while emitting event '%s'", requestEvent) + } + + wg.Wait() + + return err + +} + +// Logf logs the given message with the configured logger +func (c *Client) Logf(format string, args ...interface{}) { + if c.opts.Logger == nil { + return + } + c.opts.Logger.Printf(format, args...) +} + +// NewClient returns a new ReachRS websocket client +func NewClient(opts ...OptionFunc) *Client { + options := DefaultOptions() + for _, o := range opts { + o(options) + } + return &Client{ + opts: options, + } +} diff --git a/reach/option.go b/emlid/option.go similarity index 99% rename from reach/option.go rename to emlid/option.go index 80a713c..bb3db33 100644 --- a/reach/option.go +++ b/emlid/option.go @@ -1,4 +1,4 @@ -package reach +package emlid import ( "log" diff --git a/reach/reach.go b/emlid/reach.go similarity index 56% rename from reach/reach.go rename to emlid/reach.go index 6a8aa41..e34172f 100644 --- a/reach/reach.go +++ b/emlid/reach.go @@ -1,4 +1,4 @@ -// Package reach is a package to configure EMLID ReachRS modules in Go. +// Package emlid is a package to configure EMLID ReachRS modules in Go. // // It aims to provide a simple interface to common ReachRS modules management operations. -package reach +package emlid diff --git a/emlid/reachview/client.go b/emlid/reachview/client.go new file mode 100644 index 0000000..62a56cc --- /dev/null +++ b/emlid/reachview/client.go @@ -0,0 +1,14 @@ +package reachview + +import "forge.cadoles.com/Pyxis/orion/emlid" + +// Client is a ReachRS Updater client +type Client struct { + *emlid.Client +} + +// NewClient returns a new ReachRS ReachView client +func NewClient(opts ...emlid.OptionFunc) *Client { + client := emlid.NewClient(opts...) + return &Client{client} +} diff --git a/emlid/reachview/configuration.go b/emlid/reachview/configuration.go new file mode 100644 index 0000000..eae57b8 --- /dev/null +++ b/emlid/reachview/configuration.go @@ -0,0 +1,15 @@ +package reachview + +const ( + eventGetConfiguration = "get configuration" + eventCurrentConfiguration = "current configuration" +) + +// Configuration fetches and return the current configuration of the ReachRS module +func (r *Client) Configuration() (*Configuration, error) { + configuration := &Configuration{} + if err := r.ReqResp(eventGetConfiguration, nil, eventCurrentConfiguration, configuration); err != nil { + return nil, err + } + return configuration, nil +} diff --git a/emlid/reachview/configuration_model.go b/emlid/reachview/configuration_model.go new file mode 100644 index 0000000..1fd72ca --- /dev/null +++ b/emlid/reachview/configuration_model.go @@ -0,0 +1,178 @@ +package reachview + +// Configuration - +type Configuration struct { + RTKSettings *RTKSettings `mapstructure:"rtk settings,omitempty"` + CorrectionInput *CorrectionInput `mapstructure:"correction input,omitempty"` + PositionOutput *PositionOutput `mapstructure:"position output,omitempty"` + BaseMode *BaseMode `mapstructure:"base mode,omitempty"` + Logging *Logging `mapstructure:"logging,omitempty"` + Bluetooth *Bluetooth `mapstructure:"bluetooth,omitempty"` + LoRa *LoRa `mapstructure:"lora,omitempty"` + Constraints *Constraints `mapstructure:"constraints,omitempty"` +} + +// RTKSettings - +type RTKSettings struct { + GLONASSARMode string `mapstructure:"glonass ar mode"` + UpdateRate string `mapstructure:"update rate"` + ElevationMaskAngle string `mapstructure:"elevation mask angle"` + MaxHorizontalAcceleration string `mapstructure:"max horizontal acceleration"` + SNRMask string `mapstructure:"snr mask"` + GPSARMode string `mapstructure:"gps ar mode"` + PositionningMode string `mapstructure:"positioning mode"` + PositioningSystems *PositionningSystems `mapstructure:"positioning systems,omitempty"` + MaxVerticalAcceleration string `mapstructure:"max vertical acceleration"` +} + +// PositionningSystems - +type PositionningSystems struct { + GLONASS bool `mapstructure:"glonass"` + SBAS bool `mapstructure:"sbas"` + QZS bool `mapstructure:"qzs"` + QZSS bool `mapstructure:"qzss"` + Compass bool `mapstructure:"compass"` + Galileo bool `mapstructure:"galileo"` + GPS bool `mapstructure:"gps"` +} + +// CorrectionInput - +type CorrectionInput struct { + Input2 *Input2 `mapstructure:"input2,omitempty"` + Input3 *Input3 `mapstructure:"input3,omitempty"` +} + +// Input - +type Input struct { + Path string `mapstructure:"path"` + Type string `mapstructure:"type"` + Enabled bool `mapstructure:"enabled"` + Format string `mapstructure:"format"` +} + +// Input2 - +type Input2 struct { + Input `mapstructure:",squash"` + SendPositionToBase string `mapstructure:"send position to base"` +} + +// Input3 - +type Input3 struct { + Input `mapstructure:",squash"` +} + +// PositionOutput - +type PositionOutput struct { + Output1 *Output `mapstructure:"output1,omitempty"` + Output2 *Output `mapstructure:"output2,omitempty"` + Output3 *Output `mapstructure:"output3,omitempty"` + Output4 *Output `mapstructure:"output4,omitempty"` +} + +// Output - +type Output struct { + Path string `mapstructure:"path"` + Type string `mapstructure:"type"` + Enabled bool `mapstructure:"enabled"` + Format string `mapstructure:"format"` +} + +// BaseMode - +type BaseMode struct { + Output *Output `mapstructure:"output,omitempty"` + BaseCoordinates *BaseCoordinates `mapstructure:"base coordinates,omitempty"` + RTCM3Messages *RTCM3Messages `mapstructure:"rtcm3 messages,omitempty"` +} + +// BaseCoordinates - +type BaseCoordinates struct { + Format string `mapstructure:"format"` + AntennaOffset *AntennaOffset `mapstructure:"antenna offset,omitempty"` + Accumulation string `mapstructure:"accumulation"` + Coordinates []string `mapstructure:"coordinates"` + Mode string `mapstructure:"mode"` +} + +// AntennaOffset - +type AntennaOffset struct { + East string `mapstructure:"east"` + North string `mapstructure:"north"` + Up string `mapstructure:"up"` +} + +// RTCM3Messages - +type RTCM3Messages struct { + // GPS L1 code and phase and ambiguities and carrier-to-noise ratio + Type1002 *RTCMMessageType `mapstructure:"1002,omitemtpy"` + // Station coordinates XYZ for antenna reference point and antenna height. + Type1006 *RTCMMessageType `mapstructure:"1006,omitemtpy"` + // Antenna serial number. + Type1008 *RTCMMessageType `mapstructure:"1008,omitemtpy"` + // GLONASS L1 code and phase and ambiguities and carrier-to-noise ratio. + Type1010 *RTCMMessageType `mapstructure:"1010,omitemtpy"` + // GPS ephemeris. + Type1019 *RTCMMessageType `mapstructure:"1019,omitemtpy"` + // GLONASS ephemeris. + Type1020 *RTCMMessageType `mapstructure:"1020,omitemtpy"` + // The type 7 Multiple Signal Message format for Europe’s Galileo system + Type1097 *RTCMMessageType `mapstructure:"1097,omitemtpy"` + // Full SBAS pseudo-ranges, carrier phases, Doppler and signal strength (high resolution) + Type1107 *RTCMMessageType `mapstructure:"1107,omitemtpy"` + // Full QZSS pseudo-ranges, carrier phases, Doppler and signal strength (high resolution) + Type1117 *RTCMMessageType `mapstructure:"1117,omitemtpy"` + // Full BeiDou pseudo-ranges, carrier phases, Doppler and signal strength (high resolution) + Type1127 *RTCMMessageType `mapstructure:"1127,omitemtpy"` +} + +// RTCMMessageType - +type RTCMMessageType struct { + Frequency string `mapstructure:"frequency"` + Enabled bool `mapstructure:"enabled"` +} + +// Logging - +type Logging struct { + Correction *LoggingService `mapstructure:"correction,omitempty"` + Interval int `mapstructure:"interval"` + Solution *LoggingService `mapstructure:"solution,omitempty"` + Raw *LoggingService `mapstructure:"raw,omitempty"` + Base *LoggingService `mapstructure:"base,omitempty"` + Overwrite bool `mapstructure:"overwrite"` +} + +// LoggingService - +type LoggingService struct { + Started bool `mapstructure:"started"` + Version string `mapstructure:"version"` + Format string `mapstructure:"format"` +} + +// Bluetooth - +type Bluetooth struct { + Enabled bool `mapstructure:"enabled"` + Discoverable bool `mapstructure:"discoverable"` + Pin int `mapstructure:"pin"` +} + +// LoRa - +type LoRa struct { + AirRate float64 `mapstructure:"air rate"` + Frequency int `mapstructure:"frequency"` + OutputPower int `mapstructure:"output power"` +} + +// Constraints - +type Constraints struct { + LoRa *LoRaConstraints `mapstructure:"lora,omitempty"` +} + +// LoRaConstraints - +type LoRaConstraints struct { + Frequency *LoRaFrequencyRange `mapstructure:"frequency,omitempty"` +} + +// LoRaFrequencyRange - +type LoRaFrequencyRange struct { + Min int `mapstructure:"min"` + Max int `mapstructure:"max"` +} diff --git a/emlid/reachview/configuration_test.go b/emlid/reachview/configuration_test.go new file mode 100644 index 0000000..bea31dd --- /dev/null +++ b/emlid/reachview/configuration_test.go @@ -0,0 +1,41 @@ +package reachview + +import ( + "testing" + + "forge.cadoles.com/Pyxis/orion/emlid" + "github.com/davecgh/go-spew/spew" +) + +func TestReachViewConfiguration(t *testing.T) { + + if !*runReachViewIntegrationTests { + t.Skip("To run this test, use: go test -reachview-integration") + } + + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), + ) + if err := client.Connect(); err != nil { + t.Fatal(err) + } + + config, err := client.Configuration() + if err != nil { + t.Error(err) + } + + if config == nil { + t.Fatal("config should not be nil") + } + + if config.RTKSettings == nil { + t.Fatal("config.RTKSettings should not be nil") + } + + spew.Dump(config) + + defer client.Close() + +} diff --git a/emlid/reachview/test.go b/emlid/reachview/test.go new file mode 100644 index 0000000..1dfa823 --- /dev/null +++ b/emlid/reachview/test.go @@ -0,0 +1,13 @@ +package reachview + +import "flag" + +var runReachViewIntegrationTests = flag.Bool( + "reachview-integration", false, + "Run the 'ReachView' integration tests (in addition to the unit tests)", +) + +var reachHost = flag.String( + "reach-host", "192.168.42.1", + "The Reach module host to use in integration tests", +) diff --git a/emlid/updater/client.go b/emlid/updater/client.go new file mode 100644 index 0000000..1f0397f --- /dev/null +++ b/emlid/updater/client.go @@ -0,0 +1,15 @@ +// Package updater provides an API to communicate with the ReachRS modules "Updater" application +package updater + +import "forge.cadoles.com/Pyxis/orion/emlid" + +// Client is a ReachRS Updater client +type Client struct { + *emlid.Client +} + +// NewClient returns a new ReachRS Updater client +func NewClient(opts ...emlid.OptionFunc) *Client { + client := emlid.NewClient(opts...) + return &Client{client} +} diff --git a/reach/example_test.go b/emlid/updater/example_test.go similarity index 60% rename from reach/example_test.go rename to emlid/updater/example_test.go index 2a11c08..4e4f1e9 100644 --- a/reach/example_test.go +++ b/emlid/updater/example_test.go @@ -1,13 +1,15 @@ -package reach +package updater -import "log" +import ( + "log" -// ReachRS modules provides an Updater application when reset in factory mode. -// This package provides an API to communicate with this application. -func Example_updaterClientUsage() { + "forge.cadoles.com/Pyxis/orion/emlid" +) + +func Example_usage() { // Create a new Updater client instance - updater := NewUpdaterClient( - WithEndpoint("192.168.42.1", 80), // Define the module endpoint + updater := NewClient( + emlid.WithEndpoint("192.168.42.1", 80), // Define the module endpoint ) // Connect to the ReachRS Updater endpoint diff --git a/emlid/updater/reachview_version.go b/emlid/updater/reachview_version.go new file mode 100644 index 0000000..c0640d8 --- /dev/null +++ b/emlid/updater/reachview_version.go @@ -0,0 +1,19 @@ +package updater + +const ( + eventGetReachViewVersion = "get reachview version" + eventReachViewVersionResults = "current reachview version" +) + +type reachViewVersion struct { + Version string `json:"version"` +} + +// ReachViewVersion returns the ReachRS module ReachView version +func (c *Client) ReachViewVersion() (string, error) { + res := &reachViewVersion{} + if err := c.ReqResp(eventGetReachViewVersion, nil, eventReachViewVersionResults, res); err != nil { + return "", err + } + return res.Version, nil +} diff --git a/reach/reachview_version_test.go b/emlid/updater/reachview_version_test.go similarity index 73% rename from reach/reachview_version_test.go rename to emlid/updater/reachview_version_test.go index 7dba9a8..9ae46a4 100644 --- a/reach/reachview_version_test.go +++ b/emlid/updater/reachview_version_test.go @@ -1,7 +1,9 @@ -package reach +package updater import ( "testing" + + "forge.cadoles.com/Pyxis/orion/emlid" ) func TestClientReachViewVersion(t *testing.T) { @@ -10,9 +12,9 @@ func TestClientReachViewVersion(t *testing.T) { t.Skip("To run this test, use: go test -updater-integration") } - client := NewUpdaterClient( - WithStandardLogger(), - WithEndpoint(*reachHost, 80), + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), ) if err := client.Connect(); err != nil { t.Fatal(err) diff --git a/reach/reboot_now.go b/emlid/updater/reboot_now.go similarity index 52% rename from reach/reboot_now.go rename to emlid/updater/reboot_now.go index 18eaaf9..3003c53 100644 --- a/reach/reboot_now.go +++ b/emlid/updater/reboot_now.go @@ -1,4 +1,4 @@ -package reach +package updater import ( "sync" @@ -12,15 +12,15 @@ const ( ) // RebootNow asks the ReachRS module to reboot now -func (u *Updater) RebootNow(waitDisconnect bool) error { +func (c *Client) RebootNow(waitDisconnect bool) error { var err error var wg sync.WaitGroup if waitDisconnect { wg.Add(1) - err = u.conn.On(gosocketio.OnDisconnection, func(h *gosocketio.Channel) { - u.conn.Off(gosocketio.OnDisconnection) + err = c.On(gosocketio.OnDisconnection, func(h *gosocketio.Channel) { + c.Off(gosocketio.OnDisconnection) wg.Done() }) if err != nil { @@ -28,11 +28,9 @@ func (u *Updater) RebootNow(waitDisconnect bool) error { } } - u.logf("sending '%s' event", eventReboot) - if err = u.conn.Emit(eventReboot, nil); err != nil { - return errors.Wrapf(err, "error while emitting '%s' event", eventReboot) + if err = c.Emit(eventReboot, nil); err != nil { + return err } - u.logf("'%s' event sent", eventReboot) if waitDisconnect { wg.Wait() diff --git a/reach/reboot_now_test.go b/emlid/updater/reboot_now_test.go similarity index 50% rename from reach/reboot_now_test.go rename to emlid/updater/reboot_now_test.go index 21bac03..d3a531a 100644 --- a/reach/reboot_now_test.go +++ b/emlid/updater/reboot_now_test.go @@ -1,18 +1,24 @@ -package reach +package updater import ( "testing" + + "forge.cadoles.com/Pyxis/orion/emlid" ) -func TestClientReboutNow(t *testing.T) { +func TestClientRebootNow(t *testing.T) { if !*runUpdaterIntegrationTests { t.Skip("To run this test, use: go test -updater-integration") } - client := NewUpdaterClient( - WithStandardLogger(), - WithEndpoint(*reachHost, 80), + if !*runRebootTest { + t.Skip("To run this test, use: go test -updater-reboot-test") + } + + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), ) if err := client.Connect(); err != nil { t.Fatal(err) diff --git a/emlid/updater/receiver_upgrade.go b/emlid/updater/receiver_upgrade.go new file mode 100644 index 0000000..6ceba52 --- /dev/null +++ b/emlid/updater/receiver_upgrade.go @@ -0,0 +1,21 @@ +package updater + +const ( + eventIsReceiverUpgradeAvailable = "is receiver upgrade available" + eventReceiverUpgradeAvailable = "receiver upgrade available" +) + +type receiverUpgreAvailable struct { + Available bool `json:"available"` + Running bool `json:"running"` +} + +// ReceiverUpgradeAvailable checks if an upgrade is avaialable/running for the ReachRS module +func (c *Client) ReceiverUpgradeAvailable() (bool, bool, error) { + res := &receiverUpgreAvailable{} + if err := c.ReqResp(eventIsReceiverUpgradeAvailable, nil, eventReceiverUpgradeAvailable, res); err != nil { + return false, false, err + } + c.Logf("receiver upgrade result: available: %v, running: %v", res.Available, res.Running) + return res.Available, res.Running, nil +} diff --git a/reach/receiver_upgrade_test.go b/emlid/updater/receiver_upgrade_test.go similarity index 70% rename from reach/receiver_upgrade_test.go rename to emlid/updater/receiver_upgrade_test.go index a4358d2..65913bd 100644 --- a/reach/receiver_upgrade_test.go +++ b/emlid/updater/receiver_upgrade_test.go @@ -1,7 +1,9 @@ -package reach +package updater import ( "testing" + + "forge.cadoles.com/Pyxis/orion/emlid" ) func TestClientReceiverUpgradeAvailable(t *testing.T) { @@ -10,9 +12,9 @@ func TestClientReceiverUpgradeAvailable(t *testing.T) { t.Skip("To run this test, use: go test -updater-integration") } - client := NewUpdaterClient( - WithStandardLogger(), - WithEndpoint(*reachHost, 80), + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), ) if err := client.Connect(); err != nil { t.Fatal(err) diff --git a/emlid/updater/test.go b/emlid/updater/test.go new file mode 100644 index 0000000..a4e27b0 --- /dev/null +++ b/emlid/updater/test.go @@ -0,0 +1,23 @@ +package updater + +import "flag" + +var runUpdaterIntegrationTests = flag.Bool( + "updater-integration", false, + "Run the 'Updater' integration tests (in addition to the unit tests)", +) + +var runRebootTest = flag.Bool( + "updater-reboot-test", false, + "Run the updater 'Reboot' test (in addition to the unit tests)", +) + +var runJoinNetworkTest = flag.Bool( + "updater-join-network-test", false, + "Run the updater 'JoinWiFiNetwork' test (in addition to the unit tests)", +) + +var reachHost = flag.String( + "reach-host", "192.168.42.1", + "The Reach module host to use in integration tests", +) diff --git a/emlid/updater/test_results.go b/emlid/updater/test_results.go new file mode 100644 index 0000000..e5342ff --- /dev/null +++ b/emlid/updater/test_results.go @@ -0,0 +1,25 @@ +package updater + +const ( + eventGetTestResults = "get test results" + eventTestResults = "test results" +) + +// TestResults are the ReachRS module's test results +// +type TestResults struct { + Device string `json:"device"` + Lora bool `json:"lora"` + MPU bool `json:"mpu"` + STC bool `json:"stc"` + UBlox bool `json:"u-blox"` +} + +// TestResults returns the ReachRS module tests results +func (c *Client) TestResults() (*TestResults, error) { + res := &TestResults{} + if err := c.ReqResp(eventGetTestResults, nil, eventTestResults, res); err != nil { + return nil, err + } + return res, nil +} diff --git a/reach/test_results_test.go b/emlid/updater/test_results_test.go similarity index 75% rename from reach/test_results_test.go rename to emlid/updater/test_results_test.go index b8691bb..57bf5a3 100644 --- a/reach/test_results_test.go +++ b/emlid/updater/test_results_test.go @@ -1,7 +1,9 @@ -package reach +package updater import ( "testing" + + "forge.cadoles.com/Pyxis/orion/emlid" ) func TestClientTestResults(t *testing.T) { @@ -10,9 +12,9 @@ func TestClientTestResults(t *testing.T) { t.Skip("To run this test, use: go test -updater-integration") } - client := NewUpdaterClient( - WithStandardLogger(), - WithEndpoint(*reachHost, 80), + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), ) if err := client.Connect(); err != nil { t.Fatal(err) diff --git a/emlid/updater/time_sync.go b/emlid/updater/time_sync.go new file mode 100644 index 0000000..afaefd2 --- /dev/null +++ b/emlid/updater/time_sync.go @@ -0,0 +1,21 @@ +package updater + +const ( + eventGetTimeSyncStatus = "get time sync status" + eventTimeSyncResults = "time sync status" +) + +type timeSyncStatus struct { + Status bool `json:"status"` +} + +// TimeSynced returns the ReachRS module time synchronization status. +// A true response means that the module has synchronized its clock. +func (c *Client) TimeSynced() (bool, error) { + res := &timeSyncStatus{} + if err := c.ReqResp(eventGetTimeSyncStatus, nil, eventTimeSyncResults, res); err != nil { + return false, err + } + c.Logf("time sync result: %v", res.Status) + return res.Status, nil +} diff --git a/reach/time_sync_test.go b/emlid/updater/time_sync_test.go similarity index 68% rename from reach/time_sync_test.go rename to emlid/updater/time_sync_test.go index af81b70..c625425 100644 --- a/reach/time_sync_test.go +++ b/emlid/updater/time_sync_test.go @@ -1,7 +1,9 @@ -package reach +package updater import ( "testing" + + "forge.cadoles.com/Pyxis/orion/emlid" ) func TestClientTimeSync(t *testing.T) { @@ -10,9 +12,9 @@ func TestClientTimeSync(t *testing.T) { t.Skip("To run this test, use: go test -updater-integration") } - client := NewUpdaterClient( - WithStandardLogger(), - WithEndpoint(*reachHost, 80), + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), ) if err := client.Connect(); err != nil { t.Fatal(err) diff --git a/emlid/updater/update.go b/emlid/updater/update.go new file mode 100644 index 0000000..3fc5b44 --- /dev/null +++ b/emlid/updater/update.go @@ -0,0 +1,26 @@ +package updater + +const ( + eventUpdate = "update" + eventOPKGUpdateResult = "opkg update result" +) + +// UpdateStatus embeds informations about update status +type UpdateStatus struct { + Active bool `json:"active"` + Locked bool `json:"locked"` + State string `json:"state"` +} + +// Update asks the ReachRS module to start an OPKG update +func (c *Client) Update() (*UpdateStatus, error) { + res := &UpdateStatus{} + if err := c.ReqResp(eventUpdate, nil, eventOPKGUpdateResult, res); err != nil { + return nil, err + } + c.Logf( + "opkg update result: active: %v, state: %v, locked: %v", + res.Active, res.State, res.Locked, + ) + return res, nil +} diff --git a/reach/update_test.go b/emlid/updater/update_test.go similarity index 68% rename from reach/update_test.go rename to emlid/updater/update_test.go index 87161e4..39aa897 100644 --- a/reach/update_test.go +++ b/emlid/updater/update_test.go @@ -1,7 +1,9 @@ -package reach +package updater import ( "testing" + + "forge.cadoles.com/Pyxis/orion/emlid" ) func TestClientOPKGUpdate(t *testing.T) { @@ -10,9 +12,9 @@ func TestClientOPKGUpdate(t *testing.T) { t.Skip("To run this test, use: go test -updater-integration") } - client := NewUpdaterClient( - WithStandardLogger(), - WithEndpoint(*reachHost, 80), + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), ) if err := client.Connect(); err != nil { t.Fatal(err) diff --git a/emlid/updater/wifi_networks.go b/emlid/updater/wifi_networks.go new file mode 100644 index 0000000..dbc6326 --- /dev/null +++ b/emlid/updater/wifi_networks.go @@ -0,0 +1,101 @@ +package updater + +import ( + "sync" + + "forge.cadoles.com/Pyxis/golang-socketio" + "github.com/pkg/errors" +) + +const ( + eventGetSavedWifiNetworks = "get saved wifi networks" + eventSavedWifiNetworkResults = "wifi saved networks results" + eventAddWifiNetwork = "add new network" + eventAddWifiNetworkResults = "add network results" + eventRemoveWifiNetwork = "remove network" + eventRemoveWifiNetworkResults = "remove network results" + eventConnectToNetwork = "connect to network" +) + +// WifiSecurity is a WiFi network security algorithm +type WifiSecurity string + +const ( + // SecurityWEP WEP wifi network + SecurityWEP WifiSecurity = "wep" + // SecurityWPAPSK WPA(2)-PSK wifi network + SecurityWPAPSK WifiSecurity = "wpa-psk" + // SecurityOpen Open wifi network + SecurityOpen WifiSecurity = "open" +) + +// WifiNetwork is a ReachRS module wifi network +type WifiNetwork struct { + SSID string `json:"ssid"` + Password string `json:"password"` + Security WifiSecurity `json:"security"` + Identity string `json:"identity"` + Visible bool `json:"is_visible"` + Connected bool `json:"is_connected"` + Added bool `json:"is_added"` +} + +// WifiNetworks returns the ReachRS module wifi networks +func (c *Client) WifiNetworks() ([]WifiNetwork, error) { + res := make([]WifiNetwork, 0) + if err := c.ReqResp(eventGetSavedWifiNetworks, nil, eventSavedWifiNetworkResults, &res); err != nil { + return nil, err + } + return res, nil +} + +// AddWifiNetwork asks the ReachRS module to save the given wifi network informations +func (c *Client) AddWifiNetwork(ssid string, security WifiSecurity, password string) (bool, error) { + res := false + network := &WifiNetwork{ + SSID: ssid, + Security: security, + Password: password, + } + if err := c.ReqResp(eventAddWifiNetwork, network, eventAddWifiNetworkResults, &res); err != nil { + return false, err + } + return res, nil +} + +// RemoveWifiNetwork asks the ReachRS module to remove the given WiFi network +func (c *Client) RemoveWifiNetwork(ssid string) (bool, error) { + res := false + if err := c.ReqResp(eventRemoveWifiNetwork, ssid, eventRemoveWifiNetworkResults, &res); err != nil { + return false, err + } + return res, nil +} + +// JoinWifiNetwork asks the ReachRS module to join the given WiFi network +func (c *Client) JoinWifiNetwork(ssid string, waitDisconnect bool) error { + + var err error + var wg sync.WaitGroup + + if waitDisconnect { + wg.Add(1) + err = c.On(gosocketio.OnDisconnection, func(h *gosocketio.Channel) { + c.Off(gosocketio.OnDisconnection) + wg.Done() + }) + if err != nil { + return errors.Wrapf(err, "error while binding to '%s' event", gosocketio.OnDisconnection) + } + } + + if err := c.Emit(eventConnectToNetwork, ssid); err != nil { + return errors.Wrapf(err, "error while emitting '%s' event", eventConnectToNetwork) + } + + if waitDisconnect { + wg.Wait() + } + + return nil +} diff --git a/reach/wifi_networks_test.go b/emlid/updater/wifi_networks_test.go similarity index 81% rename from reach/wifi_networks_test.go rename to emlid/updater/wifi_networks_test.go index 06ca838..134552e 100644 --- a/reach/wifi_networks_test.go +++ b/emlid/updater/wifi_networks_test.go @@ -1,10 +1,12 @@ -package reach +package updater import ( "fmt" "math/rand" "testing" "time" + + "forge.cadoles.com/Pyxis/orion/emlid" ) func TestClientSavedWiFiNetworks(t *testing.T) { @@ -13,9 +15,9 @@ func TestClientSavedWiFiNetworks(t *testing.T) { t.Skip("To run this test, use: go test -updater-integration") } - client := NewUpdaterClient( - WithStandardLogger(), - WithEndpoint(*reachHost, 80), + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), ) if err := client.Connect(); err != nil { t.Fatal(err) @@ -36,9 +38,9 @@ func TestClientCRUDWiFiNetwork(t *testing.T) { t.Skip("To run this test, use: go test -updater-integration") } - client := NewUpdaterClient( - WithStandardLogger(), - WithEndpoint(*reachHost, 80), + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), ) if err := client.Connect(); err != nil { t.Fatal(err) @@ -91,9 +93,13 @@ func TestClientWifiNetworkJoin(t *testing.T) { t.Skip("To run this test, use: go test -updater-integration") } - client := NewUpdaterClient( - WithStandardLogger(), - WithEndpoint(*reachHost, 80), + if !*runJoinNetworkTest { + t.Skip("To run this test, use: go test -updater-join-network-test") + } + + client := NewClient( + emlid.WithStandardLogger(), + emlid.WithEndpoint(*reachHost, 80), ) if err := client.Connect(); err != nil { t.Fatal(err) diff --git a/example/updater/main.go b/example/updater/main.go index 54d685a..94c5600 100644 --- a/example/updater/main.go +++ b/example/updater/main.go @@ -6,7 +6,8 @@ import ( "log" "strings" - "forge.cadoles.com/Pyxis/orion/reach" + "forge.cadoles.com/Pyxis/orion/emlid" + "forge.cadoles.com/Pyxis/orion/emlid/updater" ) const ( @@ -18,7 +19,7 @@ var ( phase = phaseConfigureWifi host = "192.168.42.1" ssid = "" - security = string(reach.SecurityWPAPSK) + security = string(updater.SecurityWPAPSK) password = "" ) @@ -51,20 +52,20 @@ func main() { } -func connect() *reach.Updater { +func connect() *updater.Client { - updater := reach.NewUpdaterClient( - reach.WithEndpoint(host, 80), + c := updater.NewClient( + emlid.WithEndpoint(host, 80), ) log.Printf("connecting to module '%s'", host) - if err := updater.Connect(); err != nil { + if err := c.Connect(); err != nil { log.Fatal(err) } log.Println("connected") - return updater + return c } @@ -74,11 +75,11 @@ func configureWifi() { log.Fatal("you must provide a WiFi SSID with the -ssid flag") } - updater := connect() - defer updater.Close() + c := connect() + defer c.Close() log.Println("checking module status") - results, err := updater.TestResults() + results, err := c.TestResults() if err != nil { log.Fatal(err) } @@ -91,7 +92,7 @@ func configureWifi() { log.Printf("adding wifi network '%s'", ssid) - done, err := updater.AddWifiNetwork(ssid, reach.WifiSecurity(security), password) + done, err := c.AddWifiNetwork(ssid, updater.WifiSecurity(security), password) if err != nil { log.Fatal(err) } @@ -101,7 +102,7 @@ func configureWifi() { } log.Println("connecting module to wifi network") - if err := updater.JoinWifiNetwork(ssid, true); err != nil { + if err := c.JoinWifiNetwork(ssid, true); err != nil { log.Fatal(err) } log.Printf("you can now switch to the wifi network and start phase '%s'", phaseUpdateThenReboot) @@ -109,25 +110,26 @@ func configureWifi() { } func updateThenReboot() { - updater := connect() - defer updater.Close() + + c := connect() + defer c.Close() log.Println("checking time sync") - synced, err := updater.TimeSynced() + synced, err := c.TimeSynced() if err != nil { log.Fatal(err) } log.Printf("time synced ? %v", synced) log.Println("checking reachview version") - version, err := updater.ReachViewVersion() + version, err := c.ReachViewVersion() if err != nil { log.Fatal(err) } log.Printf("reachview version ? '%s'", version) log.Println("checking for update") - status, err := updater.Update() + status, err := c.Update() if err != nil { log.Fatal(err) } @@ -141,7 +143,7 @@ func updateThenReboot() { } log.Println("rebooting device") - if err := updater.RebootNow(true); err != nil { + if err := c.RebootNow(true); err != nil { log.Fatal(err) } diff --git a/go.mod b/go.mod index 08eb7a8..066ee89 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-chi/chi v3.3.3+incompatible github.com/gorilla/websocket v1.4.0 // indirect + github.com/mitchellh/mapstructure v1.0.0 github.com/pkg/errors v0.8.0 github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.2.2 // indirect diff --git a/go.sum b/go.sum index 4749ce9..eb81ba4 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/go-chi/chi v3.3.3+incompatible h1:KHkmBEMNkwKuK4FdQL7N2wOeB9jnIx7jR5w github.com/go-chi/chi v3.3.3+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I= +github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/misc/git-hooks/pre-commit b/misc/git-hooks/pre-commit new file mode 100755 index 0000000..97f1d92 --- /dev/null +++ b/misc/git-hooks/pre-commit @@ -0,0 +1,17 @@ +#!/bin/bash + +set -eo pipefail + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +CHANGESET=$(git diff --cached --name-only --diff-filter=ACM) + +function lint_go_files { + echo "Linting modified Go files..." + ( cd "$DIR/../.." && make LINT_ARGS="--new-from-rev=HEAD~ ./..." lint ) +} + +function main { + lint_go_files +} + +main \ No newline at end of file diff --git a/reach/browser_connected.go b/reach/browser_connected.go deleted file mode 100644 index a773d5b..0000000 --- a/reach/browser_connected.go +++ /dev/null @@ -1,26 +0,0 @@ -package reach - -import ( - "github.com/pkg/errors" -) - -const ( - // EventBrowserConnected is emitted after the initial connection to the - // ReachView endpoint - eventBrowserConnected = "browser connected" -) - -// sendBrowserConnected notifies the ReachView endpoint -// of a new connection. -// See misc/reachview/update_main.js line 297 -func (c *client) sendBrowserConnected() error { - payload := map[string]string{ - "data": "I'm connected", - } - c.logf("sending '%s' event", eventBrowserConnected) - if err := c.conn.Emit(eventBrowserConnected, payload); err != nil { - return errors.Wrapf(err, "error while emitting '%s' event", eventBrowserConnected) - } - c.logf("'%s' event sent", eventBrowserConnected) - return nil -} diff --git a/reach/client.go b/reach/client.go deleted file mode 100644 index eef832f..0000000 --- a/reach/client.go +++ /dev/null @@ -1,90 +0,0 @@ -package reach - -import ( - "sync" - - "forge.cadoles.com/Pyxis/golang-socketio" - "forge.cadoles.com/Pyxis/golang-socketio/transport" - "github.com/pkg/errors" -) - -type client struct { - opts *Options - conn *gosocketio.Client -} - -// Connect connects the client to the ReachView endpoint -// This method is not safe to call by different coroutines -func (c *client) Connect() error { - - var err error - var wg sync.WaitGroup - - wg.Add(1) - - transport := &transport.WebsocketTransport{ - PingInterval: c.opts.PingInterval, - PingTimeout: c.opts.PingTimeout, - ReceiveTimeout: c.opts.ReceiveTimeout, - SendTimeout: c.opts.SendTimeout, - BufferSize: c.opts.BufferSize, - } - - c.logf("connecting to '%s'", c.opts.Endpoint) - conn, err := gosocketio.Dial(c.opts.Endpoint, transport) - if err != nil { - return errors.Wrap(err, "error while connecting to endpoint") - } - - c.conn = conn - - err = conn.On(gosocketio.OnConnection, func(h *gosocketio.Channel) { - conn.Off(gosocketio.OnError) - c.logf("connected with sid '%s'", h.Id()) - err = c.sendBrowserConnected() - wg.Done() - }) - if err != nil { - return errors.Wrap(err, "error while attaching to connection event") - } - - err = conn.On(gosocketio.OnError, func(h *gosocketio.Channel) { - c.logf("error") - err = errors.Errorf("an unknown error occured") - c.conn = nil - wg.Done() - }) - if err != nil { - return errors.Wrap(err, "error while attaching to error event") - } - - wg.Wait() - - return err -} - -// Close closes the current connection to the ReachView endpoint -func (c *client) Close() { - if c.conn == nil { - return - } - c.conn.Close() - c.conn = nil -} - -func (c *client) logf(format string, args ...interface{}) { - if c.opts.Logger == nil { - return - } - c.opts.Logger.Printf(format, args...) -} - -func newClient(opts ...OptionFunc) *client { - options := DefaultOptions() - for _, o := range opts { - o(options) - } - return &client{ - opts: options, - } -} diff --git a/reach/reachview_version.go b/reach/reachview_version.go deleted file mode 100644 index db9b8c6..0000000 --- a/reach/reachview_version.go +++ /dev/null @@ -1,49 +0,0 @@ -package reach - -import ( - "sync" - - "forge.cadoles.com/Pyxis/golang-socketio" - "github.com/pkg/errors" -) - -const ( - eventGetReachViewVersion = "get reachview version" - eventReachViewVersionResults = "current reachview version" -) - -type reachViewVersion struct { - Version string `json:"version"` -} - -// ReachViewVersion returns the ReachRS module ReachView version -func (u *Updater) ReachViewVersion() (string, error) { - - var err error - var version string - var wg sync.WaitGroup - - wg.Add(1) - - err = u.conn.On(eventReachViewVersionResults, func(h *gosocketio.Channel, rv *reachViewVersion) { - version = rv.Version - u.conn.Off(eventReachViewVersionResults) - wg.Done() - }) - if err != nil { - return "", errors.Wrapf(err, "error while binding to '%s' event", eventReachViewVersionResults) - } - - u.logf("sending '%s' event", eventGetReachViewVersion) - if err = u.conn.Emit(eventGetReachViewVersion, nil); err != nil { - return "", errors.Wrapf(err, "error while emitting '%s' event", eventGetReachViewVersion) - } - u.logf("'%s' event sent", eventGetReachViewVersion) - - wg.Wait() - - u.logf("reachview version result: %v", version) - - return version, err - -} diff --git a/reach/receiver_upgrade.go b/reach/receiver_upgrade.go deleted file mode 100644 index 79b9630..0000000 --- a/reach/receiver_upgrade.go +++ /dev/null @@ -1,49 +0,0 @@ -package reach - -import ( - "sync" - - "forge.cadoles.com/Pyxis/golang-socketio" - "github.com/pkg/errors" -) - -const ( - eventIsReceiverUpgradeAvailable = "is receiver upgrade available" - eventReceiverUpgradeAvailable = "receiver upgrade available" -) - -type receiverUpgreAvailable struct { - Available bool `json:"available"` - Running bool `json:"running"` -} - -// ReceiverUpgradeAvailable checks if an upgrade is avaialable/running for the ReachRS module -func (u *Updater) ReceiverUpgradeAvailable() (available bool, running bool, err error) { - - var wg sync.WaitGroup - - wg.Add(1) - - err = u.conn.On(eventReceiverUpgradeAvailable, func(h *gosocketio.Channel, up *receiverUpgreAvailable) { - available = up.Available - running = up.Running - u.conn.Off(eventReceiverUpgradeAvailable) - wg.Done() - }) - if err != nil { - return false, false, errors.Wrapf(err, "error while binding to '%s' event", eventReceiverUpgradeAvailable) - } - - u.logf("sending '%s' event", eventIsReceiverUpgradeAvailable) - if err = u.conn.Emit(eventIsReceiverUpgradeAvailable, nil); err != nil { - return false, false, errors.Wrapf(err, "error while emitting '%s' event", eventIsReceiverUpgradeAvailable) - } - u.logf("'%s' event sent", eventIsReceiverUpgradeAvailable) - - wg.Wait() - - u.logf("receiver upgrade result: available: %v, running: %v", available, running) - - return available, running, err - -} diff --git a/reach/test.go b/reach/test.go deleted file mode 100644 index 5343fc6..0000000 --- a/reach/test.go +++ /dev/null @@ -1,13 +0,0 @@ -package reach - -import "flag" - -var runUpdaterIntegrationTests = flag.Bool( - "updater-integration", false, - "Run the 'Updater' integration tests (in addition to the unit tests)", -) - -var reachHost = flag.String( - "reach-host", "192.168.42.1", - "The Reach module host to use in integration tests", -) diff --git a/reach/test_results.go b/reach/test_results.go deleted file mode 100644 index d7ee808..0000000 --- a/reach/test_results.go +++ /dev/null @@ -1,53 +0,0 @@ -package reach - -import ( - "sync" - - "forge.cadoles.com/Pyxis/golang-socketio" - "github.com/pkg/errors" -) - -const ( - eventGetTestResults = "get test results" - eventTestResults = "test results" -) - -// TestResults are the ReachRS module's test results -// -type TestResults struct { - Device string `json:"device"` - Lora bool `json:"lora"` - MPU bool `json:"mpu"` - STC bool `json:"stc"` - UBlox bool `json:"u-blox"` -} - -// TestResults returns the ReachRS module tests results -func (u *Updater) TestResults() (*TestResults, error) { - - var err error - var results *TestResults - var wg sync.WaitGroup - - wg.Add(1) - - err = u.conn.On(eventTestResults, func(h *gosocketio.Channel, res *TestResults) { - results = res - u.conn.Off(eventTestResults) - wg.Done() - }) - if err != nil { - return nil, errors.Wrapf(err, "error while binding to '%s' event", eventTestResults) - } - - u.logf("sending '%s' event", eventGetTestResults) - if err = u.conn.Emit(eventGetTestResults, nil); err != nil { - return nil, errors.Wrapf(err, "error while emitting '%s' event", eventGetTestResults) - } - u.logf("'%s' event sent", eventGetTestResults) - - wg.Wait() - - return results, err - -} diff --git a/reach/time_sync.go b/reach/time_sync.go deleted file mode 100644 index b4e90eb..0000000 --- a/reach/time_sync.go +++ /dev/null @@ -1,50 +0,0 @@ -package reach - -import ( - "sync" - - "forge.cadoles.com/Pyxis/golang-socketio" - "github.com/pkg/errors" -) - -const ( - eventGetTimeSyncStatus = "get time sync status" - eventTimeSyncResults = "time sync status" -) - -type timeSyncStatus struct { - Status bool `json:"status"` -} - -// TimeSynced returns the ReachRS module time synchronization status. -// A true response means that the module has synchronized its clock. -func (u *Updater) TimeSynced() (bool, error) { - - var err error - var synced bool - var wg sync.WaitGroup - - wg.Add(1) - - err = u.conn.On(eventTimeSyncResults, func(h *gosocketio.Channel, st *timeSyncStatus) { - synced = st.Status - u.conn.Off(eventTimeSyncResults) - wg.Done() - }) - if err != nil { - return false, errors.Wrapf(err, "error while binding to '%s' event", eventTimeSyncResults) - } - - u.logf("sending '%s' event", eventGetTimeSyncStatus) - if err = u.conn.Emit(eventGetTimeSyncStatus, nil); err != nil { - return false, errors.Wrapf(err, "error while emitting '%s' event", eventGetTimeSyncStatus) - } - u.logf("'%s' event sent", eventGetTimeSyncStatus) - - wg.Wait() - - u.logf("time sync result: %v", synced) - - return synced, err - -} diff --git a/reach/update.go b/reach/update.go deleted file mode 100644 index 0d8d445..0000000 --- a/reach/update.go +++ /dev/null @@ -1,55 +0,0 @@ -package reach - -import ( - "sync" - - "forge.cadoles.com/Pyxis/golang-socketio" - "github.com/pkg/errors" -) - -const ( - eventUpdate = "update" - eventOPKGUpdateResult = "opkg update result" -) - -// UpdateStatus embeds informations about update status -type UpdateStatus struct { - Active bool `json:"active"` - Locked bool `json:"locked"` - State string `json:"state"` -} - -// Update asks the ReachRS module to start an OPKG update -func (u *Updater) Update() (*UpdateStatus, error) { - - var err error - var status *UpdateStatus - var wg sync.WaitGroup - - wg.Add(1) - - err = u.conn.On(eventOPKGUpdateResult, func(h *gosocketio.Channel, st *UpdateStatus) { - status = st - u.conn.Off(eventOPKGUpdateResult) - wg.Done() - }) - if err != nil { - return nil, errors.Wrapf(err, "error while binding to '%s' event", eventOPKGUpdateResult) - } - - u.logf("sending '%s' event", eventUpdate) - if err = u.conn.Emit(eventUpdate, nil); err != nil { - return nil, errors.Wrapf(err, "error while emitting '%s' event", eventUpdate) - } - u.logf("'%s' event sent", eventUpdate) - - wg.Wait() - - u.logf( - "opkg update result: active: %v, state: %v, locked: %v", - status.Active, status.State, status.Locked, - ) - - return status, err - -} diff --git a/reach/updater.go b/reach/updater.go deleted file mode 100644 index 888790d..0000000 --- a/reach/updater.go +++ /dev/null @@ -1,12 +0,0 @@ -package reach - -// Updater is a ReachRS Updater client -type Updater struct { - *client -} - -// NewUpdaterClient returns a new ReachRS Updater client -func NewUpdaterClient(opts ...OptionFunc) *Updater { - client := newClient(opts...) - return &Updater{client} -} diff --git a/reach/wifi_networks.go b/reach/wifi_networks.go deleted file mode 100644 index eac96c0..0000000 --- a/reach/wifi_networks.go +++ /dev/null @@ -1,171 +0,0 @@ -package reach - -import ( - "sync" - - "forge.cadoles.com/Pyxis/golang-socketio" - "github.com/pkg/errors" -) - -const ( - eventGetSavedWifiNetworks = "get saved wifi networks" - eventSavedWifiNetworkResults = "wifi saved networks results" - eventAddWifiNetwork = "add new network" - eventAddWifiNetworkResults = "add network results" - eventRemoveWifiNetwork = "remove network" - eventRemoveWifiNetworkResults = "remove network results" - eventConnectToNetwork = "connect to network" -) - -// WifiSecurity is a WiFi network security algorithm -type WifiSecurity string - -const ( - // SecurityWEP WEP wifi network - SecurityWEP WifiSecurity = "wep" - // SecurityWPAPSK WPA(2)-PSK wifi network - SecurityWPAPSK WifiSecurity = "wpa-psk" - // SecurityOpen Open wifi network - SecurityOpen WifiSecurity = "open" -) - -// WifiNetwork is a ReachRS module wifi network -type WifiNetwork struct { - SSID string `json:"ssid"` - Password string `json:"password"` - Security WifiSecurity `json:"security"` - Identity string `json:"identity"` - Visible bool `json:"is_visible"` - Connected bool `json:"is_connected"` - Added bool `json:"is_added"` -} - -// WifiNetworks returns the ReachRS module wifi networks -func (u *Updater) WifiNetworks() ([]*WifiNetwork, error) { - - var err error - var wifiNetworks []*WifiNetwork - var wg sync.WaitGroup - - wg.Add(1) - - err = u.conn.On(eventSavedWifiNetworkResults, func(h *gosocketio.Channel, wn []*WifiNetwork) { - wifiNetworks = wn - u.conn.Off(eventSavedWifiNetworkResults) - wg.Done() - }) - if err != nil { - return nil, errors.Wrapf(err, "error while binding to '%s' event", eventSavedWifiNetworkResults) - } - - u.logf("sending '%s' event", eventGetSavedWifiNetworks) - if err = u.conn.Emit(eventGetSavedWifiNetworks, nil); err != nil { - return nil, errors.Wrapf(err, "error while emitting '%s' event", eventGetSavedWifiNetworks) - } - u.logf("'%s' event sent", eventGetSavedWifiNetworks) - - wg.Wait() - - return wifiNetworks, err - -} - -// AddWifiNetwork asks the ReachRS module to save the given wifi network informations -func (u *Updater) AddWifiNetwork(ssid string, security WifiSecurity, password string) (bool, error) { - - var err error - var wg sync.WaitGroup - var done bool - - wg.Add(1) - - err = u.conn.On(eventAddWifiNetworkResults, func(h *gosocketio.Channel, d bool) { - done = d - u.conn.Off(eventAddWifiNetworkResults) - wg.Done() - }) - if err != nil { - return false, errors.Wrapf(err, "error while binding to '%s' event", eventAddWifiNetworkResults) - } - - wn := &WifiNetwork{ - SSID: ssid, - Security: security, - Password: password, - } - - u.logf("sending '%s' event", eventAddWifiNetwork) - if err = u.conn.Emit(eventAddWifiNetwork, wn); err != nil { - return false, errors.Wrapf(err, "error while emitting '%s' event", eventAddWifiNetwork) - } - u.logf("'%s' event sent", eventAddWifiNetwork) - - wg.Wait() - - return done, err - -} - -// RemoveWifiNetwork asks the ReachRS module to remove the given WiFi network -func (u *Updater) RemoveWifiNetwork(ssid string) (bool, error) { - - var err error - var wg sync.WaitGroup - var done bool - - wg.Add(1) - - err = u.conn.On(eventRemoveWifiNetworkResults, func(h *gosocketio.Channel, d bool) { - done = d - u.conn.Off(eventRemoveWifiNetworkResults) - wg.Done() - }) - if err != nil { - return false, errors.Wrapf(err, "error while binding to '%s' event", eventRemoveWifiNetworkResults) - } - - u.logf("sending '%s' event", eventRemoveWifiNetwork) - if err := u.conn.Emit(eventRemoveWifiNetwork, ssid); err != nil { - return false, errors.Wrapf(err, "error while emitting '%s' event", eventRemoveWifiNetwork) - } - u.logf("'%s' event sent", eventRemoveWifiNetwork) - - wg.Wait() - - return done, nil - -} - -// JoinWifiNetwork asks the ReachRS module to join the given WiFi network -func (u *Updater) JoinWifiNetwork(ssid string, waitDisconnect bool) error { - - var err error - var wg sync.WaitGroup - - if waitDisconnect { - - wg.Add(1) - - err = u.conn.On(gosocketio.OnDisconnection, func(h *gosocketio.Channel) { - u.conn.Off(gosocketio.OnDisconnection) - wg.Done() - }) - - if err != nil { - return errors.Wrapf(err, "error while binding to '%s' event", gosocketio.OnDisconnection) - } - - } - - u.logf("sending '%s' event", eventConnectToNetwork) - if err := u.conn.Emit(eventConnectToNetwork, ssid); err != nil { - return errors.Wrapf(err, "error while emitting '%s' event", eventConnectToNetwork) - } - u.logf("'%s' event sent", eventConnectToNetwork) - - if waitDisconnect { - wg.Wait() - } - - return nil -}