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
|
||||
},
|
||||
}
|
||||
// selectDeviceREPLCmd := repl.Command{
|
||||
// Name: "select",
|
||||
// Usage: "Selects a given device - pass its ID",
|
||||
// Action: func(r *repl.REPL, args []string) error {
|
||||
// // We should add this to the REPL instead
|
||||
// if len(args) < 1 {
|
||||
// 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)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
// },
|
||||
// }
|
||||
|
||||
runDeviceAPIREPLCmd := repl.Command{
|
||||
Name: "v-run",
|
||||
Usage: "runs a funcion of a device - pass its ID and function name",
|
||||
Action: func(r *repl.REPL, args []string) error {
|
||||
// We should add this to the REPL instead
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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(listDevicesREPLCmd)
|
||||
// r.RegisterCMD(selectDeviceREPLCmd)
|
||||
r.RegisterCMD(listDeviceAPIREPLCmd)
|
||||
r.RegisterCMD(runDeviceAPIREPLCmd)
|
||||
|
||||
r.Start()
|
||||
r.Close()
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
// Package helper
|
||||
package helper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
func B32(s string) [32]byte {
|
||||
var b [32]byte
|
||||
copy(b[:], s)
|
||||
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()
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return wt.Serial.Write([]byte{uint8(CmdRequestID)})
|
||||
}
|
||||
@@ -87,6 +80,7 @@ type header struct {
|
||||
}
|
||||
|
||||
func (wt *WalkieTalkie) sendPacket(data any) error {
|
||||
fmt.Println("Sending a packet...")
|
||||
// Prepare the payload
|
||||
var buf bytes.Buffer
|
||||
err := binary.Write(&buf, binary.LittleEndian, data)
|
||||
|
||||
+5
-17
@@ -65,28 +65,16 @@ func (p *PeripheralDevice) Probe() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Papers, please!
|
||||
_, err = p.WT.RequestIdentification()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 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()
|
||||
// Send the identification command
|
||||
cmd := comm.CmdRequestID
|
||||
var response pack.IdentificationPacket
|
||||
err = p.WT.SendCommand(cmd, []byte{}, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy the data
|
||||
p.Merge(&pkt)
|
||||
p.Merge(&response)
|
||||
p.ToConnectedIdling()
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package devices
|
||||
|
||||
import helper "esdi/helpers"
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
helper "esdi/helpers"
|
||||
"esdi/peripheral/types"
|
||||
)
|
||||
|
||||
const (
|
||||
newWindowCMDID = iota
|
||||
newWindowCMDID types.CommandID = iota
|
||||
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
|
||||
// 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
|
||||
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
|
||||
}
|
||||
|
||||
func (dev *Device) HasFunction(f string) *DeviceCMD {
|
||||
if cmd, ok := dev.API[f]; ok {
|
||||
return &cmd
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type DeviceCMDHeader struct {
|
||||
Payload [64]byte
|
||||
}
|
||||
@@ -34,7 +42,7 @@ type DeviceCMDPayload struct {
|
||||
// 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
|
||||
// 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 {
|
||||
Identifier types.CommandID
|
||||
@@ -44,3 +52,15 @@ type DeviceCMD struct {
|
||||
Data DeviceCMDPayload
|
||||
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 (
|
||||
"esdi/peripheral/devices"
|
||||
"esdi/peripheral/types"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
@@ -86,18 +87,59 @@ func (clerk *PeripheralDeviceClerk) ListDevices() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (clerk *PeripheralDeviceClerk) ListDeviceAPI(ID uint8) error {
|
||||
func (clerk *PeripheralDeviceClerk) getDevice(ID uint8) *devices.Device {
|
||||
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)
|
||||
}
|
||||
|
||||
for _, f := range clerk.Devices[ID].DeviceAPI.API {
|
||||
for _, f := range dev.API {
|
||||
fmt.Printf("%s\t%s\n", f.Name, f.Desc)
|
||||
}
|
||||
|
||||
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() {
|
||||
// for {
|
||||
// c.mu.RLock()
|
||||
|
||||
Reference in New Issue
Block a user