forked from adrianmo/go-nmea
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'adrianmo:master' into master
- Loading branch information
Showing
164 changed files
with
10,523 additions
and
691 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
pull_request: | ||
branches: | ||
- master | ||
workflow_dispatch: | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
go: ["1.20", "1.19", "1.18", "1.17"] | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v3 | ||
with: | ||
go-version: ${{ matrix.go }} | ||
|
||
- name: Install dependencies | ||
run: | | ||
go install golang.org/x/lint/golint@latest | ||
go install github.com/mattn/[email protected] | ||
- name: Lint | ||
run: | | ||
go vet ./... | ||
golint -set_exit_status ./... | ||
- name: Test | ||
run: | | ||
go test -v -race -covermode=atomic -coverprofile=profile.cov ./... | ||
- name: Coverage | ||
run: | | ||
goveralls -coverprofile=profile.cov -service=github -parallel -flagname="go-${{ matrix.go }}" | ||
env: | ||
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
.DEFAULT_GOAL := check | ||
check: lint vet test ## Check project | ||
|
||
lint: ## Lint the files | ||
@golint -set_exit_status ./... | ||
|
||
vet: ## Vet the files | ||
@go vet ./... | ||
|
||
test: ## Run tests with data race detector | ||
@go test -race ./... | ||
|
||
init: | ||
@go install golang.org/x/lint/golint@latest | ||
|
||
goversion ?= "1.19" | ||
test_version: ## Run tests inside Docker with given version (defaults to 1.19). Example for Go1.15: make test_version goversion=1.15 | ||
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make test" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package nmea | ||
|
||
const ( | ||
// TypeAAM type of AAM sentence for Waypoint Arrival Alarm | ||
TypeAAM = "AAM" | ||
) | ||
|
||
// AAM - Waypoint Arrival Alarm | ||
// This sentence is generated by some units to indicate the status of arrival (entering the arrival circle, or passing | ||
// the perpendicular of the course line) at the destination waypoint (source: GPSD). | ||
// https://gpsd.gitlab.io/gpsd/NMEA.html#_aam_waypoint_arrival_alarm | ||
// | ||
// Format: $--AAM,A,A,x.x,N,c--c*hh<CR><LF> | ||
// Example: $GPAAM,A,A,0.10,N,WPTNME*43 | ||
type AAM struct { | ||
BaseSentence | ||
// StatusArrivalCircleEntered is warning of arrival to waypoint circle | ||
// * A = Arrival Circle Entered | ||
// * V = not entered | ||
StatusArrivalCircleEntered string | ||
|
||
// StatusPerpendicularPassed is warning for perpendicular passing of waypoint | ||
// * A = Perpendicular passed at waypoint | ||
// * V = not passed | ||
StatusPerpendicularPassed string | ||
|
||
// ArrivalCircleRadius is radius for arrival circle | ||
ArrivalCircleRadius float64 | ||
|
||
// ArrivalCircleRadiusUnit is unit for arrival circle radius | ||
ArrivalCircleRadiusUnit string | ||
|
||
// DestinationWaypointID is destination waypoint ID | ||
DestinationWaypointID string | ||
} | ||
|
||
// newAAM constructor | ||
func newAAM(s BaseSentence) (Sentence, error) { | ||
p := NewParser(s) | ||
p.AssertType(TypeAAM) | ||
return AAM{ | ||
BaseSentence: s, | ||
StatusArrivalCircleEntered: p.EnumString(0, "arrival circle entered status", WPStatusArrivalCircleEnteredA, WPStatusArrivalCircleEnteredV), | ||
StatusPerpendicularPassed: p.EnumString(1, "perpendicularly passed status", WPStatusPerpendicularPassedA, WPStatusPerpendicularPassedV), | ||
ArrivalCircleRadius: p.Float64(2, "arrival circle radius"), | ||
ArrivalCircleRadiusUnit: p.EnumString(3, "arrival circle radius units", DistanceUnitKilometre, DistanceUnitNauticalMile, DistanceUnitStatuteMile, DistanceUnitMetre), | ||
DestinationWaypointID: p.String(4, "destination waypoint ID"), | ||
}, p.Err() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package nmea | ||
|
||
import ( | ||
"github.com/stretchr/testify/assert" | ||
"testing" | ||
) | ||
|
||
func TestAAM(t *testing.T) { | ||
var tests = []struct { | ||
name string | ||
raw string | ||
err string | ||
msg AAM | ||
}{ | ||
{ | ||
name: "good sentence", | ||
raw: "$GPAAM,A,A,0.10,N,WPTNME*32", | ||
msg: AAM{ | ||
StatusArrivalCircleEntered: WPStatusArrivalCircleEnteredA, | ||
StatusPerpendicularPassed: WPStatusPerpendicularPassedA, | ||
ArrivalCircleRadius: 0.1, | ||
ArrivalCircleRadiusUnit: DistanceUnitNauticalMile, | ||
DestinationWaypointID: "WPTNME", | ||
}, | ||
}, | ||
{ | ||
name: "invalid nmea: StatusArrivalCircleEntered", | ||
raw: "$GPAAM,x,A,0.10,N,WPTNME*0B", | ||
err: "nmea: GPAAM invalid arrival circle entered status: x", | ||
}, | ||
{ | ||
name: "invalid nmea: StatusPerpendicularPassed", | ||
raw: "$GPAAM,A,x,0.10,N,WPTNME*0B", | ||
err: "nmea: GPAAM invalid perpendicularly passed status: x", | ||
}, | ||
{ | ||
name: "invalid nmea: DistanceUnitNauticalMile", | ||
raw: "$GPAAM,A,A,0.10,x,WPTNME*04", | ||
err: "nmea: GPAAM invalid arrival circle radius units: x", | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
m, err := Parse(tt.raw) | ||
if tt.err != "" { | ||
assert.Error(t, err) | ||
assert.EqualError(t, err, tt.err) | ||
} else { | ||
assert.NoError(t, err) | ||
aam := m.(AAM) | ||
aam.BaseSentence = BaseSentence{} | ||
assert.Equal(t, tt.msg, aam) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package nmea | ||
|
||
const ( | ||
// TypeABM type of ABM sentence for AIS addressed binary and safety related message | ||
TypeABM = "ABM" | ||
) | ||
|
||
// ABM - AIS addressed binary and safety related message | ||
// https://fcc.report/FCC-ID/ADB9ZWRTR100/2768717.pdf (page 6) FURUNO MARINE RADAR, model FAR-15XX manual | ||
// | ||
// Format: !--ABM,x,x,x,xxxxxxxxx,x,xx,s--s,x,*hh<CR><LF> | ||
// Example: !AIABM,26,2,1,3381581370,3,8,177KQJ5000G?tO`K>RA1wUbN0TKH,0*02 | ||
type ABM struct { | ||
BaseSentence | ||
|
||
// NumFragments is total number of fragments/sentences need to transfer the message (1 - 9) | ||
NumFragments int64 // 0 | ||
|
||
// FragmentNumber is current fragment/sentence number (1 - 9) | ||
FragmentNumber int64 // 1 | ||
|
||
// MessageID is sequential message identifier (0 - 3) | ||
MessageID int64 // 2 | ||
|
||
// MMSI is The MMSI of destination AIS unit for the ITU-R M.1371 message (10 digits or empty) | ||
MMSI string // 3 | ||
|
||
// Channel is AIS channel for broadcast of the radio message (0 - 3) | ||
// 0 - no broadcast | ||
// 1 - on AIS channel A | ||
// 2 - on AIS channel B | ||
// 3 - broadcast on both AIS channels | ||
Channel string // 4 | ||
|
||
// VDLMessageNumber is VDL message number (6/12), see ITU-R M.1371 | ||
VDLMessageNumber int64 // 5 | ||
|
||
// Payload is encapsulated data (6 bit binary-converted data) (1 - 63 bytes) | ||
Payload []byte // 6 | ||
// 7 - Number of fill bits (0 - 5) | ||
} | ||
|
||
// newABM constructor | ||
func newABM(s BaseSentence) (Sentence, error) { | ||
p := NewParser(s) | ||
p.AssertType(TypeABM) | ||
return ABM{ | ||
BaseSentence: s, | ||
NumFragments: p.Int64(0, "number of fragments"), | ||
FragmentNumber: p.Int64(1, "fragment number"), | ||
MessageID: p.Int64(2, "message ID"), | ||
MMSI: p.String(3, "MMSI"), | ||
Channel: p.String(4, "channel"), | ||
VDLMessageNumber: p.Int64(5, "VDL message number"), | ||
Payload: p.SixBitASCIIArmour(6, int(p.Int64(7, "number of padding bits")), "payload"), | ||
}, p.Err() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package nmea | ||
|
||
import ( | ||
"github.com/stretchr/testify/assert" | ||
"testing" | ||
) | ||
|
||
func TestABM(t *testing.T) { | ||
var tests = []struct { | ||
name string | ||
raw string | ||
err string | ||
msg ABM | ||
}{ | ||
{ | ||
name: "Good single fragment message", | ||
raw: "!AIABM,26,2,1,3381581370,3,8,177KQJ5000G?tO`K>RA1wUbN0TKH,0*02", | ||
msg: ABM{ | ||
NumFragments: 26, | ||
FragmentNumber: 2, | ||
MessageID: 1, | ||
MMSI: "3381581370", | ||
Channel: "3", | ||
VDLMessageNumber: 8, | ||
Payload: []byte{ | ||
0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, // 10 | ||
0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, // 20 | ||
0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, // 30 | ||
0x0, 0x1, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, // 40 | ||
0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // 50 | ||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // 60 | ||
0x0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, // 70 | ||
0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, // 80 | ||
0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, // 90 | ||
0x0, 0x1, 0x1, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, // 100 | ||
0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x1, // 110 | ||
0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, // 120 | ||
0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x1, // 130 | ||
0x0, 0x1, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x1, // 140 | ||
0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // 150 | ||
0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, // 160 | ||
0x1, 0x1, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, // 168 | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "Good single fragment message with padding", | ||
raw: "!AIABM,26,2,1,3381581370,3,8,H77nSfPh4U=<E`H4U8G;:222220,2*42", | ||
msg: ABM{ | ||
NumFragments: 26, | ||
FragmentNumber: 2, | ||
MessageID: 1, | ||
MMSI: "3381581370", | ||
Channel: "3", | ||
VDLMessageNumber: 8, | ||
Payload: []byte{ | ||
0, 1, 1, 0, 0, 0, 0, 0, 0, 1, | ||
1, 1, 0, 0, 0, 1, 1, 1, 1, 1, | ||
0, 1, 1, 0, 1, 0, 0, 0, 1, 1, | ||
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, | ||
0, 0, 1, 1, 0, 0, 0, 0, 0, 0, | ||
0, 1, 0, 0, 1, 0, 0, 1, 0, 1, | ||
0, 0, 1, 1, 0, 1, 0, 0, 1, 1, | ||
0, 0, 0, 1, 0, 1, 0, 1, 1, 0, | ||
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, | ||
0, 0, 0, 1, 0, 0, 1, 0, 0, 1, | ||
0, 1, 0, 0, 1, 0, 0, 0, 0, 1, | ||
0, 1, 1, 1, 0, 0, 1, 0, 1, 1, | ||
0, 0, 1, 0, 1, 0, 0, 0, 0, 0, | ||
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, | ||
0, 0, 1, 0, 0, 0, 0, 0, 1, 0, | ||
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "Empty payload", | ||
raw: "!AIABM,26,2,1,3381581370,3,8,,0*7b", | ||
msg: ABM{ | ||
NumFragments: 26, | ||
FragmentNumber: 2, | ||
MessageID: 1, | ||
MMSI: "3381581370", | ||
Channel: "3", | ||
VDLMessageNumber: 8, | ||
Payload: []byte{}, | ||
}, | ||
}, | ||
{ | ||
name: "Invalid number of fragments", | ||
raw: "!AIABM,x,2,1,3381581370,3,8,177KQJ5000G?tO`K>RA1wUbN0TKH,0*7e", | ||
err: "nmea: AIABM invalid number of fragments: x", | ||
}, | ||
{ | ||
name: "Invalid VDLMessageNumber", | ||
raw: "!AIABM,26,2,1,3381581370,3,x,177KQJ5000G?tO`K>RA1wUbN0TKH,0*42", | ||
err: "nmea: AIABM invalid VDL message number: x", | ||
}, | ||
{ | ||
name: "Invalid symbol in payload", | ||
raw: "!AIABM,26,2,1,3381581370,3,8,1 1,0*5b", | ||
err: "nmea: AIABM invalid payload: data byte", | ||
}, | ||
{ | ||
name: "Negative number of fill bits", | ||
raw: "!AIABM,26,2,1,3381581370,3,8,177KQJ5000G?tO`K>RA1wUbN0TKH,-1*2e", | ||
err: "nmea: AIABM invalid payload: fill bits", | ||
}, | ||
{ | ||
name: "Too high number of fill bits", | ||
raw: "!AIABM,26,2,1,3381581370,3,8,177KQJ5000G?tO`K>RA1wUbN0TKH,20*30", | ||
err: "nmea: AIABM invalid payload: fill bits", | ||
}, | ||
{ | ||
name: "Negative number of bits", | ||
raw: "!AIABM,26,2,1,3381581370,3,8,,2*79", | ||
err: "nmea: AIABM invalid payload: num bits", | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
m, err := Parse(tt.raw) | ||
if tt.err != "" { | ||
assert.Error(t, err) | ||
assert.EqualError(t, err, tt.err) | ||
} else { | ||
assert.NoError(t, err) | ||
abm := m.(ABM) | ||
abm.BaseSentence = BaseSentence{} | ||
assert.Equal(t, tt.msg, abm) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.