Renamed Data to Frame

pull/1/head
Wijnand Modderman-Lenstra 9 years ago
parent 851da4775f
commit 6ee0b6657f

@ -41,7 +41,7 @@ var (
} }
) )
func dump(d *homebrew.Data) { func dump(d *homebrew.Frame) {
fmt.Println("DMR data:") fmt.Println("DMR data:")
fmt.Printf("\tsequence: %d\n", d.Sequence) fmt.Printf("\tsequence: %d\n", d.Sequence)
fmt.Printf("\ttarget..: %d -> %d\n", d.SrcID, d.DstID) fmt.Printf("\ttarget..: %d -> %d\n", d.SrcID, d.DstID)

@ -22,6 +22,9 @@ var (
PackageID = fmt.Sprintf("%s:go-dmr:%s-%s", runtime.GOOS, Version, runtime.GOARCH) PackageID = fmt.Sprintf("%s:go-dmr:%s-%s", runtime.GOOS, Version, runtime.GOARCH)
) )
// RepeaterConfiguration holds information about the current repeater. It
// should be returned by a callback in the implementation, returning actual
// information about the current repeater status.
type RepeaterConfiguration struct { type RepeaterConfiguration struct {
Callsign string Callsign string
RepeaterID uint32 RepeaterID uint32
@ -37,10 +40,12 @@ type RepeaterConfiguration struct {
URL string URL string
} }
// Bytes returns the configuration as bytes.
func (r *RepeaterConfiguration) Bytes() []byte { func (r *RepeaterConfiguration) Bytes() []byte {
return []byte(r.String()) return []byte(r.String())
} }
// String returns the configuration as string.
func (r *RepeaterConfiguration) String() string { func (r *RepeaterConfiguration) String() string {
if r.ColorCode < 1 { if r.ColorCode < 1 {
r.ColorCode = 1 r.ColorCode = 1
@ -81,6 +86,7 @@ func (r *RepeaterConfiguration) String() string {
type configFunc func() *RepeaterConfiguration type configFunc func() *RepeaterConfiguration
// CallType reflects the DMR data frame call type.
type CallType byte type CallType byte
const ( const (
@ -88,6 +94,7 @@ const (
UnitCall UnitCall
) )
// FrameType reflects the DMR data frame type.
type FrameType byte type FrameType byte
const ( const (
@ -97,7 +104,8 @@ const (
UnusedFrameType UnusedFrameType
) )
type Data struct { // Frame is a frame of DMR data.
type Frame struct {
Signature [4]byte Signature [4]byte
Sequence byte Sequence byte
SrcID uint32 SrcID uint32
@ -108,41 +116,41 @@ type Data struct {
DMR [33]byte DMR [33]byte
} }
func (d *Data) CallType() CallType { func (f *Frame) CallType() CallType {
return CallType((d.Flags >> 1) & 0x01) return CallType((f.Flags >> 1) & 0x01)
} }
func (d *Data) DataType() byte { func (f *Frame) DataType() byte {
return d.Flags >> 4 return f.Flags >> 4
} }
func (d *Data) FrameType() FrameType { func (f *Frame) FrameType() FrameType {
return FrameType((d.Flags >> 2) & 0x03) return FrameType((f.Flags >> 2) & 0x03)
} }
func (d *Data) Slot() int { func (f *Frame) Slot() int {
return int(d.Flags&0x01) + 1 return int(f.Flags&0x01) + 1
} }
func ParseData(data []byte) (*Data, error) { func ParseFrame(data []byte) (*Frame, error) {
if len(data) != 53 { if len(data) != 53 {
return nil, errors.New("invalid packet length") return nil, errors.New("invalid packet length")
} }
d := &Data{} f := &Frame{}
copy(d.Signature[:], data[:4]) copy(f.Signature[:], data[:4])
d.Sequence = data[4] f.Sequence = data[4]
d.SrcID = binary.BigEndian.Uint32(append([]byte{0x00}, data[5:7]...)) f.SrcID = binary.BigEndian.Uint32(append([]byte{0x00}, data[5:7]...))
d.DstID = binary.BigEndian.Uint32(append([]byte{0x00}, data[8:10]...)) f.DstID = binary.BigEndian.Uint32(append([]byte{0x00}, data[8:10]...))
d.RepeaterID = binary.BigEndian.Uint32(data[11:15]) f.RepeaterID = binary.BigEndian.Uint32(data[11:15])
d.Flags = data[15] f.Flags = data[15]
d.StreamID = binary.BigEndian.Uint32(data[16:20]) f.StreamID = binary.BigEndian.Uint32(data[16:20])
copy(d.DMR[:], data[20:]) copy(f.DMR[:], data[20:])
return d, nil return f, nil
} }
type dataFunc func(*Data) type streamFunc func(*Frame)
type authStatus byte type authStatus byte
@ -164,7 +172,7 @@ type Network struct {
type Link struct { type Link struct {
Dump bool Dump bool
config configFunc config configFunc
stream dataFunc stream streamFunc
network *Network network *Network
conn *net.UDPConn conn *net.UDPConn
authKey []byte authKey []byte
@ -184,7 +192,8 @@ type Link struct {
} }
} }
func New(network *Network, cf configFunc, df dataFunc) (*Link, error) { // New starts a new DMR repeater using the Home Brew protocol.
func New(network *Network, cf configFunc, sf streamFunc) (*Link, error) {
if cf == nil { if cf == nil {
return nil, errors.New("config func can't be nil") return nil, errors.New("config func can't be nil")
} }
@ -192,7 +201,7 @@ func New(network *Network, cf configFunc, df dataFunc) (*Link, error) {
link := &Link{ link := &Link{
network: network, network: network,
config: cf, config: cf,
stream: df, stream: sf,
} }
var err error var err error
@ -223,6 +232,7 @@ func New(network *Network, cf configFunc, df dataFunc) (*Link, error) {
return link, nil return link, nil
} }
// Run starts the datagram receiver and logs the repeater in with the master.
func (l *Link) Run() error { func (l *Link) Run() error {
var err error var err error
@ -249,6 +259,7 @@ func (l *Link) Run() error {
return nil return nil
} }
// Send data to an UDP address using the repeater datagram socket.
func (l *Link) Send(addr *net.UDPAddr, data []byte) error { func (l *Link) Send(addr *net.UDPAddr, data []byte) error {
for len(data) > 0 { for len(data) > 0 {
n, err := l.conn.WriteToUDP(data, addr) n, err := l.conn.WriteToUDP(data, addr)
@ -397,7 +408,7 @@ func (l *Link) parse(addr *net.UDPAddr, data []byte) {
if l.stream == nil { if l.stream == nil {
return return
} }
frame, err := ParseData(data) frame, err := ParseFrame(data)
if err != nil { if err != nil {
log.Printf("error parsing DMR data: %v\n", err) log.Printf("error parsing DMR data: %v\n", err)
return return

@ -1,5 +1,7 @@
package homebrew package homebrew
// Messages as documented by DL5DI, G4KLX and DG1HT, see
// http://download.prgm.org/dl5di-soft/dmrplus/documentation/Homebrew-Repeater/DMRplus%20IPSC%20Protocol%20for%20HB%20repeater%20(20150726).pdf
var ( var (
DMRData = []byte("DMRD") DMRData = []byte("DMRD")
MasterNAK = []byte("MSTNAK") MasterNAK = []byte("MSTNAK")

Loading…
Cancel
Save