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.

166 lines
2.9 KiB
Go

package bptc
import (
"fmt"
"os"
"github.com/pd0mz/go-dmr"
"github.com/pd0mz/go-dmr/fec"
)
// deinterleave matrix
var dm = [256]uint8{}
var debug bool
func init() {
var i uint32
for i = 0; i < 0x100; i++ {
dm[i] = uint8((i * 181) % 196)
}
debug = os.Getenv("DEBUG_DMR_BPTC") != ""
}
func dump(bits []byte) {
for row := 0; row < 13; row++ {
if row == 0 {
fmt.Printf("col # ")
for col := 0; col < 15; col++ {
fmt.Printf("%02d ", col+1)
if col == 10 {
fmt.Print("| ")
}
}
fmt.Println("")
}
if row == 9 {
fmt.Println(" ------------------------------- ------------")
}
for col := 0; col < 15; col++ {
if col == 0 {
fmt.Printf("row #%02d: ", row+1)
}
fmt.Printf(" %d ", bits[col+row*15+1])
if col == 10 {
fmt.Print("| ")
}
}
fmt.Println("")
}
}
func Decode(info, data []byte) error {
if len(info) < 196 {
return fmt.Errorf("bptc: info size %d too small, need at least 196 bits", len(info))
}
if len(data) < 12 {
return fmt.Errorf("bptc: data size %d too small, need at least 12 bytes", len(data))
}
var (
i, j, k uint32
datafr = make([]byte, 196)
extracted = make([]byte, 96)
)
// Deinterleave bits
for i = 1; i < 197; i++ {
datafr[i-1] = info[dm[i]]
}
if debug {
dump(datafr)
}
// Zero reserved bits
for i = 0; i < 3; i++ {
datafr[0*15+i] = 0
}
for i = 0; i < 15; i++ {
var codeword uint32
for j = 0; j < 13; j++ {
codeword <<= 1
codeword |= uint32(datafr[j*15+i])
}
fec.Hamming15_11_3_Correct(&codeword)
codeword &= 0x01ff
for j = 0; j < 9; j++ {
datafr[j*15+i] = byte((codeword >> (8 - j)) & 1)
}
}
for j = 0; j < 9; j++ {
var codeword uint32
for i = 0; i < 15; i++ {
codeword <<= 1
codeword |= uint32(datafr[j*15+i])
}
fec.Hamming15_11_3_Correct(&codeword)
for i = 0; i < 11; i++ {
datafr[j*15+10-i] = byte((codeword >> i) & 1)
}
}
// Extract data bits
for i, k = 3, 0; i < 11; i, k = i+1, k+1 {
extracted[k] = datafr[0*15+i]
}
for j = 1; j < 9; j++ {
for i = 0; i < 11; i, k = i+1, k+1 {
extracted[k] = datafr[j*15+i]
}
}
copy(data, dmr.BitsToBytes(extracted))
return nil
}
func Encode(data, info []byte) error {
if len(data) < 12 {
return fmt.Errorf("bptc: data size %d too small, need at least 12 bytes", len(data))
}
if len(info) < 196 {
return fmt.Errorf("bptc: info size %d too small, need at least 196 bits", len(info))
}
var (
i, j, k uint32
datafr = make([]byte, 196)
extracted = make([]byte, 96)
)
copy(extracted, dmr.BytesToBits(data))
for i = 0; i < 9; i++ {
if i == 0 {
for j = 3; j < 11; j++ {
datafr[j+1] = extracted[k]
k++
}
} else {
for j = 0; j < 11; j++ {
datafr[j+i*15+1] = extracted[k]
k++
}
}
datafr[i*15+11+1] = 8
datafr[i*15+12+1] = 8
datafr[i*15+13+1] = 8
datafr[i*15+14+1] = 8
}
// Interleave bits
for i = 1; i < 197; i++ {
info[dm[i]] = datafr[i-1]
}
if debug {
dump(info)
}
return nil
}