Merge pull request #3 from martinhpedersen/datablock-fixes

DataBlock fixes
master
tehmaze 5 years ago committed by GitHub
commit f3e5caa7d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -15,6 +15,30 @@ const (
MaxPacketFragmentSize = 1500 MaxPacketFragmentSize = 1500
) )
// CRC Masks for data block's CRC-9 calculation, see DMR AI spec. page 148 (Table B.21).
var crc9Masks = map[uint8]uint16{
Rate12Data: 0x00f0,
Rate34Data: 0x01ff,
//Rate1Data: 0x010f,
}
func calculateCRC9(serial uint8, data []byte, dataType uint8) (crc uint16) {
for _, block := range data {
crc9(&crc, block, 8)
}
crc9(&crc, serial, 7)
crc9end(&crc, 8)
// Inverting according to the inversion polynomial.
crc = ^crc
crc &= 0x01ff
// Applying Data Type CRC Mask
crc ^= crc9Masks[dataType]
return crc
}
type DataBlock struct { type DataBlock struct {
Serial uint8 Serial uint8
CRC uint16 CRC uint16
@ -37,17 +61,7 @@ func ParseDataBlock(data []byte, dataType uint8, confirmed bool) (*DataBlock, er
db.Data = make([]byte, db.Length) db.Data = make([]byte, db.Length)
copy(db.Data, data[2:2+db.Length]) copy(db.Data, data[2:2+db.Length])
for _, block := range db.Data { crc = calculateCRC9(db.Serial, db.Data, dataType)
crc9(&crc, block, 8)
}
crc9(&crc, db.Serial, 7)
crc9end(&crc, 8)
// Inverting according to the inversion polynomial.
crc = ^crc
crc &= 0x01ff
// Applying CRC mask, see DMR AI spec. page 143
crc ^= 0x01ff
// FIXME(pd0mz): this is not working // FIXME(pd0mz): this is not working
if crc != db.CRC { if crc != db.CRC {
@ -69,17 +83,10 @@ func (db *DataBlock) Bytes(dataType uint8, confirmed bool) []byte {
) )
if confirmed { if confirmed {
for _, block := range db.Data { db.CRC = calculateCRC9(db.Serial, db.Data, dataType)
crc9(&db.CRC, block, 8)
}
crc9(&db.CRC, db.Serial, 7)
crc9end(&db.CRC, 8)
// Inverting according to the inversion polynomial. // Grow data slice to support the two byte prefix
db.CRC = ^db.CRC data = append(data, make([]byte, 2)...)
db.CRC &= 0x01ff
// Applying CRC mask, see DMR AI spec. page 143
db.CRC ^= 0x01ff
data[0] = (db.Serial << 1) | (uint8(db.CRC>>8) & 0x01) data[0] = (db.Serial << 1) | (uint8(db.CRC>>8) & 0x01)
data[1] = uint8(db.CRC) data[1] = uint8(db.CRC)
@ -177,18 +184,7 @@ func (df *DataFragment) DataBlocks(dataType uint8, confirm bool) ([]*DataBlock,
} }
// Calculate block CRC9 // Calculate block CRC9
block.CRC = 0 block.CRC = calculateCRC9(block.Serial, block.Data, dataType)
for _, b := range block.Data {
crc9(&block.CRC, b, 8)
}
crc9(&block.CRC, block.Serial, 7)
crc9end(&block.CRC, 8)
// Inverting according to the inversion polynomial
block.CRC = ^block.CRC
block.CRC &= 0x01ff
// Applying CRC mask, see DMR AI spec. page 143
block.CRC ^= 0x01ff
blocks[i] = block blocks[i] = block
} }

@ -19,7 +19,8 @@ func TestDataBlock(t *testing.T) {
if data == nil { if data == nil {
t.Fatal("encode failed") t.Fatal("encode failed")
} }
size := int(dataBlockLength(Rate34Data, true)) // Size is the user-data + two octets of serial/crc
size := int(dataBlockLength(Rate34Data, true)) + 2
if len(data) != size { if len(data) != size {
t.Fatalf("encode failed: expected %d bytes, got %d", size, len(data)) t.Fatalf("encode failed: expected %d bytes, got %d", size, len(data))
} }

Loading…
Cancel
Save