Skip to content

Commit

Permalink
Checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
tehmaze committed Dec 17, 2015
1 parent caa5951 commit cca6817
Show file tree
Hide file tree
Showing 13 changed files with 722 additions and 167 deletions.
3 changes: 2 additions & 1 deletion bits.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package dmr

// Various sizes of information chunks.
const (
PayloadBits = 98 + 10 + 48 + 10 + 98
PayloadSize = 33
InfoHalfBits = 98
InfoBits = 2 * InfoHalfBits
InfoSize = 12 // After BPTC(196, 96) decoding
SlotTypeHalfBits = 10
SlotTypeBits = 2 * SlotTypeHalfBits
SignalBits = 48
Expand Down
6 changes: 3 additions & 3 deletions bptc/bptc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package bptc
import (
"fmt"

"github.com/tehmaze/go-dmr"
"github.com/tehmaze/go-dmr/fec"
"github.com/pd0mz/go-dmr"
"github.com/pd0mz/go-dmr/fec"
)

func Process(info []byte, payload []byte) error {
func Decode(info []byte, payload []byte) error {
if len(info) < 196 {
return fmt.Errorf("bptc: info size %d too small, need at least 196 bits", len(info))
}
Expand Down
206 changes: 206 additions & 0 deletions controlblock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package dmr

import (
"errors"
"fmt"
)

// Control Block Options
const (
CBSKOOutboundActivation = B00111000
CBSKOUnitToUnitVoiceServiceRequest = B00000100
CBSKOUnitToUnitVoiceServiceAnswerResponse = B00000101
CBSKONegativeAcknowledgeResponse = B00100100
CBSKOPreamble = B00111101
)

type ControlBlock struct {
Last bool
CBSKO uint8
SrcID, DstID uint32
Data ControlBlockData
}

type ControlBlockData interface {
Write([]byte) error
Parse([]byte) error
}

type OutboundActivation struct{}

func (d *OutboundActivation) Parse(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
return nil
}

func (d *OutboundActivation) Write(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
data[0] |= B00111000
return nil
}

type UnitToUnitVoiceServiceRequest struct {
Options uint8
}

func (d *UnitToUnitVoiceServiceRequest) Parse(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
d.Options = data[2]
return nil
}

func (d *UnitToUnitVoiceServiceRequest) Write(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
data[0] |= B00000100
data[2] = d.Options
return nil
}

var _ (ControlBlockData) = (*UnitToUnitVoiceServiceRequest)(nil)

type UnitToUnitVoiceServiceAnswerResponse struct {
Options uint8
Response uint8
}

func (d *UnitToUnitVoiceServiceAnswerResponse) Parse(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
d.Options = data[2]
d.Response = data[3]
return nil
}

func (d *UnitToUnitVoiceServiceAnswerResponse) Write(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
data[0] |= B00000101
data[2] = d.Options
data[3] = d.Response
return nil
}

var _ (ControlBlockData) = (*UnitToUnitVoiceServiceAnswerResponse)(nil)

type NegativeAcknowledgeResponse struct {
SourceType bool
ServiceType uint8
Reason uint8
}

func (d *NegativeAcknowledgeResponse) Parse(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
d.SourceType = (data[2] & B01000000) > 0
d.ServiceType = (data[2] & B00011111)
d.Reason = data[3]
return nil
}

func (d *NegativeAcknowledgeResponse) Write(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
data[0] |= B00100110
data[2] = d.ServiceType
if d.SourceType {
data[2] |= B01000000
}
data[3] = d.Reason
return nil
}

var _ (ControlBlockData) = (*NegativeAcknowledgeResponse)(nil)

type ControlBlockPreamble struct {
DataFollows bool
DstIsGroup bool
Blocks uint8
}

func (d *ControlBlockPreamble) Parse(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
d.DataFollows = (data[2] & B10000000) > 0
d.DstIsGroup = (data[2] & B01000000) > 0
d.Blocks = data[3]
return nil
}

func (d *ControlBlockPreamble) Write(data []byte) error {
if len(data) != InfoSize {
return fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}
data[0] |= B00100110
if d.DataFollows {
data[2] |= B10000000
}
if d.DstIsGroup {
data[2] |= B01000000
}
data[3] = d.Blocks
return nil
}

var _ (ControlBlockData) = (*ControlBlockPreamble)(nil)

func ParseControlBlock(data []byte) (*ControlBlock, error) {
if len(data) != InfoSize {
return nil, fmt.Errorf("dmr: expected %d info bytes, got %d", InfoSize, len(data))
}

// Calculate CRC16

// Check packet
if data[0]&B01000000 > 0 {
return nil, errors.New("dmr: CBSK protect flag is set")
}
if data[1] != 0 {
return nil, errors.New("dmr: CBSK feature set ID is set")
}

cb := &ControlBlock{
Last: (data[0] & B10000000) > 0,
CBSKO: (data[0] & B00111111),
DstID: uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6]),
SrcID: uint32(data[7])<<16 | uint32(data[8])<<8 | uint32(data[9]),
}

switch cb.CBSKO {
case CBSKOOutboundActivation:
cb.Data = &OutboundActivation{}
break
case CBSKOUnitToUnitVoiceServiceRequest:
cb.Data = &UnitToUnitVoiceServiceRequest{}
break
case CBSKOUnitToUnitVoiceServiceAnswerResponse:
cb.Data = &UnitToUnitVoiceServiceAnswerResponse{}
break
case CBSKONegativeAcknowledgeResponse:
cb.Data = &NegativeAcknowledgeResponse{}
break
case CBSKOPreamble:
cb.Data = &ControlBlockPreamble{}
break
default:
return nil, fmt.Errorf("dmr: unknown CBSKO %#02x (%#06b)", cb.CBSKO, cb.CBSKO)
}

if err := cb.Data.Parse(data); err != nil {
return nil, err
}

return cb, nil
}
9 changes: 9 additions & 0 deletions data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package dmr

type DataBlock struct {
Serial uint8
CRC uint16
OK bool
Data [24]byte
Length uint8
}
19 changes: 0 additions & 19 deletions dataheader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,6 @@ package dmr

import "fmt"

var DataTypeName = [16]string{
"PI Header", // 0000
"VOICE Header:", // 0001
"TLC:", // 0010
"CSBK:", // 0011
"MBC Header:", // 0100
"MBC:", // 0101
"DATA Header:", // 0110
"RATE 1/2 DATA:", // 0111
"RATE 3/4 DATA:", // 1000
"Slot idle", // 1001
"Rate 1 DATA", // 1010
"Unknown/Bad (11)", // 1011
"Unknown/Bad (12)", // 1100
"Unknown/Bad (13)", // 1101
"Unknown/Bad (14)", // 1110
"Unknown/Bad (15)", // 1111
}

// Data Header Packet Format
const (
PacketFormatUDT uint8 = iota // 0b0000
Expand Down
Loading

0 comments on commit cca6817

Please sign in to comment.