Added some basic command handling for the devices
This commit is contained in:
+28
-19
@@ -62,29 +62,38 @@ func replCmdAction(cmd *cobra.Command, args []string) {
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// selectDeviceREPLCmd := repl.Command{
|
|
||||||
// Name: "select",
|
runDeviceAPIREPLCmd := repl.Command{
|
||||||
// Usage: "Selects a given device - pass its ID",
|
Name: "v-run",
|
||||||
// Action: func(r *repl.REPL, args []string) error {
|
Usage: "runs a funcion of a device - pass its ID and function name",
|
||||||
// // We should add this to the REPL instead
|
Action: func(r *repl.REPL, args []string) error {
|
||||||
// if len(args) < 1 {
|
// We should add this to the REPL instead
|
||||||
// return fmt.Errorf("requires at least on argument")
|
if len(args) < 3 {
|
||||||
// }
|
return fmt.Errorf("requires at least on argument")
|
||||||
//
|
}
|
||||||
// // First and only argument should be the ID of the device we want to use
|
|
||||||
// targetID, err := strconv.ParseInt(args[0], 10, 0)
|
// First and only argument should be the ID of the device we want to use
|
||||||
// if err != nil {
|
targetID, err := strconv.ParseInt(args[0], 10, 0)
|
||||||
// return err
|
if err != nil {
|
||||||
// }
|
return err
|
||||||
//
|
}
|
||||||
// return nil
|
|
||||||
// },
|
fnName := args[1]
|
||||||
// }
|
fnArgs := args[2:]
|
||||||
|
|
||||||
|
err = perClerk.RunDeviceFunction(uint8(targetID), fnName, fnArgs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
r.RegisterCMD(discoverDevicesREPLCmd)
|
r.RegisterCMD(discoverDevicesREPLCmd)
|
||||||
r.RegisterCMD(listDevicesREPLCmd)
|
r.RegisterCMD(listDevicesREPLCmd)
|
||||||
// r.RegisterCMD(selectDeviceREPLCmd)
|
|
||||||
r.RegisterCMD(listDeviceAPIREPLCmd)
|
r.RegisterCMD(listDeviceAPIREPLCmd)
|
||||||
|
r.RegisterCMD(runDeviceAPIREPLCmd)
|
||||||
|
|
||||||
r.Start()
|
r.Start()
|
||||||
r.Close()
|
r.Close()
|
||||||
|
|||||||
@@ -1,8 +1,23 @@
|
|||||||
// Package helper
|
// Package helper
|
||||||
package helper
|
package helper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
)
|
||||||
|
|
||||||
func B32(s string) [32]byte {
|
func B32(s string) [32]byte {
|
||||||
var b [32]byte
|
var b [32]byte
|
||||||
copy(b[:], s)
|
copy(b[:], s)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func StructToBytes(s any) ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := binary.Write(&buf, binary.LittleEndian, s)
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,13 +65,6 @@ func (wt *WalkieTalkie) TurnOff() error {
|
|||||||
return wt.Serial.Close()
|
return wt.Serial.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (wt *WalkieTalkie) SendCommand(cmd Command, payload []byte) (int, error) {
|
|
||||||
// switch cmd {
|
|
||||||
// case CmdRequestID:
|
|
||||||
// return wt.RequestIdentification(d * serial.Port)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (wt *WalkieTalkie) RequestIdentification() (int, error) {
|
func (wt *WalkieTalkie) RequestIdentification() (int, error) {
|
||||||
return wt.Serial.Write([]byte{uint8(CmdRequestID)})
|
return wt.Serial.Write([]byte{uint8(CmdRequestID)})
|
||||||
}
|
}
|
||||||
@@ -87,6 +80,7 @@ type header struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (wt *WalkieTalkie) sendPacket(data any) error {
|
func (wt *WalkieTalkie) sendPacket(data any) error {
|
||||||
|
fmt.Println("Sending a packet...")
|
||||||
// Prepare the payload
|
// Prepare the payload
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err := binary.Write(&buf, binary.LittleEndian, data)
|
err := binary.Write(&buf, binary.LittleEndian, data)
|
||||||
|
|||||||
+5
-17
@@ -65,28 +65,16 @@ func (p *PeripheralDevice) Probe() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Papers, please!
|
// Send the identification command
|
||||||
_, err = p.WT.RequestIdentification()
|
cmd := comm.CmdRequestID
|
||||||
if err != nil {
|
var response pack.IdentificationPacket
|
||||||
return err
|
err = p.WT.SendCommand(cmd, []byte{}, &response)
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the papers
|
|
||||||
var pkt pack.IdentificationPacket
|
|
||||||
err = pkt.Read(p.WT)
|
|
||||||
if err != nil {
|
|
||||||
// Throw the man in the gulag!
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acknowledge successful identification
|
|
||||||
_, err = p.WT.AknowledgeIdentification()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the data
|
// copy the data
|
||||||
p.Merge(&pkt)
|
p.Merge(&response)
|
||||||
p.ToConnectedIdling()
|
p.ToConnectedIdling()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
package devices
|
package devices
|
||||||
|
|
||||||
import helper "esdi/helpers"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
helper "esdi/helpers"
|
||||||
|
"esdi/peripheral/types"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
newWindowCMDID = iota
|
newWindowCMDID types.CommandID = iota
|
||||||
destroyWindowCMDID
|
destroyWindowCMDID
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -26,10 +32,62 @@ var CDashDisplay = Device{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func createWindow(data []byte) {
|
func createWindow(dCMD *DeviceCMD, args []string) (types.CommandID, []byte, error) {
|
||||||
// Parse the command
|
// Parse the command
|
||||||
|
// x0, y0, width, height, title # add other decorations later on
|
||||||
|
// fmt.Printf("%s command called: %+v\n", dCMD.GetName(), args)
|
||||||
|
|
||||||
|
type UIWindow struct {
|
||||||
|
X0 uint16
|
||||||
|
Y0 uint16
|
||||||
|
Width uint16
|
||||||
|
Height uint16
|
||||||
|
Title [32]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) != 5 {
|
||||||
|
return 0, []byte{}, fmt.Errorf("wrong parameters, got %d, want %d. "+
|
||||||
|
"Command asks for: x0 y0 width height title", len(args), 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
x0, err := strconv.ParseInt(args[0], 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, []byte{}, err
|
||||||
|
}
|
||||||
|
y0, err := strconv.ParseInt(args[1], 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, []byte{}, err
|
||||||
|
}
|
||||||
|
width, err := strconv.ParseInt(args[2], 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, []byte{}, err
|
||||||
|
}
|
||||||
|
height, err := strconv.ParseInt(args[3], 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data := UIWindow{
|
||||||
|
X0: uint16(x0),
|
||||||
|
Y0: uint16(y0),
|
||||||
|
Width: uint16(width),
|
||||||
|
Height: uint16(height),
|
||||||
|
Title: helper.B32(args[4]),
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmt.Printf("Data: %+v\n", data)
|
||||||
|
|
||||||
|
bytes, err := helper.StructToBytes(data)
|
||||||
|
if err != nil {
|
||||||
|
return 0, []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return dCMD.GetIdentifier(), bytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func destroyWindow(data []byte) {
|
func destroyWindow(dCMD *DeviceCMD, args []string) (types.CommandID, []byte, error) {
|
||||||
// Parse the command
|
// Parse the command
|
||||||
|
fmt.Printf("%s command called: %+v\n", dCMD.GetName(), args)
|
||||||
|
|
||||||
|
return dCMD.GetIdentifier(), []byte{}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ type Device struct {
|
|||||||
API map[string]DeviceCMD
|
API map[string]DeviceCMD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dev *Device) HasFunction(f string) *DeviceCMD {
|
||||||
|
if cmd, ok := dev.API[f]; ok {
|
||||||
|
return &cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type DeviceCMDHeader struct {
|
type DeviceCMDHeader struct {
|
||||||
Payload [64]byte
|
Payload [64]byte
|
||||||
}
|
}
|
||||||
@@ -34,7 +42,7 @@ type DeviceCMDPayload struct {
|
|||||||
// DeviceCMDFn defines the basic type for the functions the devices can have
|
// DeviceCMDFn defines the basic type for the functions the devices can have
|
||||||
// The function will receive a []byte that should be the arguments the user
|
// The function will receive a []byte that should be the arguments the user
|
||||||
// types in the REPL - or however this will be used
|
// types in the REPL - or however this will be used
|
||||||
type DeviceCMDFn func(data []byte)
|
type DeviceCMDFn func(dCMD *DeviceCMD, args []string) (types.CommandID, []byte, error)
|
||||||
|
|
||||||
type DeviceCMD struct {
|
type DeviceCMD struct {
|
||||||
Identifier types.CommandID
|
Identifier types.CommandID
|
||||||
@@ -44,3 +52,15 @@ type DeviceCMD struct {
|
|||||||
Data DeviceCMDPayload
|
Data DeviceCMDPayload
|
||||||
Fn DeviceCMDFn
|
Fn DeviceCMDFn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dCMD *DeviceCMD) GetIdentifier() types.CommandID {
|
||||||
|
return dCMD.Identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dCMD *DeviceCMD) GetName() string {
|
||||||
|
return dCMD.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dCMD *DeviceCMD) GetDesc() string {
|
||||||
|
return dCMD.Desc
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package peripheral
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"esdi/peripheral/devices"
|
"esdi/peripheral/devices"
|
||||||
|
"esdi/peripheral/types"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
@@ -86,18 +87,59 @@ func (clerk *PeripheralDeviceClerk) ListDevices() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clerk *PeripheralDeviceClerk) ListDeviceAPI(ID uint8) error {
|
func (clerk *PeripheralDeviceClerk) getDevice(ID uint8) *devices.Device {
|
||||||
if _, ok := clerk.Devices[ID]; !ok {
|
if _, ok := clerk.Devices[ID]; !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return clerk.Devices[ID].DeviceAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
func (clerk *PeripheralDeviceClerk) ListDeviceAPI(ID uint8) error {
|
||||||
|
dev := clerk.getDevice(ID)
|
||||||
|
if dev == nil {
|
||||||
return fmt.Errorf("device with ID %d not found", ID)
|
return fmt.Errorf("device with ID %d not found", ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range clerk.Devices[ID].DeviceAPI.API {
|
for _, f := range dev.API {
|
||||||
fmt.Printf("%s\t%s\n", f.Name, f.Desc)
|
fmt.Printf("%s\t%s\n", f.Name, f.Desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (clerk *PeripheralDeviceClerk) sendDeviceFn(c types.CommandID, payload []byte) error {
|
||||||
|
fmt.Println("Send command:", c)
|
||||||
|
fmt.Println("With payload:", payload)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (clerk *PeripheralDeviceClerk) RunDeviceFunction(ID uint8, f string, args []string) error {
|
||||||
|
dev := clerk.getDevice(ID)
|
||||||
|
if dev == nil {
|
||||||
|
return fmt.Errorf("device with ID %d not found", ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := dev.HasFunction(f)
|
||||||
|
if cmd == nil {
|
||||||
|
return fmt.Errorf("requested function %s doesnt exist", f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the function
|
||||||
|
command, payload, err := cmd.Fn(cmd, args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = clerk.sendDeviceFn(command, payload)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// func (c *PeripheralDeviceClerk) clerkBackgroundJob() {
|
// func (c *PeripheralDeviceClerk) clerkBackgroundJob() {
|
||||||
// for {
|
// for {
|
||||||
// c.mu.RLock()
|
// c.mu.RLock()
|
||||||
|
|||||||
Reference in New Issue
Block a user