Refactor and enhance handling of payloads and data structures

Added support for handling various payload types, including GPS and alarms, with new structures and constants. Introduced helper methods for JSON marshalling/unmarshalling of GPS data and modularized the handling of certificates, configurations, and alarms. Implemented foundational server code for testing and expanded several package functionalities.
This commit is contained in:
2025-02-22 19:23:16 +03:00
parent f3083820dc
commit 16da4affa8
7 changed files with 607 additions and 61 deletions

53
io.go
View File

@ -2,10 +2,12 @@ package n9m
import (
"bytes"
"encoding/binary"
"encoding/json"
"log"
"fmt"
"github.com/icza/bitio"
"log"
"time"
)
// Read package
@ -20,7 +22,7 @@ func (e *Package) ReadPackage() bool {
e.CompressFlag = r.TryReadBool()
e.CSRCCount = uint8(r.TryReadBits(4))
e.PayloadType = PayloadType(r.TryReadBits(8))
e.SSRC = uint16(r.TryReadBits(16))
e.SSRC = SpecialPayloadType((r.TryReadBits(8) | (r.TryReadBits(8) << 8)))
if e.EncryptionFlag && e.CompressFlag {
// TODO: get snippet, that use this code
@ -60,11 +62,34 @@ func (e *Package) ReadPackage() bool {
e.Accum = e.Accum[12+e.payloadLen:]
if e.PayloadType == PayloadTypeData {
switch e.PayloadType {
case PayloadTypeData:
if err := json.Unmarshal(e.RawPayload, &e.Payload); err != nil {
log.Printf("Error parsing JSON payload: %v", err)
return false
}
case PayloadTypeSpecial:
switch e.SSRC {
case SpecialPayloadTypeGPS:
e.GPS.GPSStatus = e.RawPayload[0]
e.GPS.Expand = e.RawPayload[1]
e.GPS.Real = e.RawPayload[2]
e.GPS.Longitude = float64(binary.BigEndian.Uint32(e.RawPayload[4:8])) / 1e6
e.GPS.Latitude = float64(binary.BigEndian.Uint32(e.RawPayload[8:12])) / 1e6
e.GPS.Speed = float64(binary.BigEndian.Uint32(e.RawPayload[12:16])) / 100
e.GPS.Direction = float64(binary.BigEndian.Uint32(e.RawPayload[16:20])) / 100
e.GPS.Altitude = int32(binary.BigEndian.Uint32(e.RawPayload[20:24]))
var err error
if e.GPS.Time, err = time.Parse("20060102150405", string(e.RawPayload[24:38])); err != nil {
log.Printf("Error parsing time: %v", err)
}
default:
fmt.Println("N9M parser warning: unknown special payload type", e.SSRC)
}
default:
fmt.Println("N9M parser warning: unknown payload type", e.PayloadType)
}
if r.TryError != nil {
@ -141,3 +166,23 @@ func (e *Package) GetParametersAs(parameters any) error {
return json.Unmarshal(marshal, parameters)
}
func (e *Package) SetParameters(parameters any) {
e.Payload.Response = struct{}{}
e.Payload.Parameter = parameters
}
func (e *Package) GetResponseAs(response any) error {
marshal, err := json.Marshal(e.Payload.Response)
if err != nil {
return err
}
return json.Unmarshal(marshal, response)
}
func (e *Package) SetResponse(response any) {
e.Payload.Parameter = struct{}{}
e.Payload.Response = response
}