diff options
-rw-r--r-- | software/communication/data_link.go | 63 | ||||
-rw-r--r-- | software/communication/data_link_test.go | 33 | ||||
-rw-r--r-- | software/communication/interface.go | 10 |
3 files changed, 103 insertions, 3 deletions
diff --git a/software/communication/data_link.go b/software/communication/data_link.go new file mode 100644 index 0000000..d6e752d --- /dev/null +++ b/software/communication/data_link.go @@ -0,0 +1,63 @@ +package communication + +const ( + SLIP_END = 0xC0 + SLIP_ESC = 0xDB + SLIP_ESC_END = 0xDC + SLIP_ESC_ESC = 0xDD + SLIP_MAX_PAYLOAD = 1500 +) + +type dataLink struct { + rx chan []byte +} + +func newDataLink() dataLink { + dl := dataLink{} + + dl.rx = make(chan []byte) + + return dl +} + +func (dl *dataLink) start(source chan byte) { + go dl.receive(source) +} + +func (dl *dataLink) receive(source chan byte) { + for { + frame := unslip(source) + dl.rx <- frame + } +} + +func unslip(source chan byte) []byte { + escaped := false + buffer := make([]byte, 0) + + for { + octet := <-source + if escaped { + switch octet { + case SLIP_ESC_END: + buffer = append(buffer, SLIP_END) + case SLIP_ESC_ESC: + buffer = append(buffer, SLIP_ESC) + } + } else { + switch octet { + case SLIP_END: + break + case SLIP_ESC: + escaped = true + continue + default: + buffer = append(buffer, octet) + continue + } + break + } + } + + return buffer +} diff --git a/software/communication/data_link_test.go b/software/communication/data_link_test.go new file mode 100644 index 0000000..91b941d --- /dev/null +++ b/software/communication/data_link_test.go @@ -0,0 +1,33 @@ +package communication + +import ( + "reflect" + "testing" +) + +func TestUnslip(t *testing.T) { + input := []byte{ + 0xFF, 0x12, SLIP_END, + } + + bytes := make(chan byte) + frames := make(chan []byte) + + go func() { + for _, v := range input { + bytes <- v + } + }() + + go func() { + for { + frames <- unslip(bytes) + } + }() + + frame := <-frames + expected := []byte{0xFF, 0x12} + if !reflect.DeepEqual(frame, expected) { + t.Fatalf("Frame '%v' does not match expected '%v'\n", frame, expected) + } +} diff --git a/software/communication/interface.go b/software/communication/interface.go index d124a48..df089f2 100644 --- a/software/communication/interface.go +++ b/software/communication/interface.go @@ -1,11 +1,12 @@ package communication import ( - "fmt" + "log" ) type SerialInterface struct { phy physical + dl dataLink } func NewSerialInterface() (SerialInterface, error) { @@ -17,16 +18,19 @@ func NewSerialInterface() (SerialInterface, error) { return iface, err } + iface.dl = newDataLink() + return iface, nil } func (i *SerialInterface) Start() { i.phy.start() + i.dl.start(i.phy.rx) } func (i *SerialInterface) Cat() { for { - data := <-i.phy.rx - fmt.Printf("%s", string(data)) + data := <-i.dl.rx + log.Printf("RX: '%v'\n", data) } } |