You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.1 KiB
Go
135 lines
3.1 KiB
Go
package lc
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
dmr "github.com/pd0mz/go-dmr"
|
|
)
|
|
|
|
// Data Format
|
|
// ref: ETSI TS 102 361-2 7.2.18
|
|
const (
|
|
Format7Bit uint8 = iota
|
|
FormatISO8Bit
|
|
FormatUTF8
|
|
FormatUTF16BE
|
|
)
|
|
|
|
// DataFormatName is a map of data format to string.
|
|
var DataFormatName = map[uint8]string{
|
|
Format7Bit: "7 bit",
|
|
FormatISO8Bit: "ISO 8 bit",
|
|
FormatUTF8: "unicode utf-8",
|
|
FormatUTF16BE: "unicode utf-16be",
|
|
}
|
|
|
|
// TalkerAliasHeaderPDU Conforms to ETSI TS 102 361-2 7.1.1.4
|
|
type TalkerAliasHeaderPDU struct {
|
|
DataFormat uint8
|
|
Length uint8
|
|
Data []byte
|
|
}
|
|
|
|
// TalkerAliasBlockPDU Conforms to ETSI TS 102 361-2 7.1.1.5
|
|
type TalkerAliasBlockPDU struct {
|
|
Data []byte
|
|
}
|
|
|
|
func movebit(src []byte, srcByte int, srcBit int, dst []byte, dstByte int, dstBit int) {
|
|
bit := (src[srcByte] >> uint8(srcBit)) & dmr.B00000001
|
|
if bit >= 1 {
|
|
dst[dstByte] |= 1 << uint8(dstBit)
|
|
} else {
|
|
dst[dstByte] &= 0 << uint8(dstBit)
|
|
}
|
|
}
|
|
|
|
// ParseTalkerAliasHeaderPDU parses TalkerAliasHeader PDU from bytes
|
|
func ParseTalkerAliasHeaderPDU(data []byte) (*TalkerAliasHeaderPDU, error) {
|
|
if len(data) != 7 {
|
|
return nil, fmt.Errorf("dmr/lc/talkeralias: expected 7 bytes, got %d", len(data))
|
|
}
|
|
|
|
dataFormat := (data[0] & dmr.B11000000) >> 6
|
|
|
|
var out []byte
|
|
if dataFormat == Format7Bit {
|
|
// it will reorganize the bits in the array and return []byte with 7bit chars
|
|
// in each position
|
|
out = make([]byte, 7)
|
|
for i := 7; i < 56; i++ {
|
|
movebit(data, i/8, (7 - (i % 8)), out, (i-7)/7, 6-(i%7))
|
|
}
|
|
} else {
|
|
out = data[1:6]
|
|
}
|
|
|
|
return &TalkerAliasHeaderPDU{
|
|
DataFormat: dataFormat,
|
|
Length: (data[0] & dmr.B00111110) >> 1,
|
|
Data: out,
|
|
}, nil
|
|
}
|
|
|
|
// Bytes returns object as bytes
|
|
func (t *TalkerAliasHeaderPDU) Bytes() []byte {
|
|
var (
|
|
out []byte
|
|
bit49 byte
|
|
)
|
|
|
|
if t.DataFormat == Format7Bit {
|
|
out = make([]byte, 6)
|
|
for i := 7; i < 56; i++ {
|
|
movebit(t.Data, (i-7)/7, 6-(i%7), out, (i/8)-1, (7 - (i % 8)))
|
|
}
|
|
} else {
|
|
out = t.Data
|
|
}
|
|
|
|
return []byte{
|
|
((t.DataFormat << 6) & dmr.B11000000) | ((t.Length << 1) & dmr.B00111110) | (bit49 & dmr.B00000001),
|
|
out[0],
|
|
out[1],
|
|
out[2],
|
|
out[3],
|
|
out[4],
|
|
out[5],
|
|
}
|
|
}
|
|
|
|
// DataAsString Returns data part of PDU encoded as string
|
|
func (t *TalkerAliasHeaderPDU) DataAsString() string {
|
|
return string(t.Data)
|
|
}
|
|
|
|
func (t *TalkerAliasHeaderPDU) String() string {
|
|
return fmt.Sprintf("TalkerAliasHeader: [ format: %s, length: %d, data: \"%s\" ]",
|
|
DataFormatName[t.DataFormat], t.Length, t.DataAsString())
|
|
}
|
|
|
|
// ParseTalkerAliasBlockPDU parse talker alias block pdu
|
|
func ParseTalkerAliasBlockPDU(data []byte) (*TalkerAliasBlockPDU, error) {
|
|
if len(data) != 7 {
|
|
return nil, fmt.Errorf("dmr/lc/talkeralias: expected 7 bytes, got %d", len(data))
|
|
}
|
|
|
|
return &TalkerAliasBlockPDU{
|
|
Data: data[0:6],
|
|
}, nil
|
|
}
|
|
|
|
// Bytes returns object as bytes
|
|
func (t *TalkerAliasBlockPDU) Bytes() []byte {
|
|
return t.Data
|
|
}
|
|
|
|
// DataAsString Returns data part of PDU encoded as string
|
|
func (t *TalkerAliasBlockPDU) DataAsString() string {
|
|
return string(t.Data)
|
|
}
|
|
|
|
func (t *TalkerAliasBlockPDU) String() string {
|
|
return fmt.Sprintf("TalkerAliasBlock: [ data: \"%s\" ]", t.DataAsString())
|
|
}
|