Updated Makefiel with keymaps; updated HIDController reinit (accounting for otto memory leak); added HIDController to P4wnP1_Service;

This commit is contained in:
mame82 2018-06-27 05:38:47 +00:00
parent 513bbabbad
commit e9d268d89d
7 changed files with 77 additions and 72 deletions

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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}

View File

@ -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
}