Capture and Simulation Support

Enable Builds using Simulation only (not including gousb thus CGO)
This commit is contained in:
Justin Hammond 2021-10-02 00:59:57 +08:00
parent 5ebfc921de
commit 93a6a2d26e
12 changed files with 468 additions and 233 deletions

View file

@ -1,4 +1,4 @@
/*
/*
MIT License
Copyright (c) 2021 Justin Hammond
@ -26,26 +26,55 @@ package main
import (
"context"
"log"
"flag"
"fmt"
"os"
"time"
"github.com/Fishwaldo/go-dcdc200"
"github.com/Fishwaldo/go-dcdc200/internal/sim"
"github.com/Fishwaldo/go-logadapter/loggers/std"
)
func main() {
var simulation = flag.Bool("s", false, "Enable Simulation Mode")
var capture = flag.Bool("c", false, "Enable Packet Capture")
var help = flag.Bool("h", false, "Help")
flag.Parse()
if *help {
flag.PrintDefaults()
os.Exit(0)
}
dc := dcdcusb.DcDcUSB{}
dc.Init()
if *simulation {
if err := sim.SetCaptureFile("dcdcusb.txt"); err != nil {
fmt.Printf("Can't open Capture File dcdcusb.txt: %s\n", err)
os.Exit(-1)
}
}
dc.Init(stdlogger.DefaultLogger(), *simulation)
if *capture {
if *simulation {
fmt.Printf("Can't Enable Capture in Simulation Mode\n")
os.Exit(-1)
}
dc.SetCapture(*capture)
}
if ok, err := dc.Scan(); !ok {
log.Fatalf("Scan Failed: %v", err)
return
fmt.Printf("Scan Failed: %v\n", err)
os.Exit(-1)
}
defer dc.Close()
for i := 0; i < 100; i++ {
for i := 0; i < 1000000; i++ {
ctx, cancel := context.WithTimeout(context.Background(), (1 * time.Second))
dc.GetAllParam(ctx)
cancel()
time.Sleep(1 * time.Second)
}
dc.Close()
os.Exit(0)
}

View file

@ -1,4 +1,4 @@
/*
/*
MIT License
Copyright (c) 2021 Justin Hammond
@ -28,22 +28,29 @@ import (
"context"
"errors"
"fmt"
"sync"
"os"
"time"
"github.com/Fishwaldo/go-dcdc200/internal"
"github.com/Fishwaldo/go-dcdc200/internal/realusb"
"github.com/Fishwaldo/go-dcdc200/internal/sim"
"github.com/Fishwaldo/go-logadapter"
"github.com/Fishwaldo/go-logadapter/loggers/std"
"github.com/google/gousb"
)
type usbifI interface {
SetUSBDebug(level int)
Scan() (bool, error)
Close()
GetAllParam(ctx context.Context) ([]byte, int, error)
}
// Main Structure for the DCDCUSB Communications
type DcDcUSB struct {
ctx *gousb.Context
dev *gousb.Device
intf *gousb.Interface
done func()
log logadapter.Logger
initOnce sync.Once
connected bool
log logadapter.Logger
connected bool
captureData bool
simulation bool
usbif usbifI
}
// Represents the Settings for Off and Hardoff Delays when power is lost
@ -51,190 +58,143 @@ type TimerConfigt struct {
// After Ignition Lost, this the time waiting till we toggle the Power Switch I/F
OffDelay time.Duration `json:"off_delay"`
// After the Power Switch I/F is toggled, this is the delay before we cut power
HardOff time.Duration `json:"hard_off"`
HardOff time.Duration `json:"hard_off"`
}
// Status of Various Peripherals
type Peripheralst struct {
// ??
OutSwVin bool `json:"out_sw_vin"`
OutSwVin bool `json:"out_sw_vin"`
// ??
OutPsw bool `json:"out_psw"`
OutPsw bool `json:"out_psw"`
// ??
OutStartOutput bool `json:"out_start_output"`
// Status of the Onboard Led
OutLed bool `json:"out_led"`
// If the VOut is within range.
OutLed bool `json:"out_led"`
// If the VOut is within range.
InVoutGood bool `json:"in_vout_good"`
}
// Overall Status of the DCDCUSB Power Supply
type Params struct {
// What the Vout Setting is configured for
VoutSet float32 `json:"vout_set"`
VoutSet float32 `json:"vout_set"`
// What Voltage the Config Jumpers are set for VOut
VoutConfig float32 `json:"vout_config"`
VoutConfig float32 `json:"vout_config"`
// The Input Voltage
Vin float32 `json:"vin"`
Vin float32 `json:"vin"`
// The Ignition Voltage
Vign float32 `json:"vign"`
Vign float32 `json:"vign"`
// What the Actual VOut Voltage is
VoutActual float32 `json:"vout_actual"`
VoutActual float32 `json:"vout_actual"`
// Status of Various Peripherals
Peripherals Peripheralst `json:"peripherals"`
Peripherals Peripheralst `json:"peripherals"`
// ?? (Not Output Enabled?)
Output bool `json:"output"`
Output bool `json:"output"`
// ??
AuxVIn bool `json:"aux_v_in"`
AuxVIn bool `json:"aux_v_in"`
// Firmware Version?
Version string `json:"version"`
Version string `json:"version"`
// State of the Power Supply
State DcdcStatet `json:"state"`
State DcdcStatet `json:"state"`
// Config Registers (unknown)
CfgRegisters byte `json:"cfg_registers"`
CfgRegisters byte `json:"cfg_registers"`
// Voltage Flags (Unknown)
VoltFlags byte `json:"volt_flags"`
VoltFlags byte `json:"volt_flags"`
// Timer Flags (Unknown)
TimerFlags byte `json:"timer_flags"`
TimerFlags byte `json:"timer_flags"`
// The configured countdown times for the Timer upon Power Loss
TimerConfig TimerConfigt `json:"timer_config"`
// Current Power Loss Debounce Timer
TimerWait time.Duration `json:"timer_wait"`
TimerWait time.Duration `json:"timer_wait"`
// Current VOut Countdown Timer
TimerVOut time.Duration `json:"timer_v_out"`
TimerVOut time.Duration `json:"timer_v_out"`
// Current VAux Countdown timer
TimerVAux time.Duration `json:"timer_v_aux"`
TimerVAux time.Duration `json:"timer_v_aux"`
// Current Power Switch Toggle Count Down Timer
TimerPRWSW time.Duration `json:"timer_prwsw"`
TimerPRWSW time.Duration `json:"timer_prwsw"`
// Current Soft Off Countdown Timer
TimerSoftOff time.Duration `json:"timer_soft_off"`
TimerSoftOff time.Duration `json:"timer_soft_off"`
// Current Hard Off Countdown Timer
TimerHardOff time.Duration `json:"timer_hard_off"`
// Current Script Position
ScriptPointer byte `json:"script_pointer"`
TimerHardOff time.Duration `json:"timer_hard_off"`
// Current Script Position
ScriptPointer byte `json:"script_pointer"`
// Current Operating Mode
Mode DcdcModet `json:"mode"`
}
// Initialize the DCDCUSB Communications. Should be first function called before any other methods are called
func (dc *DcDcUSB) Init() {
dc.initOnce.Do(func() {
if dc.log == nil {
templogger := stdlogger.DefaultLogger()
templogger.Log.SetPrefix("DCDCUSB")
dc.log = templogger
}
})
dc.connected = false
dc.ctx = gousb.NewContext()
Mode DcdcModet `json:"mode"`
}
// Set a Custom Logger based on https://github.com/Fishwaldo/go-logadapter
// If not set, then the Library will use the Std Library Logger
func (dc *DcDcUSB) SetLogger(log logadapter.Logger) {
// Initialize the DCDCUSB Communications. Should be first function called before any other methods are called
// Pass a logadapter.Logger as the logger for this package and set simulation to true if you wish to reply a Captured Session instead of
// live data.
func (dc *DcDcUSB) Init(log logadapter.Logger, simulation bool) {
dc.log = log
dc.connected = false
dc.simulation = simulation
if !simulation {
dc.usbif = realusb.Init(dc.log)
} else {
dc.usbif = sim.Init(dc.log)
}
}
// Capture Data from the Power Supply and save it to dcdcusb.txt for replay via the simulator later
func (dc *DcDcUSB) SetCapture(enabled bool) {
dc.captureData = true
}
// Set the debug level for the GoUSB Library
func (dc *DcDcUSB) SetUSBDebug(level int) {
if dc.ctx != nil {
dc.ctx.Debug(level)
}
dc.usbif.SetUSBDebug(level)
}
// Returns if we are connected to the Power Supply
func (dc *DcDcUSB) IsConnected() (bool) {
func (dc *DcDcUSB) IsConnected() bool {
return dc.connected
}
// Scan for a DCDCUSB connection, returns true if found, or false (and optional error) if there
// was a failure setting up communications with it.
// was a failure setting up communications with it.
func (dc *DcDcUSB) Scan() (bool, error) {
var err error
dc.dev, err = dc.ctx.OpenDeviceWithVIDPID(dcdc200_vid, dcdc200_pid)
if err != nil {
dc.log.Warn("Could Not Open Device: %v", err)
dc.Close()
return false, err
}
if dc.dev == nil {
dc.log.Warn("Can't Find Device")
dc.Close()
return false, nil
}
err = dc.dev.SetAutoDetach(true)
if err != nil {
dc.log.Error("%s.SetAutoDetach(true): %v", dc.dev, err)
}
confignum, _ := dc.dev.ActiveConfigNum()
dc.log.Trace("Device Config: %s %d", dc.dev.String(), confignum)
// desc, _ := dc.dev.GetStringDescriptor(1)
// manu, _ := dc.dev.Manufacturer()
// prod, _ := dc.dev.Product()
// serial, _ := dc.dev.SerialNumber()
dc.intf, dc.done, err = dc.dev.DefaultInterface()
if err != nil {
dc.log.Error("%s.Interface(): %v", dc.dev, err)
dc.Close()
return false, err
}
dc.log.Trace("Interface: %s", dc.intf.String())
dc.log = dc.log.With("Device", dc.intf.String())
dc.connected = true
return true, nil
dc.connected, err = dc.usbif.Scan()
return dc.connected, err
}
func (dc *DcDcUSB) Close() {
if dc.intf != nil {
dc.done()
dc.intf.Close()
}
if dc.dev != nil {
dc.dev.Close()
}
if dc.ctx != nil {
dc.ctx.Close()
}
dc.connected = false;
dc.usbif.Close()
dc.connected = false
}
// Gets All current Params from the DCDCUSB power Supply.
// Gets All current Params from the DCDCUSB power Supply.
// Set a Timeout/Deadline Context to cancel slow calls
func (dc *DcDcUSB) GetAllParam(ctx context.Context) (Params, error) {
if dc.intf == nil {
dc.log.Warn("Interface Not Opened")
return Params{}, fmt.Errorf("Interface Not Opened")
}
outp, err := dc.intf.OutEndpoint(0x01)
recv, len, err := dc.usbif.GetAllParam(ctx)
if err != nil {
dc.log.Warn("Can't Get OutEndPoint: %s", err)
dc.log.Warn("GetAllParams Call Failed: %s", err)
return Params{}, err
}
//log.Printf("OutEndpoint: %v", outp)
var send = make([]byte, 24)
send[0] = cmdGetAllValues
//send = append(send, 0)
//log.Printf("About to Send %v", send)
len, err := outp.WriteContext(ctx, send)
if err != nil {
dc.log.Warn("Cant Send GetAllValues Command: %s (%v) - %d", err, send, len)
return Params{}, err
if len != 24 {
dc.log.Warn("Got Short Read From USB")
return Params{}, fmt.Errorf("got Short Read from USB")
}
//log.Printf("Sent %d Bytes", len)
inp, err := dc.intf.InEndpoint(0x81)
if err != nil {
dc.log.Warn("Can't Get OutPoint: %s", err)
return Params{}, err
}
//log.Printf("InEndpoint: %v", inp)
var recv = make([]byte, 24)
len, err = inp.ReadContext(ctx, recv)
if err != nil {
dc.log.Warn("Can't Read GetAllValues Command: %s", err)
return Params{}, err
if dc.captureData {
if dc.simulation {
dc.log.Warn("Running in Simulation Mode, Can't Capture")
} else {
f, err := os.OpenFile("dcdcusb.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
dc.log.Fatal("Can't open File for Capture: %s", err)
}
if _, err := f.Write(recv); err != nil {
dc.log.Fatal("Can't write Text to File: %s", err)
}
f.Close()
}
}
//log.Printf("Got %d Bytes", len)
dc.log.Trace("Got %v", recv)
params, err := dc.parseAllValues(recv, len)
params, err := dc.parseAllValues(recv)
return params, err
}
@ -245,9 +205,9 @@ func (dc *DcDcUSB) GetAllParam(ctx context.Context) (Params, error) {
// 2021/09/20 16:12:54 Got [130 133 8 76 0 44 25 133 205 251 1 0 0 0 0 0 0 0 0 0 0 0 0 167]
// 2021/09/20 16:12:56 Got [130 133 16 76 0 44 27 133 205 247 1 0 0 0 0 0 0 0 0 0 0 0 59 167]
// 2021/09/20 16:13:54 Got [130 133 16 76 0 44 9 133 205 247 1 0 0 0 0 0 0 0 0 0 0 0 0 167]
func (dc *DcDcUSB) parseAllValues(buf []byte, len int) (Params, error) {
func (dc *DcDcUSB) parseAllValues(buf []byte) (Params, error) {
switch buf[0] {
case cmdRecvAllValues:
case internal.CmdRecvAllValues:
param := Params{}
param.Mode = dc.modeToConst((buf[1] >> 6) & 0x7)
param.VoutConfig = dc.voutConfigtoFloat((buf[1] >> 2) & 0x07)
@ -351,8 +311,8 @@ func (dc DcDcUSB) stateToConst(state byte) DcdcStatet {
func (dc DcDcUSB) peripheralsState(state byte) Peripheralst {
p := Peripheralst{
InVoutGood: ((state & 0x01) != 0),
OutLed: ((state & 0x02) != 0),
OutPsw: ((state & 0x04) != 0),
OutLed: ((state & 0x02) != 0),
OutPsw: ((state & 0x04) != 0),
OutStartOutput: ((state & 0x08) != 0),
OutSwVin: ((state & 0x10) != 0),
}

View file

@ -27,13 +27,14 @@ package dcdcusb
import (
"testing"
"time"
"github.com/Fishwaldo/go-logadapter/loggers/std"
)
func TestParseAllValues(t *testing.T) {
var test1 = []byte{130, 133, 7, 76, 75, 43, 27, 133, 215, 251, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 68, 0, 0, 167}
dc := DcDcUSB{}
dc.Init()
result, err := dc.parseAllValues(test1, 24)
dc.Init(stdlogger.DefaultLogger(), false)
result, err := dc.parseAllValues(test1)
if err != nil {
t.Fatalf("Error Returned from parseAllValues: %v", err)
}
@ -108,8 +109,8 @@ func TestParseAllValues(t *testing.T) {
func TestParseAllValues2(t *testing.T) {
var test1 = []byte{130, 133, 8, 76, 0, 43, 27, 133, 205, 251, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 127, 0, 0, 167}
dc := DcDcUSB{}
dc.Init()
result, err := dc.parseAllValues(test1, 24)
dc.Init(stdlogger.DefaultLogger(), false)
result, err := dc.parseAllValues(test1)
if err != nil {
t.Fatalf("Error Returned from parseAllValues: %v", err)
}
@ -184,8 +185,8 @@ func TestParseAllValues2(t *testing.T) {
func TestParseAllValues3(t *testing.T) {
var test1 = []byte{130, 133, 8, 76, 0, 44, 25, 133, 205, 251, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167}
dc := DcDcUSB{}
dc.Init()
result, err := dc.parseAllValues(test1, 24)
dc.Init(stdlogger.DefaultLogger(), false)
result, err := dc.parseAllValues(test1)
if err != nil {
t.Fatalf("Error Returned from parseAllValues: %v", err)
}
@ -259,8 +260,8 @@ func TestParseAllValues3(t *testing.T) {
func TestParseAllValues4(t *testing.T) {
var test1 = []byte{130, 133, 16, 76, 0, 44, 27, 133, 205, 247, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 167}
dc := DcDcUSB{}
dc.Init()
result, err := dc.parseAllValues(test1, 24)
dc.Init(stdlogger.DefaultLogger(),false)
result, err := dc.parseAllValues(test1)
if err != nil {
t.Fatalf("Error Returned from parseAllValues: %v", err)
}
@ -335,8 +336,8 @@ func TestParseAllValues4(t *testing.T) {
func TestParseAllValues5(t *testing.T) {
var test1 = []byte{130, 133, 16, 76, 0, 44, 9, 133, 205, 247, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167}
dc := DcDcUSB{}
dc.Init()
result, err := dc.parseAllValues(test1, 24)
dc.Init(stdlogger.DefaultLogger(), false)
result, err := dc.parseAllValues(test1)
if err != nil {
t.Fatalf("Error Returned from parseAllValues: %v", err)
}

View file

@ -6,11 +6,12 @@ import (
"time"
"github.com/Fishwaldo/go-dcdc200"
"github.com/Fishwaldo/go-logadapter/loggers/std"
)
func Example() {
dc := dcdcusb.DcDcUSB{}
dc.Init()
dc.Init(stdlogger.DefaultLogger(), false)
if ok, err := dc.Scan(); !ok {
log.Fatalf("Scan Failed: %v", err)
return

View file

@ -24,89 +24,9 @@ SOFTWARE.
package dcdcusb
const (
dcdc200_vid = 0x04d8
dcdc200_pid = 0xd003
)
const (
statusOK = 0x00
statusErase = 0x01
statusWrite = 0x02
statusRead = 0x03
statusError = 0xFF
)
const (
cmdGetAllValues = 0x81
cmdRecvAllValues = 0x82
cmdOut = 0xB1
cmdIn = 0xB2
cmdReadOut = 0xA1
cmdReadIn = 0xA2
cmdWriteOut = 0xA3
cmdWriteIn = 0xA4
cmdErase = 0xA5
)
const (
msgInternal = 0xFF
msgInternalDisconnected = 0x01
)
const (
cmdSetAuxWin = 0x01
cmdSetPwSwitch = 0x02
cmdSetOutput = 0x03
cmdWriteVout = 0x06
cmdReadVout = 0x07
cmdIncVout = 0x0C
cmdDecVout = 0x0D
cmdLoadDefaults = 0x0E
cmdScriptStart = 0x10
cmdScriptStop = 0x11
cmdSleep = 0x12
cmdReadRegulatorStep = 0x13
)
const (
typeCodeMemory = 0x00
typeEepromExternal = 0x01
typeEepromInternal = 0x02
typeCodeSplash = 0x03
)
const (
flashReportEraseMemory = 0xF2 /* AddressLo : AddressHi : AddressUp (anywhere inside the 64 byte-block to be erased) */
flashReportReadMemory = 0xF3 /* AddressLo : AddressHi : AddressUp : Data Length (1...32) */
flashReportWriteMemory = 0xF4 /* AddressLo : AddressHi : AddressUp : Data Length (1...32) : Data.... */
keyBdReportEraseMemory = 0xB2 /* same as F2 but in keyboard mode */
keybdReportReadMemory = 0xB3 /* same as F3 but in keyboard mode */
keybdReportWriteMemory = 0xB4 /* same as F4 but in keyboard mode */
keybdReportMemory = 0x41 /* response to b3,b4 */
)
const (
inReportExtEEData = 0x31
outReportExtEERead = 0xA1
outReportExtEEWrite = 0xA2
inReportIntEEData = 0x32
outReportIntEERead = 0xA3
outReportIntEEWrite = 0xA4
)
/* MEASUREMENT CONSTANTS */
const (
ct_RW = 75
ct_R1 = 49900
ct_R2 = 1500
ct_RP = 10000
)
const check_char = 0xAA /* used for line/write check */
const max_message_cnt = 64
//go:generate stringer -type=DcdcModet
type DcdcModet int

