mirror of
https://github.com/RoganDawes/P4wnP1_aloa.git
synced 2025-04-13 06:29:02 +02:00
refactoring
This commit is contained in:
parent
c0b5b5ba26
commit
c188e1f5c1
@ -7,13 +7,16 @@ import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
"log"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/*
|
||||
var (
|
||||
EvMgr *EventManager
|
||||
evmMutex = &sync.Mutex{}
|
||||
)
|
||||
|
||||
*/
|
||||
func pDEBUG(message string) {
|
||||
fmt.Println("EVENT DEBUG: " + message)
|
||||
}
|
||||
@ -30,6 +33,31 @@ type EventManager struct {
|
||||
receiverRegListMutex *sync.Mutex
|
||||
}
|
||||
|
||||
func NewEventManager(queueSize int) *EventManager {
|
||||
EvMgr := &EventManager{
|
||||
eventQueue: make(chan *pb.Event, queueSize),
|
||||
receiverDelListMutex: &sync.Mutex{},
|
||||
receiverRegListMutex: &sync.Mutex{},
|
||||
receiverRegisterList: make(map[*EventReceiver]bool),
|
||||
registeredReceivers: make(map[*EventReceiver]bool),
|
||||
receiverDeleteList: make(map[*EventReceiver]bool),
|
||||
}
|
||||
EvMgr.ctx, EvMgr.cancel = context.WithCancel(context.Background())
|
||||
return EvMgr
|
||||
}
|
||||
|
||||
func (evm *EventManager) Start() {
|
||||
log.Println("Event Manager: Starting event dispatcher")
|
||||
go evm.dispatch()
|
||||
}
|
||||
|
||||
func (evm *EventManager) Stop() {
|
||||
log.Println("Event Manager: Stopping ...")
|
||||
evm.cancel()
|
||||
close(evm.eventQueue)
|
||||
}
|
||||
|
||||
/*
|
||||
func StartEventManager(queueSize int) *EventManager {
|
||||
if EvMgr != nil { StopEventManager() }
|
||||
|
||||
@ -61,10 +89,11 @@ func StopEventManager() {
|
||||
close(EvMgr.eventQueue)
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
func (em *EventManager) Emit(event *pb.Event) {
|
||||
em.eventQueue <-event
|
||||
// fmt.Println("Event enqueued")
|
||||
//fmt.Println("Event enqueued")
|
||||
}
|
||||
|
||||
func (em *EventManager) Write(p []byte) (n int, err error) {
|
||||
@ -75,6 +104,8 @@ func (em *EventManager) Write(p []byte) (n int, err error) {
|
||||
|
||||
|
||||
func (em *EventManager) RegisterReceiver(filterEventType int64) *EventReceiver {
|
||||
fmt.Println("!!!Event listener registered for " + strconv.Itoa(int(filterEventType)))
|
||||
|
||||
ctx,cancel := context.WithCancel(context.Background())
|
||||
er := &EventReceiver{
|
||||
EventQueue: make(chan *pb.Event, 10), //allow buffering 10 events per receiver
|
||||
|
@ -4,6 +4,15 @@ import (
|
||||
pb "../proto"
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_CDC_ECM_HOST_ADDR = "42:63:66:12:34:56"
|
||||
DEFAULT_CDC_ECM_DEV_ADDR = "42:63:66:56:34:12"
|
||||
DEFAULT_RNDIS_HOST_ADDR = "42:63:65:12:34:56"
|
||||
DEFAULT_RNDIS_DEV_ADDR = "42:63:65:56:34:12"
|
||||
USB_ETHERNET_BRIDGE_MAC = "24:22:26:12:14:16"
|
||||
USB_ETHERNET_BRIDGE_NAME = "usbeth"
|
||||
)
|
||||
|
||||
func GetDefaultNetworkSettingsUSB() (*pb.EthernetInterfaceSettings) {
|
||||
//configure 172.24.0.1/255.255.255.252 for usbeth
|
||||
ifSettings := &pb.EthernetInterfaceSettings {
|
||||
@ -70,8 +79,8 @@ func GetDefaultDHCPConfigWiFi() (settings *pb.DHCPServerSettings) {
|
||||
return
|
||||
}
|
||||
|
||||
func GetDefaultLEDSettings() (res pb.LEDSettings) {
|
||||
return pb.LEDSettings{
|
||||
func GetDefaultLEDSettings() (res *pb.LEDSettings) {
|
||||
return &pb.LEDSettings{
|
||||
BlinkCount: 254,
|
||||
}
|
||||
}
|
||||
@ -93,12 +102,12 @@ func GetDefaultGadgetSettings() (res pb.GadgetSettings) {
|
||||
Use_UMS: false,
|
||||
Use_SERIAL: false,
|
||||
RndisSettings: &pb.GadgetSettingsEthernet{
|
||||
HostAddr: "42:63:65:12:34:56",
|
||||
DevAddr: "42:63:65:56:34:12",
|
||||
HostAddr: DEFAULT_RNDIS_HOST_ADDR,
|
||||
DevAddr: DEFAULT_RNDIS_DEV_ADDR,
|
||||
},
|
||||
CdcEcmSettings: &pb.GadgetSettingsEthernet{
|
||||
HostAddr: "42:63:66:12:34:56",
|
||||
DevAddr: "42:63:66:56:34:12",
|
||||
HostAddr: DEFAULT_CDC_ECM_HOST_ADDR,
|
||||
DevAddr: DEFAULT_CDC_ECM_DEV_ADDR,
|
||||
},
|
||||
UmsSettings: &pb.GadgetSettingsUMS{
|
||||
File:"", //we don't supply an image file, which is no problem as it could be applied later on (removable media)
|
||||
|
@ -21,11 +21,19 @@ const (
|
||||
LED_DELAY_PAUSE = 500 * time.Millisecond
|
||||
)
|
||||
|
||||
|
||||
type LedState struct {
|
||||
blink_count *uint32
|
||||
}
|
||||
/*
|
||||
var (
|
||||
blink_count uint32 = 0
|
||||
)
|
||||
*/
|
||||
func NewLed(led_on bool) (ledState *LedState, err error) {
|
||||
blinkCount := uint32(0)
|
||||
ledState = &LedState{ &blinkCount }
|
||||
|
||||
func InitLed(led_on bool) (error) {
|
||||
//set trigger of LED to manual
|
||||
log.Println("Setting LED to manual trigger ...")
|
||||
ioutil.WriteFile(LED_TRIGGER_PATH, []byte(LED_TRIGGER_MANUAL), os.ModePerm)
|
||||
@ -36,22 +44,22 @@ func InitLed(led_on bool) (error) {
|
||||
log.Println("Setting LED to OFF ...")
|
||||
ioutil.WriteFile(LED_BRIGHTNESS_PATH, []byte(LED_OFF), os.ModePerm)
|
||||
}
|
||||
atomic.StoreUint32(&blink_count, 0)
|
||||
|
||||
go led_loop()
|
||||
|
||||
return nil
|
||||
|
||||
go ledState.led_loop() // watcher loop
|
||||
|
||||
ledState.SetLed(GetDefaultLEDSettings()) //set default setting
|
||||
return ledState,nil
|
||||
}
|
||||
|
||||
func led_loop() {
|
||||
func (leds *LedState) led_loop() {
|
||||
|
||||
for {
|
||||
for i := uint32(0); i < atomic.LoadUint32(&blink_count); i++ {
|
||||
for i := uint32(0); i < atomic.LoadUint32(leds.blink_count); i++ {
|
||||
ioutil.WriteFile(LED_BRIGHTNESS_PATH, []byte(LED_ON), os.ModePerm)
|
||||
time.Sleep(LED_DELAY_ON)
|
||||
|
||||
//Don't turn off led if blink_count >= 255 (solid)
|
||||
if 255 > atomic.LoadUint32(&blink_count) {
|
||||
if 255 > atomic.LoadUint32(leds.blink_count) {
|
||||
ioutil.WriteFile(LED_BRIGHTNESS_PATH, []byte(LED_OFF), os.ModePerm)
|
||||
time.Sleep(LED_DELAY_OFF)
|
||||
}
|
||||
@ -60,18 +68,15 @@ func led_loop() {
|
||||
}
|
||||
}
|
||||
|
||||
func SetLed(s pb.LEDSettings) (error) {
|
||||
func (leds *LedState) SetLed(s *pb.LEDSettings) (error) {
|
||||
//log.Printf("setLED called with %+v", s)
|
||||
|
||||
atomic.StoreUint32(&blink_count, s.BlinkCount)
|
||||
atomic.StoreUint32(leds.blink_count, s.BlinkCount)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetLed() (res *pb.LEDSettings, err error) {
|
||||
return &pb.LEDSettings{BlinkCount: atomic.LoadUint32(&blink_count)}, nil
|
||||
func (leds *LedState) GetLed() (res *pb.LEDSettings, err error) {
|
||||
return &pb.LEDSettings{BlinkCount: atomic.LoadUint32(leds.blink_count)}, nil
|
||||
}
|
||||
|
||||
func InitDefaultLEDSettings() {
|
||||
SetLed(GetDefaultLEDSettings())
|
||||
}
|
@ -13,18 +13,10 @@ import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
StoredNetworkSetting map[string]*pb.EthernetInterfaceSettings = make(map[string]*pb.EthernetInterfaceSettings)
|
||||
)
|
||||
|
||||
func init() {
|
||||
//preinitialize Default settings for "wlan0" and USB_ETHERNET_BRIDGE_NAME ("usbeth")
|
||||
StoredNetworkSetting[USB_ETHERNET_BRIDGE_NAME] = GetDefaultNetworkSettingsUSB()
|
||||
StoredNetworkSetting["wlan0"] = GetDefaultNetworkSettingsWiFi()
|
||||
}
|
||||
|
||||
func ReInitNetworkInterface(ifName string) (err error) {
|
||||
if settings, existing := StoredNetworkSetting[ifName]; existing {
|
||||
if settings, existing := ServiceState.StoredNetworkSetting[ifName]; existing {
|
||||
log.Printf("Redeploying stored Network settings for interface '%s' ...\n", ifName)
|
||||
return ConfigureInterface(settings)
|
||||
} else {
|
||||
@ -208,7 +200,7 @@ func ConfigureInterface(settings *pb.EthernetInterfaceSettings) (err error) {
|
||||
}
|
||||
|
||||
//Store latest settings
|
||||
StoredNetworkSetting[settings.Name] = settings
|
||||
ServiceState.StoredNetworkSetting[settings.Name] = settings
|
||||
|
||||
return nil
|
||||
}
|
@ -30,7 +30,8 @@ var (
|
||||
type server struct {}
|
||||
|
||||
func (s *server) EventListen(eReq *pb.EventRequest, eStream pb.P4WNP1_EventListenServer) (err error) {
|
||||
rcv := EvMgr.RegisterReceiver(eReq.ListenType)
|
||||
//ToDo: check dependency from state (EvMgr initialized)
|
||||
rcv := ServiceState.EvMgr.RegisterReceiver(eReq.ListenType)
|
||||
|
||||
for {
|
||||
|
||||
@ -96,9 +97,9 @@ func (s *server) FSCreateTempDirOrFile(ctx context.Context, req *pb.TempDirOrFil
|
||||
}
|
||||
|
||||
func (s *server) HIDGetRunningScriptJobs(ctx context.Context, rEmpty *pb.Empty) (jobs *pb.HIDScriptJobList, err error) {
|
||||
if HidCtl == nil { return nil, rpcErrNoHid}
|
||||
if ServiceState.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
|
||||
retJobs,err := HidCtl.GetAllBackgroundJobs()
|
||||
retJobs,err := ServiceState.HidCtl.GetAllBackgroundJobs()
|
||||
if err != nil { return nil, err }
|
||||
jobs = &pb.HIDScriptJobList{}
|
||||
jobs.Ids = retJobs
|
||||
@ -107,10 +108,10 @@ func (s *server) HIDGetRunningScriptJobs(ctx context.Context, rEmpty *pb.Empty)
|
||||
|
||||
func (s *server) HIDCancelAllScriptJobs(ctx context.Context, rEmpty *pb.Empty) (empty *pb.Empty, err error) {
|
||||
empty = &pb.Empty{}
|
||||
if HidCtl == nil { return empty, rpcErrNoHid}
|
||||
if ServiceState.HidCtl == nil { return empty, rpcErrNoHid}
|
||||
|
||||
// Try to find script
|
||||
HidCtl.CancelAllBackgroundJobs()
|
||||
ServiceState.HidCtl.CancelAllBackgroundJobs()
|
||||
return
|
||||
}
|
||||
|
||||
@ -118,10 +119,10 @@ func (s *server) HIDCancelAllScriptJobs(ctx context.Context, rEmpty *pb.Empty) (
|
||||
|
||||
func (s *server) HIDCancelScriptJob(ctx context.Context, sJob *pb.HIDScriptJob) (empty *pb.Empty, err error) {
|
||||
empty = &pb.Empty{}
|
||||
if HidCtl == nil { return empty, rpcErrNoHid}
|
||||
if ServiceState.HidCtl == nil { return empty, rpcErrNoHid}
|
||||
|
||||
// Try to find script
|
||||
job,err := HidCtl.GetBackgroundJobByID(int(sJob.Id))
|
||||
job,err := ServiceState.HidCtl.GetBackgroundJobByID(int(sJob.Id))
|
||||
if err != nil { return empty, err }
|
||||
|
||||
job.Cancel()
|
||||
@ -129,7 +130,7 @@ func (s *server) HIDCancelScriptJob(ctx context.Context, sJob *pb.HIDScriptJob)
|
||||
}
|
||||
|
||||
func (s *server) HIDRunScript(ctx context.Context, scriptReq *pb.HIDScriptRequest) (scriptRes *pb.HIDScriptResult, err error) {
|
||||
if HidCtl == nil { return nil, rpcErrNoHid}
|
||||
if ServiceState.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
|
||||
|
||||
|
||||
@ -142,7 +143,7 @@ func (s *server) HIDRunScript(ctx context.Context, scriptReq *pb.HIDScriptReques
|
||||
if scriptReq.TimeoutSeconds > 0 { jobCtx,_ = context.WithTimeout(jobCtx, time.Second * time.Duration(scriptReq.TimeoutSeconds))}
|
||||
|
||||
|
||||
scriptVal,err := HidCtl.RunScript(jobCtx, string(scriptFile))
|
||||
scriptVal,err := ServiceState.HidCtl.RunScript(jobCtx, string(scriptFile))
|
||||
if err != nil { return nil,err }
|
||||
val,_ := scriptVal.Export() //Convert to Go representation, error is always nil
|
||||
jsonVal,err := json.Marshal(val)
|
||||
@ -159,7 +160,7 @@ func (s *server) HIDRunScript(ctx context.Context, scriptReq *pb.HIDScriptReques
|
||||
}
|
||||
|
||||
func (s *server) HIDRunScriptJob(ctx context.Context, scriptReq *pb.HIDScriptRequest) (rJob *pb.HIDScriptJob, err error) {
|
||||
if HidCtl == nil { return nil, rpcErrNoHid}
|
||||
if ServiceState.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
|
||||
if scriptFile, err := ioutil.ReadFile(scriptReq.ScriptPath); err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Couldn't load HIDScript '%s': %v\n", scriptReq.ScriptPath, err))
|
||||
@ -168,7 +169,7 @@ func (s *server) HIDRunScriptJob(ctx context.Context, scriptReq *pb.HIDScriptReq
|
||||
jobCtx := context.Background()
|
||||
// ToDo: we don't retrieve the cancelFunc which should be called to free resources. Solution: use withCancel context and call cancel by go routine on timeout
|
||||
if scriptReq.TimeoutSeconds > 0 { jobCtx,_ = context.WithTimeout(jobCtx, time.Second * time.Duration(scriptReq.TimeoutSeconds))}
|
||||
job,err := HidCtl.StartScriptAsBackgroundJob(jobCtx, string(scriptFile))
|
||||
job,err := ServiceState.HidCtl.StartScriptAsBackgroundJob(jobCtx, string(scriptFile))
|
||||
if err != nil { return nil,err }
|
||||
|
||||
rJob = &pb.HIDScriptJob{
|
||||
@ -180,15 +181,15 @@ func (s *server) HIDRunScriptJob(ctx context.Context, scriptReq *pb.HIDScriptReq
|
||||
}
|
||||
|
||||
func (s *server) HIDGetScriptJobResult(ctx context.Context, sJob *pb.HIDScriptJob) (scriptRes *pb.HIDScriptResult, err error) {
|
||||
if HidCtl == nil { return nil, rpcErrNoHid}
|
||||
if ServiceState.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
|
||||
// Try to find script
|
||||
job,err := HidCtl.GetBackgroundJobByID(int(sJob.Id))
|
||||
job,err := ServiceState.HidCtl.GetBackgroundJobByID(int(sJob.Id))
|
||||
if err != nil { return scriptRes, err }
|
||||
|
||||
|
||||
//ToDo: check impact/behavior, because ctx is provided by gRPC server
|
||||
scriptVal,err := HidCtl.WaitBackgroundJobResult(ctx, job)
|
||||
scriptVal,err := ServiceState.HidCtl.WaitBackgroundJobResult(ctx, job)
|
||||
if err != nil { return nil,err }
|
||||
val,_ := scriptVal.Export() //Convert to Go representation, error is always nil
|
||||
jsonVal,err := json.Marshal(val)
|
||||
@ -250,11 +251,11 @@ func (s *server) DeployGadgetSetting(context.Context, *pb.Empty) (gs *pb.GadgetS
|
||||
//ToDo: Former gadgets are destroyed without testing if there're changes, this should be aborted if GadgetSettingsState == GetDeployedGadgetSettings()
|
||||
DestroyGadget(USB_GADGET_NAME)
|
||||
|
||||
errg := DeployGadgetSettings(GadgetSettingsState)
|
||||
errg := ServiceState.UsbGM.DeployGadgetSettings(ServiceState.UsbGM.UndeployedGadgetSettings)
|
||||
err = nil
|
||||
if errg != nil {
|
||||
err = errors.New(fmt.Sprintf("Deploying new gadget settings failed, reverted to old ones: %v", errg))
|
||||
DeployGadgetSettings(*gs_backup) //We don't catch the error, as the old settings should have been working
|
||||
ServiceState.UsbGM.DeployGadgetSettings(gs_backup) //We don't catch the error, as the old settings should have been working
|
||||
}
|
||||
|
||||
gs, _ = ParseGadgetState(USB_GADGET_NAME) //Return settings from deployed gadget
|
||||
@ -262,29 +263,29 @@ func (s *server) DeployGadgetSetting(context.Context, *pb.Empty) (gs *pb.GadgetS
|
||||
}
|
||||
|
||||
func (s *server) GetGadgetSettings(context.Context, *pb.Empty) (*pb.GadgetSettings, error) {
|
||||
return &GadgetSettingsState, nil
|
||||
return ServiceState.UsbGM.UndeployedGadgetSettings, nil
|
||||
}
|
||||
|
||||
func (s *server) SetGadgetSettings(ctx context.Context, gs *pb.GadgetSettings) (res *pb.GadgetSettings, err error) {
|
||||
if err = ValidateGadgetSetting(*gs); err != nil {
|
||||
//We return the validation error and the current (unchanged) GadgetSettingsState
|
||||
res = &GadgetSettingsState
|
||||
res = ServiceState.UsbGM.UndeployedGadgetSettings
|
||||
return
|
||||
}
|
||||
GadgetSettingsState = *gs
|
||||
res = &GadgetSettingsState
|
||||
ServiceState.UsbGM.UndeployedGadgetSettings = gs
|
||||
res = ServiceState.UsbGM.UndeployedGadgetSettings
|
||||
return
|
||||
}
|
||||
|
||||
func (s *server) GetLEDSettings(context.Context, *pb.Empty) (res *pb.LEDSettings, err error) {
|
||||
res, err = GetLed()
|
||||
res, err = ServiceState.Led.GetLed()
|
||||
log.Printf("GetLEDSettings, result: %+v", res)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *server) SetLEDSettings(ctx context.Context, ls *pb.LEDSettings) (*pb.Empty, error) {
|
||||
log.Printf("SetLEDSettings %+v", ls)
|
||||
SetLed(*ls)
|
||||
ServiceState.Led.SetLed(ls)
|
||||
return &pb.Empty{}, nil
|
||||
}
|
||||
|
||||
|
47
service/state.go
Normal file
47
service/state.go
Normal file
@ -0,0 +1,47 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"../hid"
|
||||
pb "../proto"
|
||||
)
|
||||
|
||||
var ServiceState *GlobalServiceState
|
||||
|
||||
type GlobalServiceState struct {
|
||||
EvMgr *EventManager
|
||||
HidCtl *hid.HIDController
|
||||
UsbGM *UsbGadgetManager
|
||||
Led *LedState
|
||||
HidDevPath map[string]string //stores device path for HID devices
|
||||
StoredNetworkSetting map[string]*pb.EthernetInterfaceSettings
|
||||
}
|
||||
|
||||
func InitGlobalServiceState() (err error) {
|
||||
state := &GlobalServiceState{}
|
||||
ServiceState = state // store state in global variable
|
||||
|
||||
state.StoredNetworkSetting = make(map[string]*pb.EthernetInterfaceSettings)
|
||||
//preinitialize Default settings for "wlan0" and USB_ETHERNET_BRIDGE_NAME ("usbeth")
|
||||
state.StoredNetworkSetting[USB_ETHERNET_BRIDGE_NAME] = GetDefaultNetworkSettingsUSB()
|
||||
state.StoredNetworkSetting["wlan0"] = GetDefaultNetworkSettingsWiFi()
|
||||
|
||||
|
||||
state.HidDevPath = make(map[string]string) //should be initialized BEFORE UsbGadgetManager uses it
|
||||
state.EvMgr = NewEventManager(20)
|
||||
state.UsbGM,err = NewUSBGadgetManager()
|
||||
if err != nil { return }
|
||||
ledState, err := NewLed(false)
|
||||
if err != nil { return }
|
||||
state.Led = ledState
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (state *GlobalServiceState) StartService() {
|
||||
state.EvMgr.Start()
|
||||
}
|
||||
|
||||
func (state *GlobalServiceState) StopService() {
|
||||
state.EvMgr.Stop()
|
||||
}
|
@ -31,9 +31,6 @@ const (
|
||||
USB_GADGET_DIR_BASE = "/sys/kernel/config/usb_gadget"
|
||||
USB_GADGET_DIR = USB_GADGET_DIR_BASE + "/" + USB_GADGET_NAME
|
||||
|
||||
USB_ETHERNET_BRIDGE_NAME = "usbeth"
|
||||
USB_ETHERNET_BRIDGE_MAC = "24:22:26:12:14:16"
|
||||
|
||||
USB_bcdDevice = "0x0100" //Version 1.00
|
||||
USB_bcdUSB = "0x0200" //mode: USB 2.0
|
||||
|
||||
@ -77,12 +74,24 @@ const (
|
||||
|
||||
)
|
||||
|
||||
var (
|
||||
GadgetSettingsState pb.GadgetSettings = pb.GadgetSettings{}
|
||||
rp_usbHidDevName = regexp.MustCompile("(?m)DEVNAME=(.*)\n")
|
||||
HidDevPath = make(map[string]string) //stores device path for HID devices
|
||||
HidCtl *hid.HIDController
|
||||
)
|
||||
var rp_usbHidDevName = regexp.MustCompile("(?m)DEVNAME=(.*)\n")
|
||||
|
||||
type UsbGadgetManager struct {
|
||||
// ToDo: variable, indicating if HIDScript is usable
|
||||
HidCtl *hid.HIDController // Points to an HID controller instance only if keyboard and/or mouse are enabled, nil otherwise
|
||||
UndeployedGadgetSettings *pb.GadgetSettings
|
||||
}
|
||||
|
||||
func NewUSBGadgetManager() (newUGM *UsbGadgetManager, err error) {
|
||||
newUGM = &UsbGadgetManager{}
|
||||
defGS := GetDefaultGadgetSettings()
|
||||
newUGM.UndeployedGadgetSettings = &defGS //preload state with default settings
|
||||
err = newUGM.DeployGadgetSettings(newUGM.UndeployedGadgetSettings)
|
||||
if err != nil { return nil, err }
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
func ValidateGadgetSetting(gs pb.GadgetSettings) error {
|
||||
/* ToDo: validations
|
||||
@ -91,7 +100,7 @@ func ValidateGadgetSetting(gs pb.GadgetSettings) error {
|
||||
- check EP consumption to be not more than 7 (ECM 2 EP, RNDIS 2 EP, HID Mouse 1 EP, HID Keyboard 1 EP, HID Raw 1 EP, Serial 2 EP ??, UMS 2 EP ?)
|
||||
- check serial, product, Manufacturer to not be empty
|
||||
- check Pid, Vid with regex (Note: we don't check if Vid+Pid have been used for another composite function setup, yet)
|
||||
- If the gadget is enabled, at least one function has to be enabled
|
||||
- Done: If the gadget is enabled, at least one function has to be enabled
|
||||
*/
|
||||
|
||||
log.Println("Validating gadget settings ...")
|
||||
@ -126,6 +135,18 @@ func ValidateGadgetSetting(gs pb.GadgetSettings) error {
|
||||
log.Print(strConsumption)
|
||||
if sum_ep > USB_EP_USAGE_MAX { return errors.New(strConsumption)}
|
||||
|
||||
//check if composite gadget is enabled without functions
|
||||
if gs.Enabled &&
|
||||
!gs.Use_CDC_ECM &&
|
||||
!gs.Use_RNDIS &&
|
||||
!gs.Use_HID_KEYBOARD &&
|
||||
!gs.Use_HID_MOUSE &&
|
||||
!gs.Use_HID_RAW &&
|
||||
!gs.Use_UMS &&
|
||||
!gs.Use_SERIAL {
|
||||
return errors.New("If the composite gadget isn't disabled, as least one function has to be enabled")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -175,12 +196,6 @@ func pollForUSBEthernet(timeout time.Duration) error {
|
||||
return errors.New(fmt.Sprintf("Timeout %v reached before usb0 or usb1 became ready"))
|
||||
}
|
||||
|
||||
func InitDefaultGadgetSettings() (err error) {
|
||||
err = DeployGadgetSettings(GetDefaultGadgetSettings()) //Deploy default settings to ConfigFS
|
||||
if err != nil { return }
|
||||
GadgetSettingsState = GetDefaultGadgetSettings() //populate settings state with same values
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -291,6 +306,12 @@ func ParseGadgetState(gadgetName string) (result *pb.GadgetSettings, err error)
|
||||
} else {
|
||||
result.RndisSettings.DevAddr = strings.TrimSuffix(string(res), "\000\n")
|
||||
}
|
||||
} else {
|
||||
// we provide GadgetSettingsEthernet with default MAC adresses anyway, to have defaults in case RNDIS should be enabled
|
||||
result.RndisSettings = &pb.GadgetSettingsEthernet{
|
||||
HostAddr: DEFAULT_RNDIS_HOST_ADDR,
|
||||
DevAddr: DEFAULT_RNDIS_DEV_ADDR,
|
||||
}
|
||||
}
|
||||
|
||||
//USB CDC ECM
|
||||
@ -313,6 +334,12 @@ func ParseGadgetState(gadgetName string) (result *pb.GadgetSettings, err error)
|
||||
result.CdcEcmSettings.DevAddr = strings.TrimSuffix(string(res), "\000\n")
|
||||
}
|
||||
|
||||
} else {
|
||||
// we provide GadgetSettingsEthernet with default MAC adresses anyway, to have defaults in case CDC ECM should be enabled
|
||||
result.CdcEcmSettings = &pb.GadgetSettingsEthernet{
|
||||
HostAddr: DEFAULT_CDC_ECM_HOST_ADDR,
|
||||
DevAddr: DEFAULT_CDC_ECM_DEV_ADDR,
|
||||
}
|
||||
}
|
||||
|
||||
//USB serial
|
||||
@ -388,7 +415,7 @@ func MountUMSFile(filename string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeployGadgetSettings(settings pb.GadgetSettings) error {
|
||||
func (gm *UsbGadgetManager) DeployGadgetSettings(settings *pb.GadgetSettings) error {
|
||||
var usesUSBEthernet bool
|
||||
|
||||
//gadget_root := "./test"
|
||||
@ -576,11 +603,10 @@ func DeployGadgetSettings(settings pb.GadgetSettings) error {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//clear device path for HID devices
|
||||
HidDevPath[USB_FUNCTION_HID_KEYBOARD_name] = ""
|
||||
HidDevPath[USB_FUNCTION_HID_MOUSE_name] = ""
|
||||
HidDevPath[USB_FUNCTION_HID_RAW_name] = ""
|
||||
ServiceState.HidDevPath[USB_FUNCTION_HID_KEYBOARD_name] = ""
|
||||
ServiceState.HidDevPath[USB_FUNCTION_HID_MOUSE_name] = ""
|
||||
ServiceState.HidDevPath[USB_FUNCTION_HID_RAW_name] = ""
|
||||
|
||||
//get UDC driver name and bind to gadget
|
||||
if settings.Enabled {
|
||||
@ -594,25 +620,25 @@ func DeployGadgetSettings(settings pb.GadgetSettings) error {
|
||||
}
|
||||
|
||||
//update device path'
|
||||
if devPath,errF := enumDevicePath(USB_FUNCTION_HID_KEYBOARD_name); errF == nil { HidDevPath[USB_FUNCTION_HID_KEYBOARD_name] = devPath }
|
||||
if devPath,errF := enumDevicePath(USB_FUNCTION_HID_MOUSE_name); errF == nil { HidDevPath[USB_FUNCTION_HID_MOUSE_name] = devPath }
|
||||
if devPath,errF := enumDevicePath(USB_FUNCTION_HID_RAW_name); errF == nil { HidDevPath[USB_FUNCTION_HID_RAW_name] = devPath }
|
||||
if devPath,errF := enumDevicePath(USB_FUNCTION_HID_KEYBOARD_name); errF == nil { ServiceState.HidDevPath[USB_FUNCTION_HID_KEYBOARD_name] = devPath }
|
||||
if devPath,errF := enumDevicePath(USB_FUNCTION_HID_MOUSE_name); errF == nil { ServiceState.HidDevPath[USB_FUNCTION_HID_MOUSE_name] = devPath }
|
||||
if devPath,errF := enumDevicePath(USB_FUNCTION_HID_RAW_name); errF == nil { ServiceState.HidDevPath[USB_FUNCTION_HID_RAW_name] = devPath }
|
||||
|
||||
//if Keyboard or Mouse are deployed, grab a HIDController Instance else set it to nil (the old HIDController object won't be destroyed)
|
||||
if settings.Use_HID_KEYBOARD || settings.Use_HID_MOUSE {
|
||||
devPathKeyboard := HidDevPath[USB_FUNCTION_HID_KEYBOARD_name]
|
||||
devPathMouse := HidDevPath[USB_FUNCTION_HID_MOUSE_name]
|
||||
devPathKeyboard := ServiceState.HidDevPath[USB_FUNCTION_HID_KEYBOARD_name]
|
||||
devPathMouse := ServiceState.HidDevPath[USB_FUNCTION_HID_MOUSE_name]
|
||||
|
||||
var errH error
|
||||
HidCtl, errH = hid.NewHIDController(context.Background(), devPathKeyboard, USB_KEYBOARD_LANGUAGE_MAP_PATH, devPathMouse)
|
||||
gm.HidCtl, errH = hid.NewHIDController(context.Background(), devPathKeyboard, USB_KEYBOARD_LANGUAGE_MAP_PATH, devPathMouse)
|
||||
if errH != nil {
|
||||
log.Printf("ERROR: Couldn't bring up an instance of HIDController for keyboard: '%s', mouse: '%s' and mapping path '%s'\nReason: %v\n", devPathKeyboard, devPathMouse, USB_KEYBOARD_LANGUAGE_MAP_PATH, errH)
|
||||
} else {
|
||||
log.Printf("HIDController for keyboard: '%s', mouse: '%s' and mapping path '%s' initialized\n", devPathKeyboard, devPathMouse, USB_KEYBOARD_LANGUAGE_MAP_PATH)
|
||||
}
|
||||
} else {
|
||||
if HidCtl != nil { HidCtl.Abort() }
|
||||
HidCtl = nil
|
||||
if gm.HidCtl != nil { gm.HidCtl.Abort() }
|
||||
gm.HidCtl = nil
|
||||
log.Printf("HIDController for keyboard / mouse disabled\n")
|
||||
}
|
||||
}
|
||||
@ -667,7 +693,7 @@ func enumDevicePath(funcName string) (devPath string, err error){
|
||||
return
|
||||
}
|
||||
|
||||
func DestroyAllGadgets() error {
|
||||
func (gm *UsbGadgetManager) DestroyAllGadgets() error {
|
||||
//gadget_root := "./test"
|
||||
gadget_root := USB_GADGET_DIR_BASE
|
||||
|
||||
@ -690,8 +716,8 @@ func DestroyAllGadgets() error {
|
||||
}
|
||||
}
|
||||
|
||||
if HidCtl != nil { HidCtl.Abort() }
|
||||
HidCtl = nil
|
||||
if gm.HidCtl != nil { gm.HidCtl.Abort() }
|
||||
gm.HidCtl = nil
|
||||
log.Printf("HIDController for keyboard / mouse disabled\n")
|
||||
|
||||
return nil
|
||||
|
1
web_client/hvueCompModal.go
Normal file
1
web_client/hvueCompModal.go
Normal file
@ -0,0 +1 @@
|
||||
package main
|
@ -1,15 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"./mvuex"
|
||||
"github.com/gopherjs/gopherjs/js"
|
||||
"time"
|
||||
"context"
|
||||
pb "../proto/gopherjs"
|
||||
"./mvuex"
|
||||
)
|
||||
|
||||
const (
|
||||
maxLogEntries = 500
|
||||
|
||||
VUEX_ACTION_DEPLOY_CURRENT_GADGET_SETTINGS = "deployCurrentGadgetSettings"
|
||||
VUEX_ACTION_UPDATE_GADGET_SETTINGS_FROM_DEPLOYED = "updateCurrentGadgetSettingsFromDeployed"
|
||||
VUEX_MUTATION_SET_CURRENT_GADGET_SETTINGS_TO = "setCurrentGadgetSettings"
|
||||
VUEX_MUTATION_SET_CURRENT_HID_SCRIPT_SOURCE_TO = "setCurrentHIDScriptSource"
|
||||
|
||||
initHIDScript = `layout('us'); // US keyboard layout
|
||||
typingSpeed(100,150) // Wait 100ms between key strokes + an additional random value between 0ms and 150ms (natural)
|
||||
|
||||
@ -42,15 +46,19 @@ type GlobalState struct {
|
||||
CurrentHIDScriptSource string `js:"currentHIDScriptSource"`
|
||||
CurrentGadgetSettings *jsGadgetSettings `js:"currentGadgetSettings"`
|
||||
EventLog *jsLoggerData `js:"eventLog"`
|
||||
IsModalEnabled bool `js:"isModalEnabled"`
|
||||
|
||||
Counter int `js:"count"`
|
||||
Text string `js:"text"`
|
||||
}
|
||||
|
||||
func UpdateGadgetSettingsFromDeployed(jsGS *jsGadgetSettings) {
|
||||
/*
|
||||
func (state *GlobalState) UpdateGadgetSettingsFromDeployed(jsGS *jsGadgetSettings) {
|
||||
//gs := vue.GetVM(c).Get("gadgetSettings")
|
||||
println("UpdateGadgetSettingsFromDeployed called")
|
||||
|
||||
|
||||
|
||||
ctx,cancel := context.WithTimeout(context.Background(), time.Second*3)
|
||||
defer cancel()
|
||||
|
||||
@ -61,20 +69,74 @@ func UpdateGadgetSettingsFromDeployed(jsGS *jsGadgetSettings) {
|
||||
jsGS.fromGS(deployedGs)
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
func createGlobalStateStruct() GlobalState {
|
||||
state := GlobalState{Object:O()}
|
||||
state.Title = "P4wnP1 by MaMe82"
|
||||
state.CurrentHIDScriptSource = initHIDScript
|
||||
state.CurrentGadgetSettings = NewUSBGadgetSettings()
|
||||
UpdateGadgetSettingsFromDeployed(state.CurrentGadgetSettings)
|
||||
//UpdateGadgetSettingsFromDeployed(state.CurrentGadgetSettings)
|
||||
state.EventLog = NewLogger(maxLogEntries)
|
||||
state.IsModalEnabled = true
|
||||
|
||||
state.Counter = 1337
|
||||
state.Text = "Hi there says MaMe82"
|
||||
return state
|
||||
}
|
||||
|
||||
func actionUpdateGadgetSettingsFromDeployed(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState) {
|
||||
go func() {
|
||||
//fetch deployed gadget settings
|
||||
dGS,err := RpcGetDeployedGadgetSettings(time.Second * 3)
|
||||
if err != nil {
|
||||
println("Couldn't retrieve deployed gadget settings")
|
||||
return
|
||||
}
|
||||
//convert to JS version
|
||||
jsGS := &jsGadgetSettings{Object:O()}
|
||||
jsGS.fromGS(dGS)
|
||||
|
||||
//commit to current
|
||||
context.Commit("setCurrentGadgetSettings", jsGS)
|
||||
}()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func actionDeployCurrentGadgetSettings(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState) {
|
||||
go func() {
|
||||
// ToDo: Indicate deployment process via global state
|
||||
|
||||
//get current GadgetSettings
|
||||
curGS := state.CurrentGadgetSettings.toGS()
|
||||
|
||||
//try to set them via gRPC (the server holds an internal state, setting != deploying)
|
||||
err := RpcSetRemoteGadgetSettings(curGS, time.Second)
|
||||
if err != nil {
|
||||
//ToDo: use global store to return something, or allow actions to return promises (latter is too much JavaScript)
|
||||
Alert(err)
|
||||
return
|
||||
}
|
||||
|
||||
//try to deploy the, now set, remote GadgetSettings via gRPC
|
||||
_,err = RpcDeployRemoteGadgetSettings(time.Second*10)
|
||||
if err != nil {
|
||||
//ToDo: use global store to return something, or allow actions to return promises (latter is too much JavaScript)
|
||||
Alert(err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
//ToDo: If we're here, we succeeded and should indicate this via global state
|
||||
Alert("GadgetSettings deployed successfully")
|
||||
|
||||
}()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func initMVuex() {
|
||||
state := createGlobalStateStruct()
|
||||
store := mvuex.NewStore(
|
||||
@ -90,6 +152,10 @@ func initMVuex() {
|
||||
}()
|
||||
|
||||
}),
|
||||
mvuex.Mutation("setModalEnabled", func (store *mvuex.Store, state *GlobalState, enabled bool) {
|
||||
state.IsModalEnabled = enabled
|
||||
return
|
||||
}),
|
||||
mvuex.Mutation("increment", func (store *mvuex.Store, state *GlobalState, add int) {
|
||||
state.Counter += add
|
||||
return
|
||||
@ -102,18 +168,12 @@ func initMVuex() {
|
||||
state.Text = newText
|
||||
return
|
||||
}),
|
||||
mvuex.Mutation("setCurrentHIDScriptSource", func (store *mvuex.Store, state *GlobalState, newText string) {
|
||||
mvuex.Mutation(VUEX_MUTATION_SET_CURRENT_HID_SCRIPT_SOURCE_TO, func (store *mvuex.Store, state *GlobalState, newText string) {
|
||||
state.CurrentHIDScriptSource = newText
|
||||
return
|
||||
}),
|
||||
mvuex.Mutation("setCurrentGadgetSettings", func (store *mvuex.Store, state *GlobalState, newSettings *jsGadgetSettings) {
|
||||
state.CurrentGadgetSettings = newSettings
|
||||
return
|
||||
}),
|
||||
mvuex.Mutation("setCurrentGadgetSettingsFromDeployed", func (store *mvuex.Store, state *GlobalState) {
|
||||
//ToDo: check if this is valid for synchronous run, has to be dispatched to action otherwise
|
||||
println("Store: commit setCurrentGadgetSettingsFromDeployed")
|
||||
go UpdateGadgetSettingsFromDeployed(state.CurrentGadgetSettings)
|
||||
mvuex.Mutation(VUEX_MUTATION_SET_CURRENT_GADGET_SETTINGS_TO, func (store *mvuex.Store, state *GlobalState, settings *jsGadgetSettings) {
|
||||
state.CurrentGadgetSettings = settings
|
||||
return
|
||||
}),
|
||||
mvuex.Mutation("startLogListening", func (store *mvuex.Store, state *GlobalState) {
|
||||
@ -124,8 +184,12 @@ func initMVuex() {
|
||||
state.EventLog.StopListening()
|
||||
return
|
||||
}),
|
||||
mvuex.Action(VUEX_ACTION_UPDATE_GADGET_SETTINGS_FROM_DEPLOYED, actionUpdateGadgetSettingsFromDeployed),
|
||||
mvuex.Action(VUEX_ACTION_DEPLOY_CURRENT_GADGET_SETTINGS, actionDeployCurrentGadgetSettings),
|
||||
)
|
||||
|
||||
// fetch deployed gadget settings
|
||||
store.Dispatch("updateCurrentGadgetSettingsFromDeployed")
|
||||
|
||||
// propagate Vuex store to global scope to allow injecting it to Vue by setting the "store" option
|
||||
js.Global.Set("store", store)
|
Loading…
x
Reference in New Issue
Block a user