diff --git a/peripheral/communication/communication.go b/peripheral/communication/communication.go index c59a6c8..bf6e15e 100644 --- a/peripheral/communication/communication.go +++ b/peripheral/communication/communication.go @@ -1,14 +1,8 @@ // Package communication will handle the data transmission with the peripheral -// device package communication import ( - "github.com/tarm/serial" -) - -const ( - StartOfText = 0x02 - EndOfText = 0x03 + "esdi/peripheral/types" ) type CommState uint8 @@ -18,16 +12,9 @@ const ( CommOff ) -type Command uint8 - const ( - CmdRequestID Command = iota + CmdRequestID types.Command = iota CmdAckID CmdCreateScreen CmdCreateWindow ) - -type DataReceiver interface { - Read(dev *serial.Port) error - Validate(data []byte) bool -} diff --git a/peripheral/communication/constvar/constvar.go.go b/peripheral/communication/constvar/constvar.go.go new file mode 100644 index 0000000..8e4a8b7 --- /dev/null +++ b/peripheral/communication/constvar/constvar.go.go @@ -0,0 +1,8 @@ +// Package constvar will hold constants and vars for communication +package constvar + +const ( + StartOfText = 0x02 + EndOfText = 0x03 + ACK = 0x06 +) diff --git a/peripheral/communication/packets/ack.go b/peripheral/communication/packets/ack.go new file mode 100644 index 0000000..fba4747 --- /dev/null +++ b/peripheral/communication/packets/ack.go @@ -0,0 +1,22 @@ +package packets + +import "esdi/peripheral/communication/constvar" + +type AckPacket struct { + StartMarker byte + AckByte byte + EndMarker byte +} + +func (pkt *AckPacket) Validate() bool { + if pkt.StartMarker != constvar.StartOfText || + pkt.EndMarker != constvar.EndOfText { + return false + } + + if pkt.AckByte != constvar.ACK { + return false + } + + return true +} diff --git a/peripheral/identificationPacket.go b/peripheral/communication/packets/identification.go similarity index 60% rename from peripheral/identificationPacket.go rename to peripheral/communication/packets/identification.go index 712cbb8..7c27ffa 100644 --- a/peripheral/identificationPacket.go +++ b/peripheral/communication/packets/identification.go @@ -1,8 +1,7 @@ -package peripheral +package packets import ( - "encoding/binary" - comm "esdi/peripheral/communication" + "esdi/peripheral/communication/constvar" "fmt" ) @@ -14,19 +13,6 @@ type IdentificationPacket struct { EndMarker byte } -func (pkt *IdentificationPacket) Read(wt *comm.WalkieTalkie) error { - err := wt.ReadFramedData(binary.Size(IdentificationPacket{}), pkt) - if err != nil { - return err - } - - if !pkt.Validate() { - return fmt.Errorf("invalid data") - } - - return nil -} - func (pkt *IdentificationPacket) Validate() bool { fmt.Println("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓") fmt.Println(pkt.StartMarker) @@ -38,8 +24,8 @@ func (pkt *IdentificationPacket) Validate() bool { // Change this to return an error and add a validation against available // device ids - if pkt.StartMarker != comm.StartOfText || - pkt.EndMarker != comm.EndOfText { + if pkt.StartMarker != constvar.StartOfText || + pkt.EndMarker != constvar.EndOfText { return false } diff --git a/peripheral/packets.go b/peripheral/communication/packets/packets.go similarity index 73% rename from peripheral/packets.go rename to peripheral/communication/packets/packets.go index 073cff8..606ff56 100644 --- a/peripheral/packets.go +++ b/peripheral/communication/packets/packets.go @@ -1,4 +1,9 @@ -package peripheral +// Package packets will define the available packets we have +package packets + +type Packet interface { + Validate() bool +} type PacketType uint8 diff --git a/peripheral/communication/walkieTalkie.go b/peripheral/communication/walkieTalkie.go index 59598ae..aa6656b 100644 --- a/peripheral/communication/walkieTalkie.go +++ b/peripheral/communication/walkieTalkie.go @@ -6,6 +6,10 @@ import ( "fmt" "io" + "esdi/peripheral/communication/constvar" + "esdi/peripheral/communication/packets" + "esdi/peripheral/types" + "github.com/tarm/serial" ) @@ -26,7 +30,7 @@ func (wt *WalkieTalkie) ReadFramedData(size int, packet any) error { return err } - if b[0] == StartOfText { + if b[0] == constvar.StartOfText { buf[0] = b[0] break } @@ -76,6 +80,96 @@ func (wt *WalkieTalkie) AknowledgeIdentification() (int, error) { return wt.Serial.Write([]byte{uint8(CmdAckID)}) } -func (wt *WalkieTalkie) SendCommand(payload []byte) (int, error) { - return wt.Serial.Write(payload) +type header struct { + StartByte uint8 + CMD types.Command + EndByte uint8 +} + +func (wt *WalkieTalkie) sendPacket(data any) error { + // Prepare the payload + var buf bytes.Buffer + err := binary.Write(&buf, binary.LittleEndian, data) + if err != nil { + return err + } + + // Send the payload + _, err = wt.Serial.Write(buf.Bytes()) + if err != nil { + return err + } + + return nil +} + +func (wt *WalkieTalkie) readPacket(resp packets.Packet) error { + size := binary.Size(resp) + if size < 0 { + return fmt.Errorf("invalid packet size") + } + + err := wt.ReadFramedData(size, resp) + if err != nil { + return err + } + + if !resp.Validate() { + return fmt.Errorf("badly formatted response") + } + + return nil +} + +func (wt *WalkieTalkie) sendHeader(h *header) error { + err := wt.sendPacket(h) + if err != nil { + return err + } + + var ack packets.AckPacket + err = wt.readPacket(&ack) + if err != nil { + return err + } + + return nil +} + +func (wt *WalkieTalkie) sendBody(payload any, resp packets.Packet) error { + err := wt.sendPacket(payload) + if err != nil { + return err + } + + err = wt.readPacket(resp) + if err != nil { + return err + } + + return nil +} + +func (wt *WalkieTalkie) SendCommand(cmd types.Command, payload any, + responseBody packets.Packet) error { + // Prepare the header + header := header{ + StartByte: constvar.StartOfText, + CMD: cmd, + EndByte: constvar.EndOfText, + } + + // Send the header + err := wt.sendHeader(&header) + if err != nil { + return err + } + + // Send the body + err = wt.sendBody(payload, responseBody) + if err != nil { + return err + } + + return nil } diff --git a/peripheral/device.go b/peripheral/device.go index c615b97..f6aae18 100644 --- a/peripheral/device.go +++ b/peripheral/device.go @@ -2,6 +2,7 @@ package peripheral import ( comm "esdi/peripheral/communication" + pack "esdi/peripheral/communication/packets" "esdi/peripheral/devices" "time" @@ -71,7 +72,7 @@ func (p *PeripheralDevice) Probe() error { } // Verify the papers - var pkt IdentificationPacket + var pkt pack.IdentificationPacket err = pkt.Read(p.WT) if err != nil { // Throw the man in the gulag! @@ -96,7 +97,7 @@ func (p *PeripheralDevice) ToConnectedIdling() { p.CommState = comm.CommIdle } -func (p *PeripheralDevice) Merge(packet *IdentificationPacket) { +func (p *PeripheralDevice) Merge(packet *pack.IdentificationPacket) { p.Name = string(packet.Name[:]) p.ID = packet.DeviceID } diff --git a/peripheral/types/types.go b/peripheral/types/types.go index 83b5c42..151147a 100644 --- a/peripheral/types/types.go +++ b/peripheral/types/types.go @@ -1,4 +1,7 @@ // Package types defines the types necessary to handle peripherals package types -type CommandID uint8 +type ( + CommandID uint8 + Command uint8 +)