5
doc.go
View file

@ -30,5 +30,10 @@ it depends upon GoUSB which in turn depends upon the libusb C library, thus CGO
Please see the GoUSB pages for hints on compiling for platforms other than linux
Building
Compile with the tag nogousb to disable compiling with USB Support. Then the only option available
is a Simulator Mode that replays a previously captured session.
*/
package dcdcusb

80
internal/definitions.go Normal file
View file

@ -0,0 +1,80 @@
package internal
const (
statusOK = 0x00
statusErase = 0x01
statusWrite = 0x02
statusRead = 0x03
statusError = 0xFF
)
const (
CmdGetAllValues = 0x81
CmdRecvAllValues = 0x82
CmdOut = 0xB1
CmdIn = 0xB2
CmdReadOut = 0xA1
CmdReadIn = 0xA2
CmdWriteOut = 0xA3
CmdWriteIn = 0xA4
CmdErase = 0xA5
)
const (
msgInternal = 0xFF
msgInternalDisconnected = 0x01
)
const (
cmdSetAuxWin = 0x01
cmdSetPwSwitch = 0x02
cmdSetOutput = 0x03
cmdWriteVout = 0x06
cmdReadVout = 0x07
cmdIncVout = 0x0C
cmdDecVout = 0x0D
cmdLoadDefaults = 0x0E
cmdScriptStart = 0x10
cmdScriptStop = 0x11
cmdSleep = 0x12
cmdReadRegulatorStep = 0x13
)
const (
typeCodeMemory = 0x00
typeEepromExternal = 0x01
typeEepromInternal = 0x02
typeCodeSplash = 0x03
)
const (
flashReportEraseMemory = 0xF2 /* AddressLo : AddressHi : AddressUp (anywhere inside the 64 byte-block to be erased) */
flashReportReadMemory = 0xF3 /* AddressLo : AddressHi : AddressUp : Data Length (1...32) */
flashReportWriteMemory = 0xF4 /* AddressLo : AddressHi : AddressUp : Data Length (1...32) : Data.... */
keyBdReportEraseMemory = 0xB2 /* same as F2 but in keyboard mode */
keybdReportReadMemory = 0xB3 /* same as F3 but in keyboard mode */
keybdReportWriteMemory = 0xB4 /* same as F4 but in keyboard mode */
keybdReportMemory = 0x41 /* response to b3,b4 */
)
const (
inReportExtEEData = 0x31
outReportExtEERead = 0xA1
outReportExtEEWrite = 0xA2
inReportIntEEData = 0x32
outReportIntEERead = 0xA3
outReportIntEEWrite = 0xA4
)
/* MEASUREMENT CONSTANTS */
const (
ct_RW = 75
ct_R1 = 49900
ct_R2 = 1500
ct_RP = 10000
)
const check_char = 0xAA /* used for line/write check */
const max_message_cnt = 64

