mirror of
https://github.com/RoganDawes/P4wnP1_aloa.git
synced 2025-03-27 01:51:45 +01:00
Updated Makefiel with keymaps; updated HIDController reinit (accounting for otto memory leak); added HIDController to P4wnP1_Service;
This commit is contained in:
parent
513bbabbad
commit
e9d268d89d
3
Makefile
3
Makefile
@ -8,6 +8,8 @@ install:
|
||||
cp P4wnP1_service /usr/local/bin/
|
||||
cp P4wnP1_cli /usr/local/bin/
|
||||
cp P4wnP1.service /etc/systemd/system/P4wnP1.service
|
||||
mkdir /usr/local/P4wnP1
|
||||
cp -R keymaps /usr/local/P4wnP1/
|
||||
# reinit service daemon
|
||||
systemctl daemon-reload
|
||||
# enable service
|
||||
@ -23,5 +25,6 @@ remove:
|
||||
rm -f /usr/local/bin/P4wnP1_service
|
||||
rm -f /usr/local/bin/P4wnP1_cli
|
||||
rm -f /etc/systemd/system/P4wnP1.service
|
||||
rm -R /usr/local/P4wnP1/
|
||||
# reinit service daemon
|
||||
systemctl daemon-reload
|
||||
|
2
ToDo.txt
2
ToDo.txt
@ -13,6 +13,8 @@ USB
|
||||
|
||||
HID
|
||||
- add additional keyboard layouts (not for first release)
|
||||
- DONE: fix absolute mouse movement
|
||||
- DONE: avoid memory leak on reinit of HIDController
|
||||
|
||||
WIFI
|
||||
- implement connection to OPEN-AUTH network as STA
|
||||
|
@ -39,12 +39,8 @@ func (avm AsyncOttoVM) IsWorking() bool {
|
||||
}
|
||||
|
||||
func (avm *AsyncOttoVM) Run(src interface{}) (val otto.Value, res error) {
|
||||
fmt.Printf("BLOCKING RUN start state: %+v Finished: %d\n",avm, len(avm.Finished))
|
||||
|
||||
res = avm.RunAsync(src)
|
||||
if res != nil { return }
|
||||
fmt.Printf("BLOCKING RUN before wait state: %+v Finished: %d\n",avm, len(avm.Finished))
|
||||
defer fmt.Printf("BLOCKING RUN after wait state: %+v Finished: %d\n",avm, len(avm.Finished))
|
||||
return avm.WaitResult()
|
||||
}
|
||||
|
||||
@ -53,7 +49,6 @@ func (avm *AsyncOttoVM) RunAsync(src interface{}) (error) {
|
||||
avm.isWorking = true
|
||||
// ToDo: This has to replaced by real job control, to preserve results in case waitResult() is called late (results have to be stored per job, not per VM)
|
||||
for len(avm.Finished) > 0 {
|
||||
fmt.Println("CONSUMING FINISH EVENT BEFORE VM REUSE")
|
||||
<-avm.Finished
|
||||
} // We consume old finish events (there was no call to waitResult() up to that point)
|
||||
avm.ResultErr = nil
|
||||
@ -64,11 +59,8 @@ func (avm *AsyncOttoVM) RunAsync(src interface{}) (error) {
|
||||
|
||||
|
||||
defer func() {
|
||||
fmt.Println("STARTING DEFER FUNC")
|
||||
|
||||
if caught := recover(); caught != nil {
|
||||
if caught == halt {
|
||||
fmt.Println("VM CANCELED")
|
||||
nErr := errors.New("VM execution cancelled")
|
||||
avm.ResultErr = &nErr
|
||||
|
||||
@ -142,22 +134,12 @@ func (avm *AsyncOttoVM) Cancel() error {
|
||||
avm.vm.Interrupt <- func() {
|
||||
panic(halt)
|
||||
}
|
||||
fmt.Printf("WAITING FOR RESULT TO BE SURE CANCEL WORKED: %+v\n", avm)
|
||||
|
||||
} else {
|
||||
fmt.Println("VM ALREADY INTERRUPTED")
|
||||
}
|
||||
|
||||
//consume result
|
||||
avm.WaitResult()
|
||||
} else {
|
||||
fmt.Println("VM NOT WORKING, NO NEED TO CANCEL")
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -63,22 +63,8 @@ func NewHIDController(keyboardDevicePath string, keyboardMapPath string, mouseDe
|
||||
} else {
|
||||
// an old HIDController object is reused and has to be cleaned
|
||||
|
||||
|
||||
|
||||
//stop the old LED reader if present
|
||||
// !! Keyboard.Close() has to be called before sending IRQ to VMs (there're JS function which register
|
||||
// blocking callbacks to the Keyboard's LED reader, which would hinder the VM interrupt in triggering)
|
||||
if hidControllerReuse.Keyboard != nil {
|
||||
fmt.Println("***CLOSE KBD AND LED STATE LISTENER DUE TO CONTROLLER REUSE")
|
||||
hidControllerReuse.Keyboard.Close() //interrupts go routines reading from device file and lets LEDStateListeners die
|
||||
fmt.Println("***DONE CLOSING KBD AND LED STATE LISTENER DUE TO CONTROLLER REUSE")
|
||||
hidControllerReuse.Keyboard = nil
|
||||
}
|
||||
|
||||
// Interrupt all VMs already running
|
||||
fmt.Println("***CANCEL BG JOBS DUE TO CONTROLLER REUSE")
|
||||
hidControllerReuse.CancelAllBackgroundJobs()
|
||||
|
||||
hidControllerReuse.Abort()
|
||||
hidControllerReuse.Keyboard = nil
|
||||
hidControllerReuse.Mouse = nil
|
||||
}
|
||||
|
||||
@ -98,39 +84,20 @@ func NewHIDController(keyboardDevicePath string, keyboardMapPath string, mouseDe
|
||||
if err != nil { return nil, err }
|
||||
}
|
||||
|
||||
|
||||
//init master otto vm (vm.Copy() seems to be prone to memory leak, so we build them by hand)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
for i:=0; i< len(ctl.vmPool); i++ {
|
||||
vm := otto.New()
|
||||
ctl.initVM(vm)
|
||||
ctl.vmPool[i] = NewAsyncOttoVM(vm)
|
||||
}
|
||||
*/
|
||||
|
||||
return hidControllerReuse, nil
|
||||
}
|
||||
|
||||
/*
|
||||
func (ctl *HIDController) Stop() error {
|
||||
//cancel LED reader (interrupts listeners, scripts using the listener, because of commands like "waitLED" continue running, but the respective command fails)
|
||||
ctl.Keyboard.Close()
|
||||
|
||||
|
||||
//Cancel all VMs which are still running scripts
|
||||
ctl.CancelAllBackgroundJobs()
|
||||
|
||||
//close interrupt channels
|
||||
for i := 0; i< MAX_VM; i++ {
|
||||
close(ctl.vmPool[i].vm.Interrupt)
|
||||
func (ctl *HIDController) Abort() {
|
||||
// stop the old LED reader if present
|
||||
// !! Keyboard.Close() has to be called before sending IRQ to VMs (there're JS function which register
|
||||
// blocking callbacks to the Keyboard's LED reader, which would hinder the VM interrupt in triggering)
|
||||
if hidControllerReuse.Keyboard != nil {
|
||||
hidControllerReuse.Keyboard.Close() //interrupts go routines reading from device file and lets LEDStateListeners die
|
||||
}
|
||||
|
||||
return nil
|
||||
// Interrupt all VMs already running
|
||||
hidControllerReuse.CancelAllBackgroundJobs()
|
||||
}
|
||||
*/
|
||||
|
||||
func (ctl *HIDController) NextUnusedVM() (idx int, vm *AsyncOttoVM, err error) {
|
||||
//iterate over pool
|
||||
@ -230,7 +197,13 @@ func (ctl *HIDController) jsType(call otto.FunctionCall) (res otto.Value) {
|
||||
log.Printf("HIDScript type: couldn't convert '%s' to UTF-8 string\n", arg0)
|
||||
return
|
||||
}
|
||||
log.Printf("HIDScript type: Typing '%s ...' on HID keyboard device '%s'\n", outStr[:15], ctl.Keyboard.DevicePath)
|
||||
var partial string
|
||||
if len(outStr) > 15 {
|
||||
partial = outStr[:15]
|
||||
} else {
|
||||
partial = outStr
|
||||
}
|
||||
log.Printf("HIDScript type: Typing '%s ...' on HID keyboard device '%s'\n", partial, ctl.Keyboard.DevicePath)
|
||||
err = ctl.Keyboard.StringToPressKeySequence(outStr)
|
||||
if err != nil {
|
||||
log.Printf("HIDScript type: Couldn't type out `%s` on %v\n", outStr, ctl.Keyboard.DevicePath)
|
||||
@ -358,12 +331,12 @@ func (ctl *HIDController) jsWaitLED(call otto.FunctionCall) (res otto.Value) {
|
||||
// log.Printf("Timeout given: %v\n", arg1)
|
||||
timeoutInt, err := arg1.ToInteger()
|
||||
if err != nil || timeoutInt < 0 {
|
||||
log.Printf("HIDScript WaitLED: Second argument for `waitLED` is the timeout in seconds and has to be given as positive interger, but '%d' was given!\n", arg1)
|
||||
log.Printf("HIDScript WaitLED: Second argument for `waitLED` is the timeout in milliseconds and has to be given as positive interger, but '%d' was given!\n", arg1)
|
||||
return
|
||||
}
|
||||
timeout = time.Duration(timeoutInt) * time.Second
|
||||
timeout = time.Duration(timeoutInt) * time.Millisecond
|
||||
default:
|
||||
log.Printf("HIDScript WaitLED: Second argument for `waitLED` is the timeout in seconds and has to be given as interger or omitted for infinite timeout\n")
|
||||
log.Printf("HIDScript WaitLED: Second argument for `waitLED` is the timeout in milliseconds and has to be given as interger or omitted for infinite timeout\n")
|
||||
return
|
||||
}
|
||||
|
||||
@ -460,12 +433,12 @@ func (ctl *HIDController) jsWaitLEDRepeat(call otto.FunctionCall) (res otto.Valu
|
||||
// log.Printf("Timeout given: %v\n", arg1)
|
||||
timeoutInt, err := arg3.ToInteger()
|
||||
if err != nil || timeoutInt < 0 {
|
||||
log.Printf("HIDScript WaitLEDRepeat: Second argument for `waitLED` is the timeout in seconds and has to be given as positive interger, but '%d' was given!\n", arg1)
|
||||
log.Printf("HIDScript WaitLEDRepeat: Second argument for `waitLED` is the timeout in milliseconds and has to be given as positive interger, but '%d' was given!\n", arg1)
|
||||
return
|
||||
}
|
||||
timeout = time.Duration(timeoutInt) * time.Second
|
||||
timeout = time.Duration(timeoutInt) * time.Millisecond
|
||||
default:
|
||||
log.Printf("HIDScript WaitLEDRepeat: Second argument for `waitLED` is the timeout in seconds and has to be given as interger or omitted for infinite timeout\n")
|
||||
log.Printf("HIDScript WaitLEDRepeat: Second argument for `waitLED` is the timeout in milliseconds and has to be given as interger or omitted for infinite timeout\n")
|
||||
return
|
||||
}
|
||||
|
||||
|
12
hid/mouse.go
12
hid/mouse.go
@ -5,6 +5,8 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"math"
|
||||
"time"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -35,7 +37,7 @@ func NewMouse(devicePath string) (mouse *Mouse, err error) {
|
||||
func (m *Mouse) writeReportToFile(file string) error {
|
||||
report, err := generateMouseReport(m.lastChangeWasAbsolute, m.buttons, m.axis)
|
||||
if err != nil { return err }
|
||||
//fmt.Printf("Writing %+v to %s\n", report, file)
|
||||
fmt.Printf("Writing %+v to %s\n", report, file)
|
||||
return ioutil.WriteFile(file, report, os.ModePerm) //Serialize Report and write to specified file
|
||||
}
|
||||
|
||||
@ -55,6 +57,7 @@ func (m* Mouse) SetButtons(bt1,bt2,bt3 bool) (err error) {
|
||||
}
|
||||
|
||||
if change {
|
||||
m.lastChangeWasAbsolute = false
|
||||
m.axis[0] = 0 //No (repeated) movement on button change
|
||||
m.axis[1] = 0 //No (repeated) movement on button change
|
||||
return m.writeReportToFile(m.devicePath)
|
||||
@ -73,6 +76,7 @@ func (m* Mouse) Click(bt1,bt2,bt3 bool) (err error) {
|
||||
|
||||
func (m* Mouse) DoubleClick(bt1,bt2,bt3 bool) (err error) {
|
||||
m.Click(bt1,bt2,bt3)
|
||||
time.Sleep(100 * time.Millisecond) // delay between clicks
|
||||
m.Click(bt1,bt2,bt3)
|
||||
return
|
||||
}
|
||||
@ -86,10 +90,10 @@ func (m* Mouse) Move(x,y int8) (err error) {
|
||||
|
||||
|
||||
func scaleAbs(fVal float64) int {
|
||||
ival := int(float64(0xFFFF) * fVal)
|
||||
ival -= 32768
|
||||
ival := int(float64(0x7FFF) * fVal)
|
||||
//ival -= 32768
|
||||
if ival < -32768 { ival = -32768 }
|
||||
if ival < 32767 { ival = 32767 }
|
||||
if ival > 32767 { ival = 32767 }
|
||||
return ival
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,21 @@ func ConfigureInterface(settings *pb.EthernetInterfaceSettings) (err error) {
|
||||
if err != nil {return err}
|
||||
//stop already running DHCPServers for the interface
|
||||
StopDHCPServer(ifName)
|
||||
|
||||
//special case: if the interface name is USB_ETHERNET_BRIDGE_NAME, we delete the old lease file
|
||||
// the flushing of still running leases is needed, as after USB reinit, RNDIS hosts aren't guaranteed to
|
||||
// receive the sam MAC, which would effectivly block reusing of a lease for the same IP (a problem, as in
|
||||
// typical DHCP server configurations for USB Ethernet, the same remote IP should be offered every time)
|
||||
if settings.Name == USB_ETHERNET_BRIDGE_NAME {
|
||||
log.Printf("Reconfiguration of USB Ethernert interface as DHCP server, trying to delete old lease file ...\n")
|
||||
errD := os.Remove(settings.DhcpServerSettings.LeaseFile)
|
||||
if errD == nil {
|
||||
log.Println(" ... old lease file deleted successfull")
|
||||
} else {
|
||||
log.Printf(" ... old lease couldn't be deleted (Fetching a new DHCP lease could take a while on USB ethernet)!\n\tReason: %v\n", errD)
|
||||
}
|
||||
}
|
||||
|
||||
//start the DHCP server
|
||||
err = StartDHCPServer(ifName, confName)
|
||||
if err != nil {return err}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
"../hid"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -71,12 +72,15 @@ const (
|
||||
USB_FUNCTION_HID_RAW_report_desc = "\x06\x00\xff\t\x01\xa1\x01\t\x01\x15\x00&\xff\x00u\x08\x95@\x81\x02\t\x02\x15\x00&\xff\x00u\x08\x95@\x91\x02\xc0"
|
||||
USB_FUNCTION_HID_RAW_name = "hid.raw"
|
||||
|
||||
USB_KEYBOARD_LANGUAGE_MAP_PATH = "/usr/local/P4wnP1/keymaps"
|
||||
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
func ValidateGadgetSetting(gs pb.GadgetSettings) error {
|
||||
@ -592,6 +596,24 @@ func DeployGadgetSettings(settings pb.GadgetSettings) error {
|
||||
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 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]
|
||||
|
||||
var errH error
|
||||
HidCtl, errH = hid.NewHIDController(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
|
||||
log.Printf("HIDController for keyboard / mouse disabled\n")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -667,6 +689,10 @@ func DestroyAllGadgets() error {
|
||||
}
|
||||
}
|
||||
|
||||
if HidCtl != nil { HidCtl.Abort() }
|
||||
HidCtl = nil
|
||||
log.Printf("HIDController for keyboard / mouse disabled\n")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user