mirror of
https://github.com/RoganDawes/P4wnP1_aloa.git
synced 2025-03-29 19:11:45 +01:00
Service emit HID controller events via gRPC
This commit is contained in:
parent
e153064605
commit
ecee187f0d
@ -1,7 +1,8 @@
|
||||
package common
|
||||
|
||||
const (
|
||||
EVT_ANY = int64(1)
|
||||
EVT_ANY = int64(0)
|
||||
EVT_LOG = int64(1)
|
||||
EVT_HID = int64(2)
|
||||
)
|
||||
|
||||
|
@ -8,18 +8,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
"log"
|
||||
"strconv"
|
||||
"../hid"
|
||||
)
|
||||
|
||||
/*
|
||||
var (
|
||||
EvMgr *EventManager
|
||||
evmMutex = &sync.Mutex{}
|
||||
)
|
||||
*/
|
||||
func pDEBUG(message string) {
|
||||
fmt.Println("EVENT DEBUG: " + message)
|
||||
}
|
||||
|
||||
type EventManager struct {
|
||||
eventQueue chan *pb.Event
|
||||
@ -57,43 +48,9 @@ func (evm *EventManager) Stop() {
|
||||
close(evm.eventQueue)
|
||||
}
|
||||
|
||||
/*
|
||||
func StartEventManager(queueSize int) *EventManager {
|
||||
if EvMgr != nil { StopEventManager() }
|
||||
|
||||
evmMutex.Lock()
|
||||
defer evmMutex.Unlock()
|
||||
|
||||
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())
|
||||
|
||||
pDEBUG("EvtMgr started")
|
||||
go EvMgr.dispatch()
|
||||
|
||||
return EvMgr
|
||||
}
|
||||
|
||||
func StopEventManager() {
|
||||
evmMutex.Lock()
|
||||
defer evmMutex.Unlock()
|
||||
|
||||
if EvMgr == nil { return }
|
||||
EvMgr.cancel()
|
||||
close(EvMgr.eventQueue)
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
func (em *EventManager) Emit(event *pb.Event) {
|
||||
//fmt.Printf("Emitting event: %+v\n", event)
|
||||
em.eventQueue <-event
|
||||
//fmt.Println("Event enqueued")
|
||||
}
|
||||
|
||||
func (em *EventManager) Write(p []byte) (n int, err error) {
|
||||
@ -104,7 +61,7 @@ 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)))
|
||||
// fmt.Println("!!!Event listener registered for " + strconv.Itoa(int(filterEventType)))
|
||||
|
||||
ctx,cancel := context.WithCancel(context.Background())
|
||||
er := &EventReceiver{
|
||||
@ -113,6 +70,7 @@ func (em *EventManager) RegisterReceiver(filterEventType int64) *EventReceiver {
|
||||
Cancel: cancel,
|
||||
FilterEventType: filterEventType,
|
||||
}
|
||||
fmt.Printf("Registered receiver for %d\n", er.FilterEventType)
|
||||
em.receiverRegListMutex.Lock()
|
||||
em.receiverRegisterList[er] = true
|
||||
em.receiverRegListMutex.Unlock()
|
||||
@ -128,7 +86,6 @@ func (em *EventManager) UnregisterReceiver(receiver *EventReceiver) {
|
||||
|
||||
func (em *EventManager) dispatch() {
|
||||
fmt.Println("Started event dispatcher")
|
||||
pDEBUG("Started dispatcher")
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
@ -173,12 +130,11 @@ func (em *EventManager) dispatch() {
|
||||
//EventManage aborted
|
||||
|
||||
// ToDo: close all eventReceivers eventQueues, to notify them of the stopped dispatcher
|
||||
pDEBUG("EvtMgr cancelled")
|
||||
//fmt.Println("EvtMgr cancelled")
|
||||
break loop
|
||||
}
|
||||
}
|
||||
fmt.Println("Stopped event dispatcher")
|
||||
pDEBUG("Stopped dispatcher")
|
||||
}
|
||||
|
||||
|
||||
@ -205,3 +161,36 @@ func ConstructEventLog(source string, level int, message string) *pb.Event {
|
||||
}
|
||||
}
|
||||
|
||||
func ConstructEventHID(hidEvent hid.Event) *pb.Event {
|
||||
//subType, vmID, jobID int, error bool, resString, errString, message string
|
||||
vmID := -1
|
||||
jobID := -1
|
||||
hasError := false
|
||||
errString := ""
|
||||
message := hidEvent.Message
|
||||
resString := ""
|
||||
if job := hidEvent.Job; job != nil {
|
||||
jobID = job.Id
|
||||
if job.ResultErr != nil {
|
||||
hasError = true
|
||||
errString = job.ResultErr.Error()
|
||||
}
|
||||
resString,_ = job.ResultJsonString()
|
||||
}
|
||||
if eVM := hidEvent.Vm; eVM != nil { vmID = eVM.Id }
|
||||
|
||||
return &pb.Event{
|
||||
Type: common.EVT_HID, //Type
|
||||
Values: []*pb.EventValue{
|
||||
{Val: &pb.EventValue_Tint64{Tint64:int64(hidEvent.Type)} }, //SubType = Type of hid.Event
|
||||
{Val: &pb.EventValue_Tint64{Tint64:int64(vmID)} }, //ID of VM
|
||||
{Val: &pb.EventValue_Tint64{Tint64:int64(jobID)} }, //ID of job
|
||||
{Val: &pb.EventValue_Tbool{Tbool:hasError} }, //isError (f.e. if a job was interrupted)
|
||||
{Val: &pb.EventValue_Tstring{Tstring:resString} }, //result String
|
||||
{Val: &pb.EventValue_Tstring{Tstring:errString} }, //error String (message in case of error)
|
||||
{Val: &pb.EventValue_Tstring{Tstring:message} }, //Mesage text of event
|
||||
{Val: &pb.EventValue_Tstring{Tstring:time.Now().String()} },//Timestamp of event genration
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,9 @@ func (s *server) EventListen(eReq *pb.EventRequest, eStream pb.P4WNP1_EventListe
|
||||
rcv := ServiceState.EvMgr.RegisterReceiver(eReq.ListenType)
|
||||
|
||||
for {
|
||||
|
||||
select {
|
||||
case ev := <- rcv.EventQueue:
|
||||
fmt.Printf("Event dequed to send: %+v\n", ev)
|
||||
//fmt.Printf("Event dequed to send: %+v\n", ev)
|
||||
|
||||
//send Event to stream
|
||||
err = eStream.Send(ev)
|
||||
@ -97,9 +96,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 ServiceState.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
if ServiceState.UsbGM.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
|
||||
retJobs,err := ServiceState.HidCtl.GetAllBackgroundJobs()
|
||||
retJobs,err := ServiceState.UsbGM.HidCtl.GetAllBackgroundJobs()
|
||||
if err != nil { return nil, err }
|
||||
jobs = &pb.HIDScriptJobList{}
|
||||
jobs.Ids = retJobs
|
||||
@ -108,10 +107,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 ServiceState.HidCtl == nil { return empty, rpcErrNoHid}
|
||||
if ServiceState.UsbGM.HidCtl == nil { return empty, rpcErrNoHid}
|
||||
|
||||
// Try to find script
|
||||
ServiceState.HidCtl.CancelAllBackgroundJobs()
|
||||
ServiceState.UsbGM.HidCtl.CancelAllBackgroundJobs()
|
||||
return
|
||||
}
|
||||
|
||||
@ -119,10 +118,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 ServiceState.HidCtl == nil { return empty, rpcErrNoHid}
|
||||
if ServiceState.UsbGM.HidCtl == nil { return empty, rpcErrNoHid}
|
||||
|
||||
// Try to find script
|
||||
job,err := ServiceState.HidCtl.GetBackgroundJobByID(int(sJob.Id))
|
||||
job,err := ServiceState.UsbGM.HidCtl.GetBackgroundJobByID(int(sJob.Id))
|
||||
if err != nil { return empty, err }
|
||||
|
||||
job.Cancel()
|
||||
@ -130,7 +129,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 ServiceState.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
if ServiceState.UsbGM.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
|
||||
|
||||
|
||||
@ -143,7 +142,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 := ServiceState.HidCtl.RunScript(jobCtx, string(scriptFile))
|
||||
scriptVal,err := ServiceState.UsbGM.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)
|
||||
@ -160,7 +159,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 ServiceState.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
if ServiceState.UsbGM.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))
|
||||
@ -169,7 +168,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 := ServiceState.HidCtl.StartScriptAsBackgroundJob(jobCtx, string(scriptFile))
|
||||
job,err := ServiceState.UsbGM.HidCtl.StartScriptAsBackgroundJob(jobCtx, string(scriptFile))
|
||||
if err != nil { return nil,err }
|
||||
|
||||
rJob = &pb.HIDScriptJob{
|
||||
@ -181,15 +180,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 ServiceState.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
if ServiceState.UsbGM.HidCtl == nil { return nil, rpcErrNoHid}
|
||||
|
||||
// Try to find script
|
||||
job,err := ServiceState.HidCtl.GetBackgroundJobByID(int(sJob.Id))
|
||||
job,err := ServiceState.UsbGM.HidCtl.GetBackgroundJobByID(int(sJob.Id))
|
||||
if err != nil { return scriptRes, err }
|
||||
|
||||
|
||||
//ToDo: check impact/behavior, because ctx is provided by gRPC server
|
||||
scriptVal,err := ServiceState.HidCtl.WaitBackgroundJobResult(ctx, job)
|
||||
scriptVal,err := ServiceState.UsbGM.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)
|
||||
@ -393,7 +392,7 @@ func StartRpcServerAndWeb(host string, gRPCPort string, webPort string, absWebRo
|
||||
if strings.Contains(req.Header.Get("Content-Type"), "application/grpc") ||
|
||||
req.Method == "OPTIONS" ||
|
||||
strings.Contains(req.Header.Get("Sec-Websocket-Protocol"), "grpc-websockets") {
|
||||
fmt.Printf("gRPC-web req:\n %v\n", req)
|
||||
//fmt.Printf("gRPC-web req:\n %v\n", req)
|
||||
grpc_web_srv.ServeHTTP(resp, req) // if content type indicates grpc or REQUEST METHOD IS OPTIONS (pre-flight) serve gRPC-web
|
||||
} else {
|
||||
fmt.Printf("legacy web req:\n %v\n", req)
|
||||
|
@ -1,7 +1,6 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"../hid"
|
||||
pb "../proto"
|
||||
)
|
||||
|
||||
@ -9,7 +8,6 @@ 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
|
||||
|
@ -82,6 +82,11 @@ type UsbGadgetManager struct {
|
||||
UndeployedGadgetSettings *pb.GadgetSettings
|
||||
}
|
||||
|
||||
func (gm *UsbGadgetManager) HandleEvent(event hid.Event) {
|
||||
fmt.Printf("GADGET MANAGER HID EVENT: %+v\n", event)
|
||||
ServiceState.EvMgr.Emit(ConstructEventHID(event))
|
||||
}
|
||||
|
||||
func NewUSBGadgetManager() (newUGM *UsbGadgetManager, err error) {
|
||||
newUGM = &UsbGadgetManager{}
|
||||
defGS := GetDefaultGadgetSettings()
|
||||
@ -631,6 +636,7 @@ func (gm *UsbGadgetManager) DeployGadgetSettings(settings *pb.GadgetSettings) er
|
||||
|
||||
var errH error
|
||||
gm.HidCtl, errH = hid.NewHIDController(context.Background(), devPathKeyboard, USB_KEYBOARD_LANGUAGE_MAP_PATH, devPathMouse)
|
||||
gm.HidCtl.SetEventHandler(gm)
|
||||
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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user