122
internal/realusb/realusb.go Normal file
View file

@ -0,0 +1,122 @@
// +build !nogousb
package realusb
import (
"context"
"fmt"
"github.com/Fishwaldo/go-dcdc200/internal"
"github.com/Fishwaldo/go-logadapter"
"github.com/google/gousb"
)
const (
dcdc200_vid = 0x04d8
dcdc200_pid = 0xd003
)
type UsbIF struct {
ctx *gousb.Context
dev *gousb.Device
intf *gousb.Interface
done func()
log logadapter.Logger
}
func Init(log logadapter.Logger) (*UsbIF) {
usbif := UsbIF{log: log, ctx: gousb.NewContext()}
return &usbif
}
func (usbif *UsbIF) SetUSBDebug(level int) {
if usbif.ctx != nil {
usbif.ctx.Debug(level)
}
}
func (usbif *UsbIF) Scan() (bool, error) {
var err error
usbif.dev, err = usbif.ctx.OpenDeviceWithVIDPID(dcdc200_vid, dcdc200_pid)
if err != nil {
usbif.log.Warn("Could Not Open Device: %v", err)
usbif.Close()
return false, err
}
if usbif.dev == nil {
usbif.log.Warn("Can't Find Device")
usbif.Close()
return false, nil
}
err = usbif.dev.SetAutoDetach(true)
if err != nil {
usbif.log.Error("%s.SetAutoDetach(true): %v", usbif.dev, err)
}
confignum, _ := usbif.dev.ActiveConfigNum()
usbif.log.Trace("Device Config: %s %d", usbif.dev.String(), confignum)
// desc, _ := dc.dev.GetStringDescriptor(1)
// manu, _ := dc.dev.Manufacturer()
// prod, _ := dc.dev.Product()
// serial, _ := dc.dev.SerialNumber()
usbif.intf, usbif.done, err = usbif.dev.DefaultInterface()
if err != nil {
usbif.log.Error("%s.Interface(): %v", usbif.dev, err)
usbif.Close()
return false, err
}
usbif.log.Trace("Interface: %s", usbif.intf.String())
usbif.log = usbif.log.With("Device", usbif.intf.String())
return true, nil
}
func (usbif *UsbIF) Close() {
if usbif.intf != nil {
usbif.done()
usbif.intf.Close()
}
if usbif.dev != nil {
usbif.dev.Close()
}
if usbif.ctx != nil {
usbif.ctx.Close()
}
}
func (usbif *UsbIF) GetAllParam(ctx context.Context) ([]byte, int, error) {
if usbif.intf == nil {
usbif.log.Warn("Interface Not Opened")
return nil, 0, fmt.Errorf("interface Not Opened")
}
outp, err := usbif.intf.OutEndpoint(0x01)
if err != nil {
usbif.log.Warn("Can't Get OutEndPoint: %s", err)
return nil, 0, err
}
//log.Printf("OutEndpoint: %v", outp)
var send = make([]byte, 24)
send[0] = internal.CmdGetAllValues
//send = append(send, 0)
//log.Printf("About to Send %v", send)
len, err := outp.WriteContext(ctx, send)
if err != nil {
usbif.log.Warn("Cant Send GetAllValues Command: %s (%v) - %d", err, send, len)
return nil, 0, err
}
//log.Printf("Sent %d Bytes", len)
inp, err := usbif.intf.InEndpoint(0x81)
if err != nil {
usbif.log.Warn("Can't Get OutPoint: %s", err)
return nil, 0, err
}
//log.Printf("InEndpoint: %v", inp)
var recv = make([]byte, 24)
len, err = inp.ReadContext(ctx, recv)
if err != nil {
usbif.log.Warn("Can't Read GetAllValues Command: %s", err)
return nil, 0, err
}
return recv, len, nil
}

