@ -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,7 @@ 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.
db . CRC = ^ db . CRC
db . CRC &= 0x01ff
// Applying CRC mask, see DMR AI spec. page 143
db . CRC ^ = 0x01ff
// Grow data slice to support the two byte prefix
// Grow data slice to support the two byte prefix
data = append ( data , make ( [ ] byte , 2 ) ... )
data = append ( data , make ( [ ] byte , 2 ) ... )
@ -180,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
}
}