Skip to content

Commit

Permalink
chore: update readme with tcp support, fix lint warnings, update fati…
Browse files Browse the repository at this point in the history
…h/color for example.
  • Loading branch information
xiegeo committed Sep 8, 2022
1 parent 91c55f9 commit a691ec2
Show file tree
Hide file tree
Showing 21 changed files with 163 additions and 139 deletions.
28 changes: 24 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,19 @@ linters-settings:
linters:
enable-all: true
disable:
# might be good to have for future refactoring
- wrapcheck
- goerr113
- gocyclo
- cyclop
- exhaustive
- durationcheck
- errname

# generally disabled linters
- nolintlint
- errcheck
- gochecknoglobals
- gocyclo
- gocyclop
- gocognit
- lll
- gomnd
Expand All @@ -24,8 +33,12 @@ linters:
- varnamelen
- nlreturn
- exhaustruct
- nonamedreturns
- testpackage
- thelper
- ireturn

# offically deprecated
# officially deprecated
- nosnakecase
- maligned
- exhaustivestruct
Expand All @@ -37,10 +50,17 @@ linters:
- golint

issues:
exclude-rules:
- path: "(.+)_test.go"
linters:
- maintidx
- unused

exclude:
- "G104: Errors unhandled." # turn off errcheck
- "declaration of \"[a-z]\" shadows declaration at .*_test.go" # ignore shadowing a single charcter varibles in tests
- "declaration of \"[a-z]\" shadows declaration at .*_test.go" # ignore shadowing a single character variables in tests
- "receiver name [a-z]0 should be consistent with previous receiver name [a-z]" # when we want to operate on a copy
- "ST1016: methods on the same type should have the same receiver name .seen .. \"[a-z]0\", .. \"[a-z]\""
- "error strings should not be capitalized or end with punctuation or a newline" # doesn't matter
- "lines are duplicate of `crc.crc.go:" # ignore duplications in crc.go
- "package should be `crc_test` instead of `crc`" # ignore white listed internal testing
Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,25 +220,24 @@ Instead, a callback based API (like http server handler) is used for both server
## Implemented

- Serial RTU
- Modbus over TCP
- Function Codes 1-6,15,16
- Server and Client API
- Server and Client Tester (examples/memory)

## Development

This project is mostly stable, and I am using it in production.
This project and API is stable, and I am using it in production.

API stability is best effort. This means:
My primary usage is RTU (over RS-485). TCP is also supported. Others may or may not be implemented in the future.

- Changes should not break users code unless there is a compelling reason.

- Code broken by API changes should not compile, new errors to user code should not be introduced silently.
Contribution to new or existing functionally, or just changing a private identifier public are welcome, as well as documentation, test, example code or any other improvements.

- API changes will be documented to speed adoption of new versions.
Development tools:

My primary usage is RTU (over RS-485). Others may or may not be implemented in the future.

Contribution to new or existing functionally, or just changing a private identifier public are welcome, as well as documentation, test, example code or any other improvements.
- `go generate` runs `embedmd` to copy parts of the examples_test.go to this readme file
- `golangci-lint run` for improvement hints. Ideally there are no warnings.
- Use `go test -race -count=5 ./...` pre release.

## Breaking Changes

Expand All @@ -255,16 +254,18 @@ Contribution to new or existing functionally, or just changing a private identif

Compatibility with a wide range of serial hardware/drivers. (good)

Compatibility with existing Modbus environments. (good)
Compatibility with existing Modbus environments, including non-compliance and extensions. (good)

Recover from transmission errors and timeouts, to work continuously unattended. (good)

Better test coverage that also tests error conditions. (todo)
Better test coverage that also tests error conditions. (todo)

Fuzz testing. (todo)
Fuzz testing. (todo)

## Failover mode

TLDR: do not use.

Failover has landed in v0.2.0, but it should be considered less stable than the other parts.