View file

@ -0,0 +1,35 @@
// +build nogousb
package realusb
import (
"context"
"fmt"
"github.com/Fishwaldo/go-logadapter"
)
type UsbIF struct {
log logadapter.Logger
}
func Init(log logadapter.Logger) (*UsbIF) {
usbif := UsbIF{log: log}
log.Panic("Not Compiled with USB Support!")
return &usbif
}
func (usbif *UsbIF) SetUSBDebug(level int) {
usbif.log.Panic("Not Compiled with USB Support!")
}
func (usbif *UsbIF) Scan() (bool, error) {
usbif.log.Panic("Not Compiled with USB Support")
return false, fmt.Errorf("Not Compiled with USB Support")
}
func (usbif *UsbIF) Close() {
usbif.log.Panic("Not Compiled with USB Support")
}
func (usbif *UsbIF) GetAllParam(ctx context.Context) ([]byte, int, error) {
usbif.log.Panic("Not Compiled with USB Support")
return nil, 0, fmt.Errorf("not compiled with USB Support")
}

82
internal/sim/sim.go Normal file
View file

@ -0,0 +1,82 @@
package sim
import (
"context"
"fmt"
"io"
"os"
"github.com/Fishwaldo/go-logadapter"
)
type SimIF struct {
log logadapter.Logger
file *os.File
}
var captureFile string
func SetCaptureFile(name string) error {
file, err := os.Open(name)
if err != nil {
return err
}
defer file.Close()
captureFile = name
return nil
}
func Init(log logadapter.Logger) *SimIF {
usbif := SimIF{log: log}
usbif.log.Info("Enabling Simulation Replay")
var err error
usbif.file, err = os.Open(captureFile)
if err != nil {
usbif.log.Panic("cannot open USB Capture File %s: %s", captureFile, err)
}
return &usbif
}
func (usbif *SimIF) SetUSBDebug(level int) {
}
func (usbif *SimIF) Scan() (bool, error) {
if usbif.file != nil {
return true, nil
} else {
return false, fmt.Errorf("capture File Not Specified")
}
}
func (usbif *SimIF) Close() {
if usbif.file != nil {
usbif.file.Close()
}
}
func (usbif *SimIF) GetAllParam(ctx context.Context) ([]byte, int, error) {
if usbif.file == nil {
usbif.log.Panic("usb Capture File Not Opened")
return nil, 0, fmt.Errorf("usb Capture File Not Opened")
}
cap := make([]byte, 24)
var len int
var err error
len, err = usbif.file.Read(cap)
if err != nil {
if err == io.EOF {
usbif.file.Seek(0, 0)
_, err = usbif.file.Read(cap)
if err != nil {
usbif.log.Warn("Seek to start of file Failed: %s", err)
return nil, 0, fmt.Errorf("seek to Start of File Failed: %s", err)
}
} else {
usbif.log.Warn("Read From Capture File Returned Error: %s", err)
return nil, 0, fmt.Errorf("read from Capture FIle Returned %s", err)
}
}
if len != 24 {
usbif.log.Warn("Short Read from USB Capture File: %d", len)
return nil, 0, fmt.Errorf("short Read from USB Capture File: %d", len)
}
return cap, len, nil
}

BIN
running.cap Normal file

Binary file not shown.

BIN
shutdown.cap Normal file

Binary file not shown.