Service emit HID controller events via gRPC

This commit is contained in:
MaMe82 2018-07-29 02:46:17 +02:00
parent e153064605
commit ecee187f0d
5 changed files with 61 additions and 68 deletions

View File

@ -1,7 +1,8 @@
package common
const (
EVT_ANY = int64(1)
EVT_ANY = int64(0)
EVT_LOG = int64(1)
EVT_HID = int64(2)
)

View File

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

View File

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

View File

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

View File

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