In mission-critical applications, or anywhere hardware redundancy is cheaper than downtime, having a standby system taking over in case of the failure of the primary system is desirable.
Expand Down
12 changes: 6 additions & 6 deletions crc/crc.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"io"
)

// Table of CRC values for high–order byte
var crcHighBytes = []byte{
// Table of CRC values for high–order byte.
var crcHighBytes = []byte{ //nolint:dupl
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
Expand All @@ -28,8 +28,8 @@ var crcHighBytes = []byte{
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
}

// Table of CRC values for low-order byte
var crcLowBytes = []byte{
// Table of CRC values for low-order byte.
var crcLowBytes = []byte{ //nolint:dupl
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04,
0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8,
0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
Expand All @@ -48,7 +48,7 @@ var crcLowBytes = []byte{
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40,
}

// Cyclical Redundancy Checking
// crc is Cyclical Redundancy Checking.
type crc struct {
high byte
low byte
Expand Down Expand Up @@ -87,7 +87,7 @@ func (c *crc) Sum16() uint16 {
return uint16(c.low)<<8 | uint16(c.high)
}

// Hash is a subset of hash.Hash
// Hash is a subset of hash.Hash.
type Hash interface {
// Write (via the embedded io.Writer interface) adds more data to the running hash.
// It never returns an error.
Expand Down
2 changes: 1 addition & 1 deletion crc/rtu.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package crc

// Validate return true if byte slice ends with valid crc
// Validate return true if byte slice ends with valid CRC.
func Validate(bs []byte) bool {
if len(bs) <= 2 {
return false
Expand Down
1 change: 1 addition & 0 deletions examples_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//go:generate embedmd -w README.md
//go:generate sed -i -e 's/\t/\ \ \ \ /g' README.md

//nolint:forbidigo
package modbusone_test

import (
Expand Down
6 changes: 3 additions & 3 deletions failover_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ func TestFailoverClient(t *testing.T) {
// t.Skip()

id := byte(0x77)
clientA, clientB, pc, countA, countB, countC, close := connectMockClients(t, id)
defer close()
clientA, clientB, pc, countA, countB, countC, closeClients := connectMockClients(t, id)
defer closeClients()
exCount := &counter{Stats: &Stats{}}
resetCounts := func() {
exCount.reset()
Expand Down Expand Up @@ -106,7 +106,7 @@ func TestFailoverClient(t *testing.T) {
}
time.Sleep(serverProcessingTime)
if !pc.IsActive() {
t.Fatal("primaray client should be active")
t.Fatal("primary client should be active")
}
})

Expand Down
2 changes: 1 addition & 1 deletion failover_rtu_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type FailoverRTUClient struct {
actions chan rtuAction
}

// FailoverRTUClient is also a Server
// FailoverRTUClient is also a Server.
var _ Server = &FailoverRTUClient{}

// NewFailoverRTUClient create a new client with failover function communicating over SerialContext with the
Expand Down
6 changes: 3 additions & 3 deletions failover_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ func connectToMockServers(t *testing.T, slaveID byte) (*RTUClient, *FailoverSeri

func TestFailoverServer(t *testing.T) {
id := byte(0x77)
client, pc, countA, countB, countC, close := connectToMockServers(t, id)
defer close()
client, pc, countA, countB, countC, closeServers := connectToMockServers(t, id)
defer closeServers()
exCount := counter{Stats: &Stats{}}
resetCounts := func() {
exCount.reset()
Expand Down Expand Up @@ -155,7 +155,7 @@ func TestFailoverServer(t *testing.T) {
}
time.Sleep(serverProcessingTime * 2)
if !pc.IsActive() {
t.Fatal("primaray servers should be active")
t.Fatal("primary servers should be active")
}
})

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/xiegeo/modbusone
go 1.14

require (
github.com/fatih/color v1.9.0
github.com/fatih/color v1.13.0
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07
github.com/xiegeo/coloredgoroutine v0.1.1
)
21 changes: 11 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/xiegeo/coloredgoroutine v0.1.1 h1:L6EaQHWIY+oIlKpj5ORu9hIorsLbQwTAStEHSp1SoAs=
github.com/xiegeo/coloredgoroutine v0.1.1/go.mod h1:d3jyamWlthEBXOL5qUpKOaaKSJM75HuCIn/z9f4ylrs=
golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
17 changes: 8 additions & 9 deletions handler2serial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package modbusone_test
import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"sync"
Expand Down Expand Up @@ -125,7 +124,7 @@ func TestHandler(t *testing.T) {
sc.LastWritten = nil
}

t.Run(fmt.Sprintf("Read Coil Status (FC=01)"), func(t *testing.T) {
t.Run("Read Coil Status (FC=01)", func(t *testing.T) {
subtest = t
header, err := FcReadCoils.MakeRequestHeader(0x0013, 0x0025)
if err != nil {
Expand Down Expand Up @@ -154,7 +153,7 @@ func TestHandler(t *testing.T) {
testTrans(header, request, response)
})

t.Run(fmt.Sprintf("Read Input Status (FC=02)"), func(t *testing.T) {
t.Run("Read Input Status (FC=02)", func(t *testing.T) {
subtest = t
header, err := FcReadDiscreteInputs.MakeRequestHeader(0x00C4, 0x0016)
if err != nil {
Expand All @@ -181,7 +180,7 @@ func TestHandler(t *testing.T) {
testTrans(header, request, response)
})

t.Run(fmt.Sprintf("Read Holding Registers (FC=03)"), func(t *testing.T) {
t.Run("Read Holding Registers (FC=03)", func(t *testing.T) {
subtest = t
header, err := FcReadHoldingRegisters.MakeRequestHeader(0x006B, 0x0003)
if err != nil {
Expand All @@ -204,7 +203,7 @@ func TestHandler(t *testing.T) {
testTrans(header, request, response)
})

t.Run(fmt.Sprintf("Read Input Registers (FC=04)"), func(t *testing.T) {
t.Run("Read Input Registers (FC=04)", func(t *testing.T) {
subtest = t
header, err := FcReadInputRegisters.MakeRequestHeader(0x0008, 0x0001)
if err != nil {
Expand All @@ -227,7 +226,7 @@ func TestHandler(t *testing.T) {
testTrans(header, request, response)
})

t.Run(fmt.Sprintf("Write Single Coil (FC=05)"), func(t *testing.T) {
t.Run("Write Single Coil (FC=05)", func(t *testing.T) {
subtest = t
header, err := FcWriteSingleCoil.MakeRequestHeader(0x00AC, 1)
if err != nil {
Expand All @@ -250,7 +249,7 @@ func TestHandler(t *testing.T) {
testTrans(header, request, response)
})

t.Run(fmt.Sprintf("Write Single Register (FC=06)"), func(t *testing.T) {
t.Run("Write Single Register (FC=06)", func(t *testing.T) {
subtest = t
header, err := FcWriteSingleRegister.MakeRequestHeader(0x0001, 1)
if err != nil {
Expand All @@ -273,7 +272,7 @@ func TestHandler(t *testing.T) {
testTrans(header, request, response)
})

t.Run(fmt.Sprintf("Write Multiple Coils (FC=15)"), func(t *testing.T) {
t.Run("Write Multiple Coils (FC=15)", func(t *testing.T) {
subtest = t
header, err := FcWriteMultipleCoils.MakeRequestHeader(0x0013, 0x000A)
if err != nil {
Expand All @@ -298,7 +297,7 @@ func TestHandler(t *testing.T) {
}
testTrans(header, request, response)
})
t.Run(fmt.Sprintf("Write Multiple Registers (FC=16)"), func(t *testing.T) {
t.Run("Write Multiple Registers (FC=16)", func(t *testing.T) {
subtest = t
header, err := FcWriteMultipleRegisters.MakeRequestHeader(0x0001, 0x0002)
if err != nil {
Expand Down
Loading

0 comments on commit a691ec2

Please sign in to comment.