Introduced events (gRPC server streaming) for server,CLI and WEBCLIENTgit add www/

This commit is contained in:
mame82 2018-07-20 14:59:25 +00:00
parent 344517f138
commit 9c9454a563
15 changed files with 3408 additions and 1776 deletions

View File

@ -5,60 +5,5 @@ import (
)
func main() {
/*
//Parse cli flags, should be replaced with cobra
getUsbGadgetConf := flag.Bool("get_gadget_state", false, "Retrieves the current USB gadget state")
blinkCountPtr := flag.Int("blink", -1, "LED blink count (0 = LED off, 255 = LED solid, 1..254 blink n times)")
var rpcHostPtr string
var rpcPortPtr string
flag.StringVar(&rpcHostPtr, "host", "localhost", "The remote RPC host running P4wnP1 service")
flag.StringVar(&rpcPortPtr, "port", "50051", "The remote RPC port of P4wnP1 service")
flag.Parse()
*/
cli_client.Execute()
/*
// Set up a connection to the server.
address := rpcHostPtr + ":" + rpcPortPtr
log.Printf("Connecting %s ...", address)
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewP4WNP1Client(conn)
// Contact the server
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if *blinkCountPtr >= 0 {
_, err1 := c.SetLEDSettings(ctx, &pb.LEDSettings{BlinkCount: uint32(*blinkCountPtr)})
if err1 != nil {
log.Printf("Error setting LED blink count %d: %v", *blinkCountPtr, err1)
}
}
if *getUsbGadgetConf {
r, err := c.GetGadgetSettings(ctx, &pb.Empty{})
if err != nil {
log.Fatalf("could not get GadgetSettings: %v", err)
}
log.Printf("USB Settings %s: %+v", reflect.TypeOf(*r), *r)
}
*/
/*
r, err := c.GetGadgetSettings(ctx, &pb.Empty{})
if err != nil {
log.Fatalf("could not get GadgetSettings: %v", err)
}
log.Printf("USB Settings %s: %+v", reflect.TypeOf(*r), *r)
log.Printf("Set LED to blink count 3")
c.SetLEDSettings(ctx, &pb.LEDSettings{ BlinkCount: 3})
*/
}

View File

@ -10,6 +10,8 @@ import (
"fmt"
pb "./proto"
"./common"
"time"
"strconv"
)
func main() {
@ -48,12 +50,24 @@ func main() {
//Indicate servers up with LED blink count 1
service.SetLed(pb.LEDSettings{1})
service.StartEventManager(20)
go func() {
err := common.RunBashScript("/usr/local/P4wnP1/scripts/servicestart.sh")
if err != nil { log.Printf("Error executing service startup script: %v\n", err) }
}()
//Send some log messages for testing
i := 0
go func() {
for {
service.EvMgr.Emit(service.ConstructEventLog("test "+strconv.Itoa(i), "message"))
time.Sleep(time.Second)
i++
}
}()
//use a channel to wait for SIGTERM or SIGINT
fmt.Println("P4wnP1 service initialized, stop with SIGTERM or SIGINT")

View File

@ -49,13 +49,19 @@ LOGGING:
- consistent logging (no mix between STDOUT/STDERR)
- reduce logging of gadget setting changes (only if settings are deployed)
Events:
- remove debug out
- proper unregister of event listeners from web app
OTHER:
- extend installer to movee HIDScripts to a fixed absolute path
- proper error extraction from gRPC calls
TO FIX:
- remove dependencies of CLI client on service package
- debug out of HIDScript puts way to much CPU load on journaling daemon (floods logs)
- allow gRPC server to abort Running HID scripts on context.Done() -> possible, testing needed
- jobs aren't deleted from global job list, unless result is fetched with waitResult. This affects interrupted
jobs (f.e. timeout) and jobs run as background job --> cancelled jobs need a way to communicate back to the controller,
that they could be deleted (Solution: goroutine listening for context.Done() per job in controller)
that they could be deleted (Solution: goroutine listening for context.Done() per job in controller)

27
cli_client/cmd_event.go Normal file
View File

@ -0,0 +1,27 @@
package cli_client
import (
"github.com/spf13/cobra"
"../common"
"log"
)
// usbCmd represents the usb command
var evtCmd = &cobra.Command{
Use: "EVT",
Short: "Receive P4wnP1 service events",
Run: func(cmd *cobra.Command, args []string) {
err := receiveEvent(common.EVT_LOG)
if err != nil { log.Fatal(err)}
},
}
func receiveEvent(eType int64) (err error) {
return ClientRegisterEvent(StrRemoteHost, StrRemotePort, eType)
}
func init() {
rootCmd.AddCommand(evtCmd)
}

View File

@ -75,6 +75,26 @@ func ClientUploadFileFromSrcPath(host string, port string, srcPath string, destP
return ClientUploadFile(host,port,f,destPath,forceOverwrite)
}
func ClientRegisterEvent(host string, port string, evtType int64) (err error) {
// open gRPC Client
address := host + ":" + port
connection, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {return}
defer connection.Close()
client := pb.NewP4WNP1Client(connection)
evStream, err := client.EventListen(context.Background(), &pb.EventRequest{ListenType: evtType})
if err != nil { return err }
for {
event, err := evStream.Recv()
if err == io.EOF { break }
if err != nil { return err }
log.Printf("Event: %+v", event)
}
return nil
}
func ClientUploadFile(host string, port string, src io.Reader, destPath string, forceOverwrite bool) (err error) {
// open gRPC Client

7
common/EventConst.go Normal file
View File

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

View File

@ -8,6 +8,9 @@
grpc.proto
It has these top-level messages:
EventRequest
EventValue
Event
TempDirOrFileRequest
TempDirOrFileResponse
ReadFileRequest
@ -111,6 +114,286 @@ func (x WiFiSettings_APAuthMode) String() string {
return WiFiSettings_APAuthMode_name[int(x)]
}
// Events
type EventRequest struct {
ListenType int64
}
// GetListenType gets the ListenType of the EventRequest.
func (m *EventRequest) GetListenType() (x int64) {
if m == nil {
return x
}
return m.ListenType
}
// MarshalToWriter marshals EventRequest to the provided writer.
func (m *EventRequest) MarshalToWriter(writer jspb.Writer) {
if m == nil {
return
}
if m.ListenType != 0 {
writer.WriteInt64(1, m.ListenType)
}
return
}
// Marshal marshals EventRequest to a slice of bytes.
func (m *EventRequest) Marshal() []byte {
writer := jspb.NewWriter()
m.MarshalToWriter(writer)
return writer.GetResult()
}
// UnmarshalFromReader unmarshals a EventRequest from the provided reader.
func (m *EventRequest) UnmarshalFromReader(reader jspb.Reader) *EventRequest {
for reader.Next() {
if m == nil {
m = &EventRequest{}
}
switch reader.GetFieldNumber() {
case 1:
m.ListenType = reader.ReadInt64()
default:
reader.SkipField()
}
}
return m
}
// Unmarshal unmarshals a EventRequest from a slice of bytes.
func (m *EventRequest) Unmarshal(rawBytes []byte) (*EventRequest, error) {
reader := jspb.NewReader(rawBytes)
m = m.UnmarshalFromReader(reader)
if err := reader.Err(); err != nil {
return nil, err
}
return m, nil
}
type EventValue struct {
// Types that are valid to be assigned to Val:
// *EventValue_Tstring
// *EventValue_Tbool
// *EventValue_Tint64
Val isEventValue_Val
}
// isEventValue_Val is used to distinguish types assignable to Val
type isEventValue_Val interface{ isEventValue_Val() }
// EventValue_Tstring is assignable to Val
type EventValue_Tstring struct {
Tstring string
}
// EventValue_Tbool is assignable to Val
type EventValue_Tbool struct {
Tbool bool
}
// EventValue_Tint64 is assignable to Val
type EventValue_Tint64 struct {
Tint64 int64
}
func (*EventValue_Tstring) isEventValue_Val() {}
func (*EventValue_Tbool) isEventValue_Val() {}
func (*EventValue_Tint64) isEventValue_Val() {}
// GetVal gets the Val of the EventValue.
func (m *EventValue) GetVal() (x isEventValue_Val) {
if m == nil {
return x
}
return m.Val
}
// GetTstring gets the Tstring of the EventValue.
func (m *EventValue) GetTstring() (x string) {
if v, ok := m.GetVal().(*EventValue_Tstring); ok {
return v.Tstring
}
return x
}
// GetTbool gets the Tbool of the EventValue.
func (m *EventValue) GetTbool() (x bool) {
if v, ok := m.GetVal().(*EventValue_Tbool); ok {
return v.Tbool
}
return x
}
// GetTint64 gets the Tint64 of the EventValue.
func (m *EventValue) GetTint64() (x int64) {
if v, ok := m.GetVal().(*EventValue_Tint64); ok {
return v.Tint64
}
return x
}
// MarshalToWriter marshals EventValue to the provided writer.
func (m *EventValue) MarshalToWriter(writer jspb.Writer) {
if m == nil {
return
}
switch t := m.Val.(type) {
case *EventValue_Tstring:
if len(t.Tstring) > 0 {
writer.WriteString(1, t.Tstring)
}
case *EventValue_Tbool:
if t.Tbool {
writer.WriteBool(2, t.Tbool)
}
case *EventValue_Tint64:
if t.Tint64 != 0 {
writer.WriteInt64(3, t.Tint64)
}
}
return
}
// Marshal marshals EventValue to a slice of bytes.
func (m *EventValue) Marshal() []byte {
writer := jspb.NewWriter()
m.MarshalToWriter(writer)
return writer.GetResult()
}
// UnmarshalFromReader unmarshals a EventValue from the provided reader.
func (m *EventValue) UnmarshalFromReader(reader jspb.Reader) *EventValue {
for reader.Next() {
if m == nil {
m = &EventValue{}
}
switch reader.GetFieldNumber() {
case 1:
m.Val = &EventValue_Tstring{
Tstring: reader.ReadString(),
}
case 2:
m.Val = &EventValue_Tbool{
Tbool: reader.ReadBool(),
}
case 3:
m.Val = &EventValue_Tint64{
Tint64: reader.ReadInt64(),
}
default:
reader.SkipField()
}
}
return m
}
// Unmarshal unmarshals a EventValue from a slice of bytes.
func (m *EventValue) Unmarshal(rawBytes []byte) (*EventValue, error) {
reader := jspb.NewReader(rawBytes)
m = m.UnmarshalFromReader(reader)
if err := reader.Err(); err != nil {
return nil, err
}
return m, nil
}
type Event struct {
Type int64
Values []*EventValue
}
// GetType gets the Type of the Event.
func (m *Event) GetType() (x int64) {
if m == nil {
return x
}
return m.Type
}
// GetValues gets the Values of the Event.
func (m *Event) GetValues() (x []*EventValue) {
if m == nil {
return x
}
return m.Values
}
// MarshalToWriter marshals Event to the provided writer.
func (m *Event) MarshalToWriter(writer jspb.Writer) {
if m == nil {
return
}
if m.Type != 0 {
writer.WriteInt64(1, m.Type)
}
for _, msg := range m.Values {
writer.WriteMessage(2, func() {
msg.MarshalToWriter(writer)
})
}
return
}
// Marshal marshals Event to a slice of bytes.
func (m *Event) Marshal() []byte {
writer := jspb.NewWriter()
m.MarshalToWriter(writer)
return writer.GetResult()
}
// UnmarshalFromReader unmarshals a Event from the provided reader.
func (m *Event) UnmarshalFromReader(reader jspb.Reader) *Event {
for reader.Next() {
if m == nil {
m = &Event{}
}
switch reader.GetFieldNumber() {
case 1:
m.Type = reader.ReadInt64()
case 2:
reader.ReadMessage(func() {
m.Values = append(m.Values, new(EventValue).UnmarshalFromReader(reader))
})
default:
reader.SkipField()
}
}
return m
}
// Unmarshal unmarshals a Event from a slice of bytes.
func (m *Event) Unmarshal(rawBytes []byte) (*Event, error) {
reader := jspb.NewReader(rawBytes)
m = m.UnmarshalFromReader(reader)
if err := reader.Err(); err != nil {
return nil, err
}
return m, nil
}
// File System
type TempDirOrFileRequest struct {
Dir string
@ -2398,6 +2681,7 @@ const _ = grpcweb.GrpcWebPackageIsVersion3
// Client API for P4WNP1 service
type P4WNP1Client interface {
// USB gadget
GetDeployedGadgetSetting(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*GadgetSettings, error)
DeployGadgetSetting(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*GadgetSettings, error)
GetGadgetSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*GadgetSettings, error)
@ -2405,18 +2689,24 @@ type P4WNP1Client interface {
GetLEDSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*LEDSettings, error)
SetLEDSettings(ctx context.Context, in *LEDSettings, opts ...grpcweb.CallOption) (*Empty, error)
MountUMSFile(ctx context.Context, in *GadgetSettingsUMS, opts ...grpcweb.CallOption) (*Empty, error)
// Ethernet
DeployEthernetInterfaceSettings(ctx context.Context, in *EthernetInterfaceSettings, opts ...grpcweb.CallOption) (*Empty, error)
// WiFi
DeployWifiSettings(ctx context.Context, in *WiFiSettings, opts ...grpcweb.CallOption) (*Empty, error)
// HIDScript / job management
HIDRunScript(ctx context.Context, in *HIDScriptRequest, opts ...grpcweb.CallOption) (*HIDScriptResult, error)
HIDRunScriptJob(ctx context.Context, in *HIDScriptRequest, opts ...grpcweb.CallOption) (*HIDScriptJob, error)
HIDGetScriptJobResult(ctx context.Context, in *HIDScriptJob, opts ...grpcweb.CallOption) (*HIDScriptResult, error)
HIDCancelScriptJob(ctx context.Context, in *HIDScriptJob, opts ...grpcweb.CallOption) (*Empty, error)
HIDGetRunningScriptJobs(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*HIDScriptJobList, error)
HIDCancelAllScriptJobs(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*Empty, error)
// FileSystem
FSWriteFile(ctx context.Context, in *WriteFileRequest, opts ...grpcweb.CallOption) (*Empty, error)
FSReadFile(ctx context.Context, in *ReadFileRequest, opts ...grpcweb.CallOption) (*ReadFileResponse, error)
FSGetFileInfo(ctx context.Context, in *FileInfoRequest, opts ...grpcweb.CallOption) (*FileInfoResponse, error)
FSCreateTempDirOrFile(ctx context.Context, in *TempDirOrFileRequest, opts ...grpcweb.CallOption) (*TempDirOrFileResponse, error)
// Events
EventListen(ctx context.Context, in *EventRequest, opts ...grpcweb.CallOption) (P4WNP1_EventListenClient, error)
}
type p4WNP1Client struct {
@ -2600,3 +2890,35 @@ func (c *p4WNP1Client) FSCreateTempDirOrFile(ctx context.Context, in *TempDirOrF
return new(TempDirOrFileResponse).Unmarshal(resp)
}
func (c *p4WNP1Client) EventListen(ctx context.Context, in *EventRequest, opts ...grpcweb.CallOption) (P4WNP1_EventListenClient, error) {
srv, err := c.client.NewClientStream(ctx, false, true, "EventListen", opts...)
if err != nil {
return nil, err
}
err = srv.SendMsg(in.Marshal())
if err != nil {
return nil, err
}
return &p4WNP1EventListenClient{srv}, nil
}
type P4WNP1_EventListenClient interface {
Recv() (*Event, error)
grpcweb.ClientStream
}
type p4WNP1EventListenClient struct {
grpcweb.ClientStream
}
func (x *p4WNP1EventListenClient) Recv() (*Event, error) {
resp, err := x.RecvMsg()
if err != nil {
return nil, err
}
return new(Event).Unmarshal(resp)
}

View File

@ -8,6 +8,9 @@ It is generated from these files:
grpc.proto
It has these top-level messages:
EventRequest
EventValue
Event
TempDirOrFileRequest
TempDirOrFileResponse
ReadFileRequest
@ -76,7 +79,7 @@ func (x EthernetInterfaceSettings_Mode) String() string {
return proto.EnumName(EthernetInterfaceSettings_Mode_name, int32(x))
}
func (EthernetInterfaceSettings_Mode) EnumDescriptor() ([]byte, []int) {
return fileDescriptor0, []int{15, 0}
return fileDescriptor0, []int{18, 0}
}
type WiFiSettings_Mode int32
@ -101,7 +104,7 @@ var WiFiSettings_Mode_value = map[string]int32{
func (x WiFiSettings_Mode) String() string {
return proto.EnumName(WiFiSettings_Mode_name, int32(x))
}
func (WiFiSettings_Mode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{19, 0} }
func (WiFiSettings_Mode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{22, 0} }
type WiFiSettings_APAuthMode int32
@ -122,7 +125,190 @@ var WiFiSettings_APAuthMode_value = map[string]int32{
func (x WiFiSettings_APAuthMode) String() string {
return proto.EnumName(WiFiSettings_APAuthMode_name, int32(x))
}
func (WiFiSettings_APAuthMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{19, 1} }
func (WiFiSettings_APAuthMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{22, 1} }
// Events
type EventRequest struct {
ListenType int64 `protobuf:"varint,1,opt,name=listenType" json:"listenType,omitempty"`
}
func (m *EventRequest) Reset() { *m = EventRequest{} }
func (m *EventRequest) String() string { return proto.CompactTextString(m) }
func (*EventRequest) ProtoMessage() {}
func (*EventRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *EventRequest) GetListenType() int64 {
if m != nil {
return m.ListenType
}
return 0
}
type EventValue struct {
// Types that are valid to be assigned to Val:
// *EventValue_Tstring
// *EventValue_Tbool
// *EventValue_Tint64
Val isEventValue_Val `protobuf_oneof:"val"`
}
func (m *EventValue) Reset() { *m = EventValue{} }
func (m *EventValue) String() string { return proto.CompactTextString(m) }
func (*EventValue) ProtoMessage() {}
func (*EventValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type isEventValue_Val interface {
isEventValue_Val()
}
type EventValue_Tstring struct {
Tstring string `protobuf:"bytes,1,opt,name=tstring,oneof"`
}
type EventValue_Tbool struct {
Tbool bool `protobuf:"varint,2,opt,name=tbool,oneof"`
}
type EventValue_Tint64 struct {
Tint64 int64 `protobuf:"varint,3,opt,name=tint64,oneof"`
}
func (*EventValue_Tstring) isEventValue_Val() {}
func (*EventValue_Tbool) isEventValue_Val() {}
func (*EventValue_Tint64) isEventValue_Val() {}
func (m *EventValue) GetVal() isEventValue_Val {
if m != nil {
return m.Val
}
return nil
}
func (m *EventValue) GetTstring() string {
if x, ok := m.GetVal().(*EventValue_Tstring); ok {
return x.Tstring
}
return ""
}
func (m *EventValue) GetTbool() bool {
if x, ok := m.GetVal().(*EventValue_Tbool); ok {
return x.Tbool
}
return false
}
func (m *EventValue) GetTint64() int64 {
if x, ok := m.GetVal().(*EventValue_Tint64); ok {
return x.Tint64
}
return 0
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*EventValue) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _EventValue_OneofMarshaler, _EventValue_OneofUnmarshaler, _EventValue_OneofSizer, []interface{}{
(*EventValue_Tstring)(nil),
(*EventValue_Tbool)(nil),
(*EventValue_Tint64)(nil),
}
}
func _EventValue_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*EventValue)
// val
switch x := m.Val.(type) {
case *EventValue_Tstring:
b.EncodeVarint(1<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Tstring)
case *EventValue_Tbool:
t := uint64(0)
if x.Tbool {
t = 1
}
b.EncodeVarint(2<<3 | proto.WireVarint)
b.EncodeVarint(t)
case *EventValue_Tint64:
b.EncodeVarint(3<<3 | proto.WireVarint)
b.EncodeVarint(uint64(x.Tint64))
case nil:
default:
return fmt.Errorf("EventValue.Val has unexpected type %T", x)
}
return nil
}
func _EventValue_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*EventValue)
switch tag {
case 1: // val.tstring
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Val = &EventValue_Tstring{x}
return true, err
case 2: // val.tbool
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Val = &EventValue_Tbool{x != 0}
return true, err
case 3: // val.tint64
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Val = &EventValue_Tint64{int64(x)}
return true, err
default:
return false, nil
}
}
func _EventValue_OneofSizer(msg proto.Message) (n int) {
m := msg.(*EventValue)
// val
switch x := m.Val.(type) {
case *EventValue_Tstring:
n += proto.SizeVarint(1<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Tstring)))
n += len(x.Tstring)
case *EventValue_Tbool:
n += proto.SizeVarint(2<<3 | proto.WireVarint)
n += 1
case *EventValue_Tint64:
n += proto.SizeVarint(3<<3 | proto.WireVarint)
n += proto.SizeVarint(uint64(x.Tint64))
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
type Event struct {
Type int64 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"`
Values []*EventValue `protobuf:"bytes,2,rep,name=values" json:"values,omitempty"`
}
func (m *Event) Reset() { *m = Event{} }
func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *Event) GetType() int64 {
if m != nil {
return m.Type
}
return 0
}
func (m *Event) GetValues() []*EventValue {
if m != nil {
return m.Values
}
return nil
}
// File System
type TempDirOrFileRequest struct {
@ -134,7 +320,7 @@ type TempDirOrFileRequest struct {
func (m *TempDirOrFileRequest) Reset() { *m = TempDirOrFileRequest{} }
func (m *TempDirOrFileRequest) String() string { return proto.CompactTextString(m) }
func (*TempDirOrFileRequest) ProtoMessage() {}
func (*TempDirOrFileRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*TempDirOrFileRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *TempDirOrFileRequest) GetDir() string {
if m != nil {
@ -164,7 +350,7 @@ type TempDirOrFileResponse struct {
func (m *TempDirOrFileResponse) Reset() { *m = TempDirOrFileResponse{} }
func (m *TempDirOrFileResponse) String() string { return proto.CompactTextString(m) }
func (*TempDirOrFileResponse) ProtoMessage() {}
func (*TempDirOrFileResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (*TempDirOrFileResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *TempDirOrFileResponse) GetResultPath() string {
if m != nil {
@ -182,7 +368,7 @@ type ReadFileRequest struct {
func (m *ReadFileRequest) Reset() { *m = ReadFileRequest{} }
func (m *ReadFileRequest) String() string { return proto.CompactTextString(m) }
func (*ReadFileRequest) ProtoMessage() {}
func (*ReadFileRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (*ReadFileRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (m *ReadFileRequest) GetPath() string {
if m != nil {
@ -212,7 +398,7 @@ type ReadFileResponse struct {
func (m *ReadFileResponse) Reset() { *m = ReadFileResponse{} }
func (m *ReadFileResponse) String() string { return proto.CompactTextString(m) }
func (*ReadFileResponse) ProtoMessage() {}
func (*ReadFileResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (*ReadFileResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *ReadFileResponse) GetReadCount() int64 {
if m != nil {
@ -231,7 +417,7 @@ type WriteFileRequest struct {
func (m *WriteFileRequest) Reset() { *m = WriteFileRequest{} }
func (m *WriteFileRequest) String() string { return proto.CompactTextString(m) }
func (*WriteFileRequest) ProtoMessage() {}
func (*WriteFileRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (*WriteFileRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *WriteFileRequest) GetPath() string {
if m != nil {
@ -268,7 +454,7 @@ type FileInfoRequest struct {
func (m *FileInfoRequest) Reset() { *m = FileInfoRequest{} }
func (m *FileInfoRequest) String() string { return proto.CompactTextString(m) }
func (*FileInfoRequest) ProtoMessage() {}
func (*FileInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (*FileInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (m *FileInfoRequest) GetPath() string {
if m != nil {
@ -288,7 +474,7 @@ type FileInfoResponse struct {
func (m *FileInfoResponse) Reset() { *m = FileInfoResponse{} }
func (m *FileInfoResponse) String() string { return proto.CompactTextString(m) }
func (*FileInfoResponse) ProtoMessage() {}
func (*FileInfoResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (*FileInfoResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
func (m *FileInfoResponse) GetName() string {
if m != nil {
@ -334,7 +520,7 @@ type HIDScriptRequest struct {
func (m *HIDScriptRequest) Reset() { *m = HIDScriptRequest{} }
func (m *HIDScriptRequest) String() string { return proto.CompactTextString(m) }
func (*HIDScriptRequest) ProtoMessage() {}
func (*HIDScriptRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (*HIDScriptRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
func (m *HIDScriptRequest) GetScriptPath() string {
if m != nil {
@ -357,7 +543,7 @@ type HIDScriptJob struct {
func (m *HIDScriptJob) Reset() { *m = HIDScriptJob{} }
func (m *HIDScriptJob) String() string { return proto.CompactTextString(m) }
func (*HIDScriptJob) ProtoMessage() {}
func (*HIDScriptJob) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (*HIDScriptJob) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
func (m *HIDScriptJob) GetId() uint32 {
if m != nil {
@ -373,7 +559,7 @@ type HIDScriptJobList struct {
func (m *HIDScriptJobList) Reset() { *m = HIDScriptJobList{} }
func (m *HIDScriptJobList) String() string { return proto.CompactTextString(m) }
func (*HIDScriptJobList) ProtoMessage() {}
func (*HIDScriptJobList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
func (*HIDScriptJobList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (m *HIDScriptJobList) GetIds() []uint32 {
if m != nil {
@ -391,7 +577,7 @@ type HIDScriptResult struct {
func (m *HIDScriptResult) Reset() { *m = HIDScriptResult{} }
func (m *HIDScriptResult) String() string { return proto.CompactTextString(m) }
func (*HIDScriptResult) ProtoMessage() {}
func (*HIDScriptResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
func (*HIDScriptResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
func (m *HIDScriptResult) GetJob() *HIDScriptJob {
if m != nil {
@ -422,7 +608,7 @@ type LEDSettings struct {
func (m *LEDSettings) Reset() { *m = LEDSettings{} }
func (m *LEDSettings) String() string { return proto.CompactTextString(m) }
func (*LEDSettings) ProtoMessage() {}
func (*LEDSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
func (*LEDSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
func (m *LEDSettings) GetBlinkCount() uint32 {
if m != nil {
@ -454,7 +640,7 @@ type GadgetSettings struct {
func (m *GadgetSettings) Reset() { *m = GadgetSettings{} }
func (m *GadgetSettings) String() string { return proto.CompactTextString(m) }
func (*GadgetSettings) ProtoMessage() {}
func (*GadgetSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (*GadgetSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
func (m *GadgetSettings) GetEnabled() bool {
if m != nil {
@ -576,7 +762,7 @@ type GadgetSettingsEthernet struct {
func (m *GadgetSettingsEthernet) Reset() { *m = GadgetSettingsEthernet{} }
func (m *GadgetSettingsEthernet) String() string { return proto.CompactTextString(m) }
func (*GadgetSettingsEthernet) ProtoMessage() {}
func (*GadgetSettingsEthernet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
func (*GadgetSettingsEthernet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
func (m *GadgetSettingsEthernet) GetHostAddr() string {
if m != nil {
@ -600,7 +786,7 @@ type GadgetSettingsUMS struct {
func (m *GadgetSettingsUMS) Reset() { *m = GadgetSettingsUMS{} }
func (m *GadgetSettingsUMS) String() string { return proto.CompactTextString(m) }
func (*GadgetSettingsUMS) ProtoMessage() {}
func (*GadgetSettingsUMS) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
func (*GadgetSettingsUMS) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
func (m *GadgetSettingsUMS) GetCdrom() bool {
if m != nil {
@ -628,7 +814,7 @@ type EthernetInterfaceSettings struct {
func (m *EthernetInterfaceSettings) Reset() { *m = EthernetInterfaceSettings{} }
func (m *EthernetInterfaceSettings) String() string { return proto.CompactTextString(m) }
func (*EthernetInterfaceSettings) ProtoMessage() {}
func (*EthernetInterfaceSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
func (*EthernetInterfaceSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
func (m *EthernetInterfaceSettings) GetName() string {
if m != nil {
@ -689,7 +875,7 @@ type DHCPServerSettings struct {
func (m *DHCPServerSettings) Reset() { *m = DHCPServerSettings{} }
func (m *DHCPServerSettings) String() string { return proto.CompactTextString(m) }
func (*DHCPServerSettings) ProtoMessage() {}
func (*DHCPServerSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
func (*DHCPServerSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
func (m *DHCPServerSettings) GetListenPort() uint32 {
if m != nil {
@ -764,7 +950,7 @@ type DHCPServerRange struct {
func (m *DHCPServerRange) Reset() { *m = DHCPServerRange{} }
func (m *DHCPServerRange) String() string { return proto.CompactTextString(m) }
func (*DHCPServerRange) ProtoMessage() {}
func (*DHCPServerRange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
func (*DHCPServerRange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} }
func (m *DHCPServerRange) GetRangeLower() string {
if m != nil {
@ -796,7 +982,7 @@ type DHCPServerStaticHost struct {
func (m *DHCPServerStaticHost) Reset() { *m = DHCPServerStaticHost{} }
func (m *DHCPServerStaticHost) String() string { return proto.CompactTextString(m) }
func (*DHCPServerStaticHost) ProtoMessage() {}
func (*DHCPServerStaticHost) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
func (*DHCPServerStaticHost) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} }
func (m *DHCPServerStaticHost) GetMac() string {
if m != nil {
@ -828,7 +1014,7 @@ type WiFiSettings struct {
func (m *WiFiSettings) Reset() { *m = WiFiSettings{} }
func (m *WiFiSettings) String() string { return proto.CompactTextString(m) }
func (*WiFiSettings) ProtoMessage() {}
func (*WiFiSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
func (*WiFiSettings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} }
func (m *WiFiSettings) GetDisabled() bool {
if m != nil {
@ -901,7 +1087,7 @@ type BSSCfg struct {
func (m *BSSCfg) Reset() { *m = BSSCfg{} }
func (m *BSSCfg) String() string { return proto.CompactTextString(m) }
func (*BSSCfg) ProtoMessage() {}
func (*BSSCfg) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} }
func (*BSSCfg) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} }
func (m *BSSCfg) GetSSID() string {
if m != nil {
@ -923,9 +1109,12 @@ type Empty struct {
func (m *Empty) Reset() { *m = Empty{} }
func (m *Empty) String() string { return proto.CompactTextString(m) }
func (*Empty) ProtoMessage() {}
func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} }
func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
func init() {
proto.RegisterType((*EventRequest)(nil), "P4wnP1_grpc.EventRequest")
proto.RegisterType((*EventValue)(nil), "P4wnP1_grpc.EventValue")
proto.RegisterType((*Event)(nil), "P4wnP1_grpc.Event")
proto.RegisterType((*TempDirOrFileRequest)(nil), "P4wnP1_grpc.TempDirOrFileRequest")
proto.RegisterType((*TempDirOrFileResponse)(nil), "P4wnP1_grpc.TempDirOrFileResponse")
proto.RegisterType((*ReadFileRequest)(nil), "P4wnP1_grpc.ReadFileRequest")
@ -964,6 +1153,7 @@ const _ = grpc.SupportPackageIsVersion4
// Client API for P4WNP1 service
type P4WNP1Client interface {
// USB gadget
GetDeployedGadgetSetting(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GadgetSettings, error)
DeployGadgetSetting(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GadgetSettings, error)
GetGadgetSettings(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GadgetSettings, error)
@ -971,18 +1161,24 @@ type P4WNP1Client interface {
GetLEDSettings(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*LEDSettings, error)
SetLEDSettings(ctx context.Context, in *LEDSettings, opts ...grpc.CallOption) (*Empty, error)
MountUMSFile(ctx context.Context, in *GadgetSettingsUMS, opts ...grpc.CallOption) (*Empty, error)
// Ethernet
DeployEthernetInterfaceSettings(ctx context.Context, in *EthernetInterfaceSettings, opts ...grpc.CallOption) (*Empty, error)
// WiFi
DeployWifiSettings(ctx context.Context, in *WiFiSettings, opts ...grpc.CallOption) (*Empty, error)
// HIDScript / job management
HIDRunScript(ctx context.Context, in *HIDScriptRequest, opts ...grpc.CallOption) (*HIDScriptResult, error)
HIDRunScriptJob(ctx context.Context, in *HIDScriptRequest, opts ...grpc.CallOption) (*HIDScriptJob, error)
HIDGetScriptJobResult(ctx context.Context, in *HIDScriptJob, opts ...grpc.CallOption) (*HIDScriptResult, error)
HIDCancelScriptJob(ctx context.Context, in *HIDScriptJob, opts ...grpc.CallOption) (*Empty, error)
HIDGetRunningScriptJobs(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*HIDScriptJobList, error)
HIDCancelAllScriptJobs(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
// FileSystem
FSWriteFile(ctx context.Context, in *WriteFileRequest, opts ...grpc.CallOption) (*Empty, error)
FSReadFile(ctx context.Context, in *ReadFileRequest, opts ...grpc.CallOption) (*ReadFileResponse, error)
FSGetFileInfo(ctx context.Context, in *FileInfoRequest, opts ...grpc.CallOption) (*FileInfoResponse, error)
FSCreateTempDirOrFile(ctx context.Context, in *TempDirOrFileRequest, opts ...grpc.CallOption) (*TempDirOrFileResponse, error)
// Events
EventListen(ctx context.Context, in *EventRequest, opts ...grpc.CallOption) (P4WNP1_EventListenClient, error)
}
type p4WNP1Client struct {
@ -1164,9 +1360,42 @@ func (c *p4WNP1Client) FSCreateTempDirOrFile(ctx context.Context, in *TempDirOrF
return out, nil
}
func (c *p4WNP1Client) EventListen(ctx context.Context, in *EventRequest, opts ...grpc.CallOption) (P4WNP1_EventListenClient, error) {
stream, err := grpc.NewClientStream(ctx, &_P4WNP1_serviceDesc.Streams[0], c.cc, "/P4wnP1_grpc.P4WNP1/EventListen", opts...)
if err != nil {
return nil, err
}
x := &p4WNP1EventListenClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type P4WNP1_EventListenClient interface {
Recv() (*Event, error)
grpc.ClientStream
}
type p4WNP1EventListenClient struct {
grpc.ClientStream
}
func (x *p4WNP1EventListenClient) Recv() (*Event, error) {
m := new(Event)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// Server API for P4WNP1 service
type P4WNP1Server interface {
// USB gadget
GetDeployedGadgetSetting(context.Context, *Empty) (*GadgetSettings, error)
DeployGadgetSetting(context.Context, *Empty) (*GadgetSettings, error)
GetGadgetSettings(context.Context, *Empty) (*GadgetSettings, error)
@ -1174,18 +1403,24 @@ type P4WNP1Server interface {
GetLEDSettings(context.Context, *Empty) (*LEDSettings, error)
SetLEDSettings(context.Context, *LEDSettings) (*Empty, error)
MountUMSFile(context.Context, *GadgetSettingsUMS) (*Empty, error)
// Ethernet
DeployEthernetInterfaceSettings(context.Context, *EthernetInterfaceSettings) (*Empty, error)
// WiFi
DeployWifiSettings(context.Context, *WiFiSettings) (*Empty, error)
// HIDScript / job management
HIDRunScript(context.Context, *HIDScriptRequest) (*HIDScriptResult, error)
HIDRunScriptJob(context.Context, *HIDScriptRequest) (*HIDScriptJob, error)
HIDGetScriptJobResult(context.Context, *HIDScriptJob) (*HIDScriptResult, error)
HIDCancelScriptJob(context.Context, *HIDScriptJob) (*Empty, error)
HIDGetRunningScriptJobs(context.Context, *Empty) (*HIDScriptJobList, error)
HIDCancelAllScriptJobs(context.Context, *Empty) (*Empty, error)
// FileSystem
FSWriteFile(context.Context, *WriteFileRequest) (*Empty, error)
FSReadFile(context.Context, *ReadFileRequest) (*ReadFileResponse, error)
FSGetFileInfo(context.Context, *FileInfoRequest) (*FileInfoResponse, error)
FSCreateTempDirOrFile(context.Context, *TempDirOrFileRequest) (*TempDirOrFileResponse, error)
// Events
EventListen(*EventRequest, P4WNP1_EventListenServer) error
}
func RegisterP4WNP1Server(s *grpc.Server, srv P4WNP1Server) {
@ -1534,6 +1769,27 @@ func _P4WNP1_FSCreateTempDirOrFile_Handler(srv interface{}, ctx context.Context,
return interceptor(ctx, in, info, handler)
}
func _P4WNP1_EventListen_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(EventRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(P4WNP1Server).EventListen(m, &p4WNP1EventListenServer{stream})
}
type P4WNP1_EventListenServer interface {
Send(*Event) error
grpc.ServerStream
}
type p4WNP1EventListenServer struct {
grpc.ServerStream
}
func (x *p4WNP1EventListenServer) Send(m *Event) error {
return x.ServerStream.SendMsg(m)
}
var _P4WNP1_serviceDesc = grpc.ServiceDesc{
ServiceName: "P4wnP1_grpc.P4WNP1",
HandlerType: (*P4WNP1Server)(nil),
@ -1615,126 +1871,140 @@ var _P4WNP1_serviceDesc = grpc.ServiceDesc{
Handler: _P4WNP1_FSCreateTempDirOrFile_Handler,
},
},
Streams: []grpc.StreamDesc{},
Streams: []grpc.StreamDesc{
{
StreamName: "EventListen",
Handler: _P4WNP1_EventListen_Handler,
ServerStreams: true,
},
},
Metadata: "grpc.proto",
}
func init() { proto.RegisterFile("grpc.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 1814 bytes of a gzipped FileDescriptorProto
// 1937 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xeb, 0x72, 0xe3, 0xb6,
0x15, 0xb6, 0x2d, 0xaf, 0x2d, 0x1d, 0x5d, 0x17, 0x7b, 0x09, 0xd7, 0xd9, 0xf5, 0xba, 0xec, 0x26,
0xe3, 0x69, 0x32, 0x6e, 0xe3, 0x7a, 0x26, 0x99, 0xcc, 0x74, 0x5a, 0x5a, 0xa2, 0x2c, 0xad, 0xad,
0xcb, 0x80, 0x76, 0x3c, 0xed, 0x1f, 0x86, 0x26, 0x60, 0x09, 0x5d, 0x8a, 0x64, 0x09, 0xd0, 0x59,
0xf7, 0x47, 0x9e, 0xac, 0xaf, 0xd0, 0x07, 0xe8, 0x03, 0xf4, 0x39, 0xda, 0x01, 0x78, 0x11, 0xa5,
0x95, 0xec, 0x4c, 0xfb, 0x0f, 0xf8, 0x70, 0xce, 0x87, 0x03, 0x9c, 0x83, 0x73, 0x00, 0x00, 0x4c,
0xa2, 0xd0, 0x3d, 0x0a, 0xa3, 0x40, 0x04, 0xa8, 0x3a, 0x3e, 0xf9, 0xc9, 0x1f, 0x7f, 0x63, 0x4b,
0x48, 0xff, 0x11, 0x9e, 0x5f, 0xd2, 0x59, 0xd8, 0x61, 0xd1, 0x28, 0xea, 0x32, 0x8f, 0x62, 0xfa,
0xb7, 0x98, 0x72, 0x81, 0x5a, 0x50, 0x22, 0x2c, 0xd2, 0x36, 0x0f, 0x36, 0x0f, 0x2b, 0x58, 0x36,
0xd1, 0x4b, 0xd8, 0x09, 0x23, 0x7a, 0xcb, 0x3e, 0x6a, 0x5b, 0x0a, 0x4c, 0x7b, 0x68, 0x1f, 0x20,
0xf0, 0xbd, 0xfb, 0x6e, 0xe0, 0x11, 0x1a, 0x69, 0xa5, 0x83, 0xcd, 0xc3, 0x32, 0x2e, 0x20, 0xfa,
0xb7, 0xf0, 0x62, 0x69, 0x06, 0x1e, 0x06, 0x3e, 0xa7, 0x52, 0x31, 0xa2, 0x3c, 0xf6, 0xc4, 0xd8,
0x11, 0xd3, 0x74, 0xa6, 0x02, 0xa2, 0x8f, 0xa0, 0x89, 0xa9, 0x43, 0x8a, 0x56, 0x21, 0xd8, 0x0e,
0xe7, 0xc2, 0xaa, 0x8d, 0x9e, 0xc3, 0x13, 0x2e, 0x9c, 0x48, 0x28, 0xb3, 0x4a, 0x38, 0xe9, 0x48,
0x49, 0xe2, 0x08, 0x47, 0xd9, 0x53, 0xc3, 0xaa, 0xad, 0xff, 0x0e, 0x5a, 0x73, 0xc2, 0xd4, 0x88,
0xd7, 0x50, 0x89, 0xa8, 0x43, 0xda, 0x41, 0xec, 0x0b, 0x45, 0x5b, 0xc2, 0x73, 0x40, 0xbf, 0x83,
0xd6, 0x75, 0xc4, 0x04, 0x7d, 0xcc, 0x86, 0x97, 0xb0, 0xe3, 0x84, 0x21, 0xf5, 0x89, 0x32, 0xa2,
0x8c, 0xd3, 0x1e, 0xd2, 0xa1, 0x36, 0x8b, 0xb9, 0x18, 0x06, 0xc2, 0xfc, 0xc8, 0xb8, 0x48, 0x77,
0x67, 0x01, 0xcb, 0x2d, 0xdd, 0x2e, 0x58, 0xfa, 0x05, 0x34, 0xe5, 0x94, 0x7d, 0xff, 0x36, 0x78,
0x60, 0x5a, 0xfd, 0x67, 0x68, 0xcd, 0xc5, 0xd2, 0x05, 0x21, 0xd8, 0xf6, 0x9d, 0x19, 0xcd, 0xe4,
0x64, 0x5b, 0x62, 0x9c, 0xfd, 0x9d, 0xa6, 0x3b, 0xa4, 0xda, 0x12, 0x9b, 0x05, 0x84, 0x2a, 0x93,
0xea, 0x58, 0xb5, 0x91, 0x06, 0xbb, 0xb3, 0x80, 0x5c, 0xb2, 0x19, 0x55, 0xd6, 0x94, 0x70, 0xd6,
0x95, 0x9b, 0xcc, 0x78, 0x87, 0x45, 0xda, 0x13, 0xb5, 0x82, 0xa4, 0xa3, 0xff, 0x05, 0x5a, 0xbd,
0x7e, 0xc7, 0x72, 0x23, 0x16, 0x8a, 0xcc, 0xce, 0x7d, 0x00, 0xae, 0x80, 0xa2, 0x57, 0xe7, 0x08,
0xfa, 0x12, 0x1a, 0x82, 0xcd, 0x68, 0x10, 0x0b, 0x8b, 0xba, 0x81, 0x4f, 0xb8, 0xb2, 0xaa, 0x8e,
0x97, 0x50, 0x7d, 0x1f, 0x6a, 0x39, 0xf7, 0xfb, 0xe0, 0x06, 0x35, 0x60, 0x8b, 0x11, 0xc5, 0x57,
0xc7, 0x5b, 0x8c, 0xe8, 0xef, 0x0a, 0x73, 0xbf, 0x0f, 0x6e, 0x2e, 0x58, 0x12, 0xb4, 0x8c, 0x70,
0x6d, 0xf3, 0xa0, 0x74, 0x58, 0xc7, 0xb2, 0xa9, 0xff, 0x0c, 0xcd, 0x82, 0x85, 0x32, 0xb4, 0xd0,
0x57, 0x50, 0xfa, 0x6b, 0x70, 0xa3, 0x98, 0xaa, 0xc7, 0xaf, 0x8e, 0x0a, 0x87, 0xe1, 0xa8, 0x48,
0x88, 0xa5, 0x94, 0x5c, 0x0d, 0xe3, 0x5d, 0xe6, 0x33, 0x3e, 0xa5, 0x99, 0x73, 0x0b, 0xc8, 0x3c,
0x86, 0xdf, 0xf3, 0xc0, 0x57, 0x7b, 0x99, 0xc7, 0xb0, 0x44, 0xf4, 0x23, 0xa8, 0x5e, 0x98, 0x1d,
0x8b, 0x0a, 0xc1, 0xfc, 0x09, 0x47, 0x6f, 0xa1, 0x7a, 0xe3, 0x31, 0xff, 0x83, 0xed, 0xe6, 0xf1,
0x56, 0xc7, 0xa0, 0xa0, 0x24, 0xe0, 0xfe, 0xbd, 0x0d, 0x8d, 0x33, 0x87, 0x4c, 0xa8, 0xc8, 0x75,
0x34, 0xd8, 0xa5, 0xbe, 0x73, 0xe3, 0xd1, 0x64, 0xf5, 0x65, 0x9c, 0x75, 0xe5, 0x72, 0xef, 0x18,
0x49, 0x8f, 0xa3, 0x6c, 0x4a, 0x24, 0x64, 0x24, 0xb5, 0x43, 0x36, 0x55, 0x04, 0x3a, 0x7e, 0x7c,
0xeb, 0xb8, 0x22, 0x8e, 0x68, 0xa4, 0xfc, 0x5a, 0xc1, 0x0b, 0x98, 0x9c, 0x21, 0x8c, 0x02, 0x12,
0xbb, 0x42, 0xb9, 0xb7, 0x82, 0xb3, 0xae, 0x8c, 0x6b, 0x4e, 0x23, 0xe6, 0x78, 0xda, 0x4e, 0x72,
0xe6, 0x93, 0x1e, 0xda, 0x87, 0x6a, 0xcc, 0xa9, 0xdd, 0xee, 0xb4, 0x6d, 0xb3, 0x3d, 0xd0, 0x76,
0x95, 0x5d, 0x95, 0x98, 0xd3, 0x76, 0xa7, 0x6d, 0xb6, 0x07, 0xe8, 0x73, 0x90, 0x1d, 0x1b, 0x0f,
0x3b, 0x7d, 0x4b, 0x2b, 0xab, 0xd1, 0x72, 0xcc, 0xa9, 0xea, 0xa3, 0x43, 0x68, 0xc9, 0xc1, 0x5e,
0xbf, 0x63, 0x9f, 0x9b, 0x7f, 0x3e, 0x1d, 0x19, 0xb8, 0xa3, 0x55, 0x94, 0x4c, 0x23, 0xe6, 0xb4,
0xd7, 0xef, 0x64, 0x28, 0xd2, 0xa1, 0x9e, 0x49, 0x0e, 0x46, 0x57, 0x96, 0xa9, 0x81, 0x12, 0xab,
0x26, 0x62, 0x0a, 0xca, 0x4c, 0x91, 0x32, 0xd8, 0xb8, 0xd6, 0xaa, 0xb9, 0x29, 0xbd, 0x7e, 0x07,
0x1b, 0xd7, 0xe8, 0x33, 0xd8, 0x95, 0xe3, 0x57, 0x03, 0x4b, 0xab, 0x25, 0x67, 0x33, 0xe6, 0xf4,
0x6a, 0x60, 0xa1, 0x37, 0x00, 0x72, 0xc0, 0x32, 0x71, 0xdf, 0xb8, 0xd0, 0xea, 0xb9, 0x5e, 0x02,
0xa0, 0xf7, 0xd0, 0x88, 0x7c, 0xc2, 0xb8, 0xcd, 0x53, 0x47, 0x68, 0x0d, 0x15, 0x31, 0xbf, 0x5e,
0x88, 0x98, 0x45, 0x5f, 0x99, 0x62, 0x4a, 0x23, 0x9f, 0x0a, 0x5c, 0x57, 0xaa, 0xb9, 0x0b, 0x07,
0xd0, 0x72, 0x89, 0x6b, 0x53, 0x77, 0x36, 0x67, 0x6b, 0xfe, 0x72, 0xb6, 0x86, 0x4b, 0x5c, 0xd3,
0x9d, 0xe5, 0x74, 0x06, 0xd4, 0xe2, 0x59, 0xc1, 0xb0, 0x96, 0xa2, 0xda, 0x7f, 0x80, 0xea, 0x6a,
0x60, 0xe1, 0x6a, 0x3c, 0xcb, 0x2d, 0xd2, 0xc7, 0xf0, 0x72, 0xf5, 0x64, 0xd2, 0x75, 0xd3, 0x80,
0x0b, 0xdb, 0x21, 0x24, 0x4b, 0xff, 0x65, 0x09, 0x18, 0x84, 0x44, 0xe8, 0x15, 0x94, 0x09, 0xbd,
0x4b, 0xc6, 0x92, 0xb0, 0xdb, 0x25, 0xf4, 0x4e, 0x0e, 0xe9, 0x7f, 0x80, 0xa7, 0x9f, 0xcc, 0x29,
0xd3, 0x86, 0x4b, 0xa2, 0x60, 0x96, 0x46, 0x6e, 0xd2, 0x91, 0xa9, 0xe7, 0x96, 0x79, 0x34, 0x65,
0x50, 0x6d, 0xfd, 0x9f, 0x5b, 0xf0, 0x2a, 0xb3, 0xa1, 0xef, 0x0b, 0x1a, 0xdd, 0x3a, 0x2e, 0xcd,
0x57, 0xbc, 0x2a, 0xa9, 0xfd, 0x31, 0x4d, 0x60, 0x92, 0xa5, 0x71, 0xfc, 0xd5, 0xc2, 0xea, 0xd7,
0x32, 0x1d, 0x0d, 0x02, 0x42, 0xd3, 0x6c, 0x27, 0xcf, 0x76, 0x28, 0x6d, 0xa7, 0x9c, 0x9f, 0x64,
0x67, 0x77, 0x8e, 0xa0, 0x3d, 0x28, 0xfb, 0x54, 0xcc, 0x1c, 0xfe, 0xe1, 0x24, 0x3d, 0x36, 0x79,
0xbf, 0x78, 0x28, 0x9f, 0x2c, 0x1e, 0xca, 0x11, 0x20, 0x32, 0x75, 0x43, 0x8b, 0x46, 0x77, 0x34,
0xca, 0xa6, 0x55, 0xc7, 0xa7, 0x7a, 0xfc, 0x76, 0xc1, 0xc8, 0x4e, 0xaf, 0x3d, 0x5e, 0x14, 0xc3,
0x2b, 0x54, 0xf5, 0x13, 0xd8, 0x96, 0x46, 0x23, 0x80, 0x9d, 0x81, 0x31, 0xbc, 0x32, 0x2e, 0x5a,
0x1b, 0xa8, 0x09, 0x55, 0xa9, 0x6d, 0xb7, 0x2f, 0xfa, 0xe6, 0xf0, 0xb2, 0xb5, 0x99, 0x03, 0x96,
0x89, 0x7f, 0x30, 0x71, 0x6b, 0x4b, 0xff, 0x4f, 0x09, 0xd0, 0xa7, 0x13, 0xc8, 0x35, 0x7b, 0x8c,
0x0b, 0xea, 0x8f, 0x83, 0x28, 0xcf, 0x3f, 0x73, 0x04, 0x1d, 0x42, 0x33, 0xe9, 0xe5, 0x3b, 0x97,
0x7a, 0x69, 0x19, 0x96, 0x85, 0xd3, 0xa3, 0x0e, 0x57, 0xa5, 0x31, 0xdd, 0xbc, 0x39, 0x80, 0x7e,
0x03, 0x2d, 0x3f, 0x10, 0x46, 0x2c, 0xa6, 0x41, 0xc4, 0x84, 0x23, 0xd8, 0x5d, 0x52, 0x52, 0xca,
0xf8, 0x13, 0x1c, 0x1d, 0x01, 0x22, 0xc1, 0x30, 0x10, 0xa7, 0xcc, 0x27, 0xf3, 0x69, 0x93, 0x6d,
0x5d, 0x31, 0x22, 0x2b, 0x88, 0xeb, 0x78, 0xde, 0x8d, 0xe3, 0x7e, 0x48, 0xb2, 0x75, 0x9a, 0x9c,
0x96, 0x50, 0x74, 0x02, 0x3b, 0x91, 0xe3, 0x4f, 0x28, 0xd7, 0x76, 0x0f, 0x4a, 0x87, 0xd5, 0xe3,
0xd7, 0x6b, 0x76, 0x1f, 0x4b, 0x21, 0x9c, 0xca, 0xa2, 0x2e, 0xec, 0x06, 0xa1, 0x60, 0x81, 0xcf,
0xb5, 0xb2, 0x52, 0xfb, 0xfa, 0x11, 0xa7, 0x1d, 0x8d, 0x12, 0x71, 0xd3, 0x17, 0xd1, 0x3d, 0xce,
0x94, 0x51, 0x1b, 0xaa, 0x5c, 0x2e, 0xd0, 0xed, 0x05, 0x5c, 0x70, 0xad, 0xa2, 0xb8, 0x7e, 0xb5,
0x8e, 0x2b, 0x97, 0xc4, 0x45, 0xad, 0xbd, 0xef, 0xa1, 0x56, 0x64, 0x97, 0xf9, 0xfd, 0x03, 0xbd,
0x4f, 0xfd, 0x26, 0x9b, 0xf2, 0x84, 0xdd, 0x39, 0x5e, 0x9c, 0xb9, 0x29, 0xe9, 0x7c, 0xbf, 0xf5,
0xdd, 0xa6, 0x1e, 0x40, 0x73, 0x69, 0x8d, 0xaa, 0x5a, 0xc9, 0xc6, 0x45, 0xf0, 0x13, 0x8d, 0xf2,
0x1b, 0x57, 0x8e, 0xe4, 0xe3, 0x57, 0x61, 0x48, 0xb3, 0x03, 0x5e, 0x40, 0x72, 0x9f, 0xab, 0x1b,
0x42, 0xd1, 0xe7, 0x12, 0xd0, 0xbf, 0x83, 0xe7, 0xab, 0x56, 0x24, 0x8d, 0x9e, 0x39, 0x6e, 0x76,
0x95, 0x9c, 0x39, 0xae, 0xaa, 0xe5, 0x61, 0xca, 0xbf, 0xc5, 0x42, 0xfd, 0x5f, 0x25, 0xa8, 0x5d,
0xb3, 0x2e, 0xcb, 0xc3, 0x74, 0x0f, 0xca, 0x84, 0xf1, 0x62, 0xd1, 0xcb, 0xfb, 0x92, 0x2e, 0xa2,
0x93, 0xac, 0xea, 0x45, 0x74, 0x82, 0x8e, 0x0b, 0x57, 0x99, 0xc6, 0x52, 0x1e, 0x2c, 0xd2, 0x16,
0x0f, 0xbf, 0x01, 0x15, 0x27, 0x16, 0x53, 0x5b, 0x29, 0x6e, 0x2b, 0xc5, 0x77, 0xeb, 0x15, 0x8d,
0xb1, 0x0c, 0x59, 0xa5, 0x5e, 0x76, 0xd2, 0x96, 0x2c, 0x20, 0x4e, 0x68, 0xbb, 0x53, 0xc7, 0xf7,
0xa9, 0xa7, 0xe2, 0xb5, 0x8e, 0x2b, 0x4e, 0xd8, 0x4e, 0x00, 0xf4, 0x5b, 0x28, 0x9f, 0x72, 0xde,
0xbe, 0x9d, 0x18, 0xe3, 0xf4, 0xf8, 0x3f, 0x5b, 0x98, 0xe0, 0xd4, 0xb2, 0xda, 0xb7, 0x13, 0x9c,
0x0b, 0xa1, 0x6f, 0xa1, 0x96, 0xb4, 0xdb, 0x1e, 0xa3, 0xbe, 0x50, 0x55, 0x75, 0x8d, 0xd2, 0x82,
0x20, 0x3a, 0x80, 0x9a, 0x13, 0xda, 0x53, 0x46, 0xa8, 0xcd, 0x39, 0x23, 0x69, 0xc1, 0x05, 0x27,
0xec, 0x31, 0x42, 0x2d, 0xce, 0x08, 0xfa, 0x02, 0x1a, 0xe9, 0xfe, 0xd9, 0x3e, 0xfd, 0x38, 0x0b,
0xfc, 0xb4, 0x92, 0xd6, 0x53, 0x74, 0xa8, 0x40, 0xfd, 0xeb, 0x34, 0xd5, 0xec, 0xc0, 0x96, 0x31,
0x6e, 0x6d, 0xa0, 0x5d, 0x28, 0x59, 0x97, 0x46, 0x6b, 0x13, 0x3d, 0x83, 0xa6, 0x75, 0x69, 0xd8,
0x5d, 0xa3, 0x7f, 0x31, 0xfa, 0xc1, 0xc4, 0xb6, 0x31, 0x6e, 0x6d, 0xe9, 0xef, 0x00, 0xe6, 0xfb,
0x82, 0x6a, 0x50, 0xbe, 0x1e, 0x1b, 0xc7, 0xf6, 0xd8, 0x3a, 0x6f, 0x6d, 0xa0, 0x32, 0x6c, 0x8f,
0xc6, 0xe6, 0xb0, 0xb5, 0xa9, 0x1f, 0xc1, 0x4e, 0x62, 0xb4, 0x4c, 0xe2, 0x96, 0xd5, 0xef, 0x64,
0x49, 0x5c, 0xb6, 0xa5, 0x33, 0xc7, 0xd6, 0x79, 0xe6, 0xcc, 0xb1, 0x75, 0xae, 0xef, 0xc2, 0x13,
0x73, 0x16, 0x8a, 0xfb, 0xe3, 0x7f, 0x54, 0x61, 0x67, 0x7c, 0x72, 0x3d, 0x1c, 0x7f, 0x83, 0x06,
0xa0, 0x9d, 0x51, 0xd1, 0xa1, 0xa1, 0x17, 0xdc, 0x53, 0xb2, 0x50, 0x66, 0x10, 0x5a, 0x4c, 0xfc,
0x52, 0x75, 0xef, 0xf3, 0x07, 0x4a, 0xa1, 0xbe, 0x81, 0x7a, 0xf0, 0x2c, 0xe1, 0xfa, 0xbf, 0x99,
0xba, 0xf0, 0xf4, 0x8c, 0x8a, 0xa5, 0x0b, 0xdb, 0xff, 0xc0, 0x33, 0x82, 0xa7, 0xd6, 0x27, 0x3c,
0x0f, 0xe9, 0x3c, 0x46, 0xf8, 0x27, 0x68, 0x9c, 0x51, 0x51, 0xbc, 0x7a, 0xae, 0xb2, 0x4a, 0x5b,
0xc0, 0x0a, 0xd2, 0x09, 0x83, 0xb5, 0xc8, 0xb0, 0x56, 0x7a, 0x6f, 0x05, 0xb7, 0xbe, 0x81, 0x3a,
0x50, 0x1b, 0xc8, 0x4b, 0xed, 0xd5, 0xc0, 0x52, 0x35, 0xe1, 0x91, 0x0b, 0xca, 0x1a, 0x16, 0x1b,
0xde, 0x26, 0xce, 0x5a, 0x7f, 0x3b, 0xf8, 0xf2, 0x97, 0xd5, 0xfe, 0x35, 0x13, 0x98, 0x80, 0x92,
0x09, 0xae, 0xd9, 0xed, 0x3c, 0x03, 0xbd, 0x5a, 0x9b, 0x0c, 0xd6, 0xd0, 0x0c, 0xd4, 0x7b, 0x05,
0xc7, 0x7e, 0x5a, 0x7d, 0xde, 0xac, 0x7e, 0x59, 0xa4, 0xcf, 0xa4, 0xbd, 0xd7, 0xeb, 0x86, 0xe5,
0xd3, 0x41, 0xd1, 0x35, 0x8b, 0x74, 0xf2, 0x05, 0xf4, 0x08, 0xe3, 0xfa, 0xa7, 0x8c, 0xbe, 0x81,
0x30, 0xbc, 0xe8, 0xf5, 0x3b, 0x67, 0x54, 0xcc, 0xdf, 0x37, 0xc9, 0x6b, 0x68, 0xbd, 0xd6, 0xa3,
0x26, 0x9a, 0x80, 0x7a, 0xfd, 0x4e, 0xdb, 0xf1, 0x5d, 0xea, 0xcd, 0xad, 0x7c, 0x80, 0x70, 0xf5,
0xc6, 0x0d, 0xe1, 0xb3, 0xc4, 0x34, 0x1c, 0xfb, 0x3e, 0xf3, 0x27, 0xb9, 0xfc, 0xea, 0x98, 0x7d,
0xb3, 0x96, 0x5f, 0x3e, 0x01, 0xf5, 0x0d, 0x74, 0x0a, 0x2f, 0x73, 0xb3, 0x0c, 0xcf, 0x7b, 0x84,
0x6e, 0xb5, 0x4d, 0xa7, 0x50, 0xed, 0x5a, 0xf9, 0xcb, 0x7f, 0x69, 0xe7, 0x97, 0x7f, 0x04, 0xd6,
0x70, 0x9c, 0x03, 0x74, 0xad, 0xec, 0xbf, 0x01, 0x2d, 0x6e, 0xe6, 0xd2, 0xbf, 0xc6, 0xd2, 0xa2,
0x96, 0x3f, 0x29, 0xd4, 0x26, 0xd5, 0xbb, 0xd6, 0x19, 0x15, 0xd9, 0x73, 0x7f, 0x89, 0x6f, 0xe9,
0xb3, 0x60, 0x89, 0x6f, 0xf9, 0x8f, 0x40, 0xdf, 0x40, 0x3f, 0xc2, 0x8b, 0xae, 0xd5, 0x8e, 0xa8,
0x23, 0xe8, 0xc2, 0xe7, 0x0c, 0x5a, 0xbc, 0xa1, 0xac, 0xfa, 0x1a, 0xda, 0xd3, 0x1f, 0x12, 0xc9,
0x66, 0xb8, 0xd9, 0x51, 0x9f, 0x4d, 0xbf, 0xff, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x16, 0xce,
0xf8, 0x17, 0x7a, 0x12, 0x00, 0x00,
0x15, 0x96, 0x25, 0x5b, 0x97, 0xa3, 0x8b, 0xb5, 0xd8, 0x1b, 0xd7, 0xd9, 0x5b, 0xd9, 0x4d, 0xc6,
0xd3, 0x64, 0x9c, 0xc4, 0xf5, 0x34, 0x99, 0xcc, 0x74, 0x1a, 0x5a, 0xa2, 0x2c, 0xed, 0x5a, 0xb6,
0x06, 0xb4, 0xd7, 0xd3, 0xfe, 0x61, 0x68, 0x12, 0x96, 0xd1, 0xa5, 0x40, 0x96, 0x00, 0x9d, 0x75,
0x7f, 0xe4, 0x0d, 0xfb, 0x00, 0x7d, 0x80, 0xbe, 0x46, 0xdb, 0x01, 0x78, 0x11, 0xa5, 0x95, 0xec,
0x4c, 0xfb, 0x0f, 0xf8, 0x70, 0xf0, 0xe1, 0x03, 0x0e, 0x70, 0x0e, 0x00, 0x80, 0x69, 0x14, 0xba,
0x7b, 0x61, 0x14, 0x88, 0x00, 0x35, 0x27, 0x07, 0x3f, 0xb3, 0xc9, 0xb7, 0xb6, 0x84, 0xf4, 0x3d,
0x68, 0x99, 0x37, 0x84, 0x09, 0x4c, 0xfe, 0x16, 0x13, 0x2e, 0xd0, 0x4b, 0x00, 0x9f, 0x72, 0x41,
0xd8, 0xd9, 0x6d, 0x48, 0xb4, 0x8d, 0xd7, 0x1b, 0xbb, 0x15, 0x5c, 0x40, 0x74, 0x07, 0x40, 0xd9,
0xbf, 0x77, 0xfc, 0x98, 0xa0, 0x1d, 0xa8, 0x09, 0x2e, 0x22, 0xca, 0xa6, 0xca, 0xb4, 0x31, 0x2c,
0xe1, 0x0c, 0x40, 0x4f, 0x60, 0x4b, 0x5c, 0x06, 0x81, 0xaf, 0x95, 0x5f, 0x6f, 0xec, 0xd6, 0x87,
0x25, 0x9c, 0x54, 0x91, 0x06, 0x55, 0x41, 0x99, 0xf8, 0xc3, 0x81, 0x56, 0x91, 0xec, 0xc3, 0x12,
0x4e, 0xeb, 0x87, 0x5b, 0x50, 0xb9, 0x71, 0x7c, 0xfd, 0x18, 0xb6, 0xd4, 0x10, 0x08, 0xc1, 0xa6,
0x98, 0xab, 0x50, 0x65, 0xf4, 0x35, 0x54, 0x6f, 0xe4, 0xd0, 0x5c, 0x2b, 0xbf, 0xae, 0xec, 0x36,
0xf7, 0x9f, 0xee, 0x15, 0x66, 0xb3, 0x37, 0x97, 0x86, 0x53, 0x33, 0xfd, 0x27, 0x78, 0x74, 0x46,
0x66, 0x61, 0x9f, 0x46, 0xa7, 0xd1, 0x80, 0xfa, 0x24, 0x9b, 0x68, 0x17, 0x2a, 0x1e, 0x8d, 0x12,
0xd9, 0x58, 0x16, 0xd1, 0x13, 0xa8, 0x86, 0x11, 0xb9, 0xa2, 0x1f, 0x95, 0xe2, 0x06, 0x4e, 0x6b,
0x72, 0x49, 0x02, 0xe6, 0xdf, 0x0e, 0x02, 0xdf, 0x23, 0x91, 0x12, 0x5d, 0xc7, 0x05, 0x44, 0xff,
0x0e, 0x1e, 0x2f, 0x8d, 0xc0, 0xc3, 0x80, 0x71, 0x22, 0x3b, 0x46, 0x84, 0xc7, 0xbe, 0x98, 0x38,
0xe2, 0x3a, 0x1d, 0xa9, 0x80, 0xe8, 0xa7, 0xb0, 0x8d, 0x89, 0xe3, 0x15, 0x55, 0x21, 0xd8, 0x0c,
0xe7, 0xc6, 0xaa, 0x8c, 0x1e, 0xc1, 0x16, 0x17, 0x4e, 0x24, 0x94, 0xac, 0x0a, 0x4e, 0x2a, 0xd2,
0xd2, 0x73, 0x84, 0xa3, 0xf4, 0xb4, 0xb0, 0x2a, 0xeb, 0xdf, 0x40, 0x77, 0x4e, 0x98, 0x8a, 0x78,
0x0e, 0x8d, 0x88, 0x38, 0x5e, 0x2f, 0x88, 0x99, 0x48, 0x57, 0x72, 0x0e, 0xe8, 0x37, 0xd0, 0xbd,
0x88, 0xa8, 0x20, 0xf7, 0x69, 0x78, 0x02, 0x55, 0x27, 0x0c, 0x09, 0xf3, 0x12, 0x6f, 0xe2, 0xb4,
0x86, 0x74, 0x68, 0xcd, 0x62, 0x2e, 0x4e, 0x02, 0x61, 0x7e, 0xa4, 0x5c, 0xa4, 0xab, 0xb3, 0x80,
0xe5, 0x4a, 0x37, 0x0b, 0x4a, 0x3f, 0x87, 0x6d, 0x39, 0xe4, 0x88, 0x5d, 0x05, 0x77, 0x0c, 0xab,
0xff, 0x02, 0xdd, 0xb9, 0x59, 0x3a, 0x21, 0x04, 0x9b, 0xcc, 0x99, 0x91, 0xcc, 0x4e, 0x96, 0x25,
0xc6, 0xe9, 0xdf, 0x49, 0xba, 0x42, 0xaa, 0x2c, 0xb1, 0x59, 0xe0, 0x11, 0x25, 0xa9, 0x8d, 0x55,
0x19, 0x69, 0x50, 0x9b, 0x05, 0xde, 0x19, 0x9d, 0x11, 0xa5, 0xa6, 0x82, 0xb3, 0xaa, 0x5c, 0x64,
0xca, 0xfb, 0x34, 0xd2, 0xb6, 0xd4, 0x0c, 0x92, 0x8a, 0xfe, 0x17, 0xe8, 0x0e, 0x47, 0x7d, 0xcb,
0x8d, 0x68, 0x58, 0x3c, 0x21, 0x5c, 0x01, 0x45, 0xaf, 0xce, 0x11, 0xf4, 0x05, 0x74, 0x04, 0x9d,
0x91, 0x20, 0x16, 0x16, 0x71, 0x03, 0xe6, 0x71, 0xa5, 0xaa, 0x8d, 0x97, 0x50, 0xfd, 0x25, 0xb4,
0x72, 0xee, 0xb7, 0xc1, 0x25, 0xea, 0x40, 0x99, 0x7a, 0x8a, 0xaf, 0x8d, 0xcb, 0xd4, 0xd3, 0xdf,
0x14, 0xc6, 0x7e, 0x1b, 0x5c, 0x1e, 0xd3, 0x64, 0xd3, 0x52, 0x8f, 0x6b, 0x1b, 0xaf, 0x2b, 0xbb,
0x6d, 0x2c, 0x8b, 0xfa, 0x2f, 0xb0, 0x5d, 0x50, 0x28, 0xb7, 0x16, 0xfa, 0x12, 0x2a, 0x7f, 0x0d,
0x2e, 0x15, 0x53, 0x73, 0xff, 0xd9, 0xc2, 0xf9, 0x28, 0x12, 0x62, 0x69, 0x25, 0x67, 0x43, 0xf9,
0x80, 0x32, 0xca, 0xaf, 0x49, 0xe6, 0xdc, 0x02, 0x32, 0xdf, 0xc3, 0x6f, 0x79, 0xc0, 0xd4, 0x5a,
0xe6, 0x7b, 0x58, 0x22, 0xfa, 0x1e, 0x34, 0x8f, 0xcd, 0xbe, 0x45, 0x84, 0xa0, 0x6c, 0xca, 0xd1,
0x2b, 0x68, 0x5e, 0xfa, 0x94, 0x7d, 0xb0, 0xdd, 0x7c, 0xbf, 0xb5, 0x31, 0x28, 0x28, 0xd9, 0x70,
0xff, 0xda, 0x84, 0xce, 0x91, 0xe3, 0x4d, 0x89, 0xc8, 0xfb, 0x68, 0x50, 0x23, 0xcc, 0xb9, 0xf4,
0x49, 0x32, 0xfb, 0x3a, 0xce, 0xaa, 0x72, 0xba, 0x37, 0xd4, 0x4b, 0x8f, 0xa3, 0x2c, 0x4a, 0x24,
0xa4, 0x5e, 0xaa, 0x43, 0x16, 0xd5, 0x0e, 0x74, 0x58, 0x7c, 0xe5, 0xb8, 0x22, 0x8e, 0x48, 0xa4,
0xfc, 0xda, 0xc0, 0x0b, 0x98, 0x1c, 0x21, 0x8c, 0x02, 0x2f, 0x76, 0x85, 0x72, 0x6f, 0x03, 0x67,
0x55, 0xb9, 0xaf, 0x39, 0x89, 0xa8, 0xe3, 0x6b, 0xd5, 0xe4, 0xcc, 0x27, 0x35, 0xf4, 0x12, 0x9a,
0x31, 0x27, 0x76, 0xaf, 0xdf, 0xb3, 0xcd, 0xde, 0x58, 0xab, 0x29, 0x5d, 0x8d, 0x98, 0x93, 0x5e,
0xbf, 0x67, 0xf6, 0xc6, 0xe8, 0x33, 0x90, 0x15, 0x1b, 0x9f, 0xf4, 0x47, 0x96, 0x56, 0x57, 0xad,
0xf5, 0x98, 0x13, 0x55, 0x47, 0xbb, 0xd0, 0x95, 0x8d, 0xc3, 0x51, 0xdf, 0x7e, 0x67, 0xfe, 0xf9,
0xf0, 0xd4, 0xc0, 0x7d, 0xad, 0xa1, 0x6c, 0x3a, 0x31, 0x27, 0xc3, 0x51, 0x3f, 0x43, 0x91, 0x0e,
0xed, 0xcc, 0x72, 0x7c, 0x7a, 0x6e, 0x99, 0x1a, 0x28, 0xb3, 0x66, 0x62, 0xa6, 0xa0, 0x4c, 0x8a,
0xb4, 0xc1, 0xc6, 0x85, 0xd6, 0xcc, 0xa5, 0x0c, 0x47, 0x7d, 0x6c, 0x5c, 0xa0, 0xa7, 0x50, 0x93,
0xed, 0xe7, 0x63, 0x4b, 0x6b, 0x25, 0x67, 0x33, 0xe6, 0xe4, 0x7c, 0x6c, 0xa1, 0x17, 0x00, 0xb2,
0xc1, 0x32, 0xf1, 0xc8, 0x38, 0xd6, 0xda, 0x79, 0xbf, 0x04, 0x40, 0x6f, 0xa1, 0x13, 0x31, 0x8f,
0x72, 0x9b, 0xa7, 0x8e, 0xd0, 0x3a, 0x6a, 0xc7, 0xfc, 0x76, 0x61, 0xc7, 0x2c, 0xfa, 0xca, 0x14,
0xd7, 0x24, 0x62, 0x44, 0xe0, 0xb6, 0xea, 0x9a, 0xbb, 0x70, 0x0c, 0x5d, 0xd7, 0x73, 0x6d, 0xe2,
0xce, 0xe6, 0x6c, 0xdb, 0xbf, 0x9e, 0xad, 0xe3, 0x7a, 0xae, 0xe9, 0xce, 0x72, 0x3a, 0x03, 0x5a,
0xf1, 0xac, 0x20, 0xac, 0xab, 0xa8, 0x5e, 0xde, 0x41, 0x75, 0x3e, 0xb6, 0x70, 0x33, 0x9e, 0xe5,
0x8a, 0xf4, 0x09, 0x3c, 0x59, 0x3d, 0x98, 0x74, 0xdd, 0x75, 0xc0, 0x85, 0xed, 0x78, 0x5e, 0x16,
0xfe, 0xeb, 0x12, 0x30, 0x3c, 0x2f, 0x42, 0xcf, 0xa0, 0xee, 0x91, 0x9b, 0xa4, 0x2d, 0xd9, 0x76,
0x35, 0x8f, 0xdc, 0xc8, 0x26, 0xfd, 0x8f, 0xf0, 0xe0, 0x93, 0x31, 0x65, 0xd8, 0x70, 0xbd, 0x28,
0x98, 0xa5, 0x3b, 0x37, 0xa9, 0xc8, 0xd0, 0x73, 0x45, 0x7d, 0x92, 0x32, 0xa8, 0xb2, 0xfe, 0x8f,
0x32, 0x3c, 0xcb, 0x34, 0x8c, 0x98, 0x20, 0xd1, 0x95, 0xe3, 0x92, 0x7c, 0xc6, 0xab, 0x82, 0xda,
0x9f, 0xd2, 0x00, 0x26, 0x59, 0x3a, 0xfb, 0x5f, 0x2e, 0x26, 0xba, 0x75, 0x4c, 0x7b, 0xe3, 0xc0,
0x23, 0x69, 0xb4, 0x93, 0x67, 0x3b, 0x94, 0xda, 0x09, 0xe7, 0x07, 0xd9, 0xd9, 0x9d, 0x23, 0x68,
0x07, 0xea, 0x8c, 0x88, 0x99, 0xc3, 0x3f, 0x1c, 0xa4, 0xc7, 0x26, 0xaf, 0x17, 0x0f, 0xe5, 0xd6,
0xe2, 0xa1, 0x3c, 0x05, 0xe4, 0x5d, 0xbb, 0xa1, 0x45, 0xa2, 0x1b, 0x12, 0x65, 0xc3, 0xaa, 0xe3,
0xd3, 0xdc, 0x7f, 0xb5, 0x20, 0xb2, 0x3f, 0xec, 0x4d, 0x16, 0xcd, 0xf0, 0x8a, 0xae, 0xfa, 0x01,
0x6c, 0x4a, 0xd1, 0x08, 0xa0, 0x3a, 0x36, 0x4e, 0xce, 0x8d, 0xe3, 0x6e, 0x09, 0x6d, 0x43, 0x53,
0xf6, 0xb6, 0x7b, 0xc7, 0x23, 0xf3, 0xe4, 0xac, 0xbb, 0x91, 0x03, 0x96, 0x89, 0xdf, 0x9b, 0xb8,
0x5b, 0xd6, 0xff, 0x53, 0x01, 0xf4, 0xe9, 0x00, 0xf3, 0xfb, 0xcb, 0x24, 0x88, 0xf2, 0xf8, 0x33,
0x47, 0xd0, 0x2e, 0x6c, 0x27, 0xb5, 0x7c, 0xe5, 0x52, 0x2f, 0x2d, 0xc3, 0x32, 0x71, 0xfa, 0xc4,
0xe1, 0x2a, 0x35, 0xa6, 0x8b, 0x37, 0x07, 0xd0, 0xef, 0xa0, 0xcb, 0x02, 0x61, 0xc4, 0xe2, 0x3a,
0x88, 0xa8, 0x70, 0x04, 0xbd, 0x49, 0x52, 0x4a, 0x1d, 0x7f, 0x82, 0xa3, 0x3d, 0x40, 0x5e, 0x70,
0x12, 0x88, 0x43, 0xca, 0xbc, 0xf9, 0xb0, 0xc9, 0xb2, 0xae, 0x68, 0x91, 0x19, 0xc4, 0x75, 0x7c,
0xff, 0xd2, 0x71, 0x3f, 0x24, 0xd1, 0x3a, 0x0d, 0x4e, 0x4b, 0x28, 0x3a, 0x80, 0x6a, 0xe4, 0xb0,
0x29, 0xe1, 0x5a, 0x4d, 0xdd, 0x85, 0x9e, 0xaf, 0x59, 0x7d, 0x2c, 0x8d, 0x70, 0x6a, 0x8b, 0x06,
0x50, 0x0b, 0x42, 0x41, 0x03, 0xc6, 0xb5, 0xba, 0xea, 0xf6, 0xd5, 0x3d, 0x4e, 0xdb, 0x3b, 0x4d,
0xcc, 0x4d, 0x26, 0xa2, 0x5b, 0x9c, 0x75, 0x46, 0x3d, 0x68, 0x72, 0x39, 0x41, 0x77, 0x18, 0x70,
0xc1, 0xb5, 0x86, 0xe2, 0xfa, 0xcd, 0x3a, 0xae, 0xdc, 0x12, 0x17, 0x7b, 0xed, 0xfc, 0x00, 0xad,
0x22, 0xbb, 0x8c, 0xef, 0x1f, 0xc8, 0x6d, 0xea, 0x37, 0x59, 0x94, 0x27, 0x4c, 0xdd, 0xe4, 0x52,
0x37, 0x25, 0x95, 0x1f, 0xca, 0xdf, 0x6f, 0xe8, 0x01, 0x6c, 0x2f, 0xcd, 0x51, 0x65, 0x2b, 0x59,
0x38, 0x0e, 0x7e, 0x26, 0x51, 0x7e, 0xe3, 0xca, 0x91, 0xbc, 0xfd, 0x3c, 0x0c, 0x49, 0x76, 0xc0,
0x0b, 0x48, 0xee, 0x73, 0x75, 0x43, 0x28, 0xfa, 0x5c, 0x02, 0xfa, 0xf7, 0xf0, 0x68, 0xd5, 0x8c,
0xa4, 0xe8, 0x99, 0xe3, 0x66, 0x57, 0xc9, 0x99, 0xe3, 0xaa, 0x5c, 0x1e, 0xa6, 0xfc, 0x65, 0x1a,
0xea, 0xff, 0xac, 0x40, 0xeb, 0x82, 0x0e, 0x68, 0xbe, 0x4d, 0x77, 0xa0, 0xee, 0x51, 0x5e, 0x4c,
0x7a, 0x79, 0x5d, 0xd2, 0x45, 0x64, 0x9a, 0x65, 0xbd, 0x88, 0x4c, 0xd1, 0x7e, 0xe1, 0x2a, 0xd3,
0x59, 0x8a, 0x83, 0x45, 0xda, 0xe2, 0xe1, 0x37, 0xa0, 0xe1, 0xc4, 0xe2, 0xda, 0x56, 0x1d, 0x37,
0x55, 0xc7, 0x37, 0xeb, 0x3b, 0x1a, 0x13, 0xb9, 0x65, 0x55, 0xf7, 0xba, 0x93, 0x96, 0x64, 0x02,
0x71, 0x42, 0xdb, 0xbd, 0x76, 0x18, 0x23, 0xbe, 0xda, 0xaf, 0x6d, 0xdc, 0x70, 0xc2, 0x5e, 0x02,
0xa0, 0xaf, 0xa1, 0x7e, 0xc8, 0x79, 0xef, 0x6a, 0x6a, 0x4c, 0xd2, 0xe3, 0xff, 0x70, 0x61, 0x80,
0x43, 0xcb, 0xea, 0x5d, 0x4d, 0x71, 0x6e, 0x84, 0xbe, 0x83, 0x56, 0x52, 0xee, 0xf9, 0x94, 0x30,
0xa1, 0xb2, 0xea, 0x9a, 0x4e, 0x0b, 0x86, 0xe8, 0x35, 0xb4, 0x9c, 0xd0, 0xbe, 0xa6, 0x1e, 0xb1,
0x39, 0xa7, 0x5e, 0x9a, 0x70, 0xc1, 0x09, 0x87, 0xd4, 0x23, 0x16, 0xa7, 0x1e, 0xfa, 0x1c, 0x3a,
0xe9, 0xfa, 0xd9, 0x8c, 0x7c, 0x9c, 0x05, 0x2c, 0xcd, 0xa4, 0xed, 0x14, 0x3d, 0x51, 0xa0, 0xfe,
0x55, 0x1a, 0x6a, 0xaa, 0x50, 0x36, 0x26, 0xdd, 0x12, 0xaa, 0x41, 0xc5, 0x3a, 0x33, 0xba, 0x1b,
0xe8, 0x21, 0x6c, 0x5b, 0x67, 0x86, 0x3d, 0x30, 0x46, 0xc7, 0xa7, 0xef, 0x4d, 0x6c, 0x1b, 0x93,
0x6e, 0x59, 0x7f, 0x03, 0x30, 0x5f, 0x17, 0xd4, 0x82, 0xfa, 0xc5, 0xc4, 0xd8, 0xb7, 0x27, 0xd6,
0xbb, 0x6e, 0x09, 0xd5, 0x61, 0xf3, 0x74, 0x62, 0x9e, 0x74, 0x37, 0xf4, 0x3d, 0xa8, 0x26, 0xa2,
0x65, 0x10, 0xb7, 0xac, 0x51, 0x3f, 0x0b, 0xe2, 0xb2, 0x2c, 0x9d, 0x39, 0xb1, 0xde, 0x65, 0xce,
0x9c, 0x58, 0xef, 0xf4, 0x1a, 0x6c, 0x99, 0xb3, 0x50, 0xdc, 0xee, 0xff, 0xbb, 0x09, 0xd5, 0xc9,
0xc1, 0xc5, 0xc9, 0xe4, 0x5b, 0x34, 0x06, 0xed, 0x88, 0x88, 0x3e, 0x09, 0xfd, 0xe0, 0x96, 0x78,
0x0b, 0x69, 0x06, 0xa1, 0xc5, 0xc0, 0x2f, 0xbb, 0xee, 0x7c, 0x76, 0x47, 0x2a, 0xd4, 0x4b, 0x68,
0x08, 0x0f, 0x13, 0xae, 0xff, 0x9b, 0x69, 0x00, 0x0f, 0x8e, 0x88, 0x58, 0xba, 0xb0, 0xfd, 0x0f,
0x3c, 0xa7, 0xf0, 0xc0, 0xfa, 0x84, 0xe7, 0xae, 0x3e, 0xf7, 0x11, 0xfe, 0x08, 0x9d, 0x23, 0x22,
0x8a, 0x57, 0xcf, 0x55, 0xaa, 0xb4, 0x05, 0xac, 0x60, 0x9d, 0x30, 0x58, 0x8b, 0x0c, 0x6b, 0xad,
0x77, 0x56, 0x70, 0xeb, 0x25, 0xd4, 0x87, 0xd6, 0x58, 0x5e, 0x6a, 0xcf, 0xc7, 0x96, 0xca, 0x09,
0xf7, 0x5c, 0x50, 0xd6, 0xb0, 0xd8, 0xf0, 0x2a, 0x71, 0xd6, 0xfa, 0xdb, 0xc1, 0x17, 0xbf, 0x2e,
0xf7, 0xaf, 0x19, 0xc0, 0x04, 0x94, 0x0c, 0x70, 0x41, 0xaf, 0xe6, 0x11, 0xe8, 0xd9, 0xda, 0x60,
0xb0, 0x86, 0x66, 0xac, 0xde, 0x2b, 0x38, 0x66, 0x69, 0xf6, 0x79, 0xb1, 0xfa, 0x65, 0x91, 0x3e,
0x93, 0x76, 0x9e, 0xaf, 0x6b, 0x96, 0x4f, 0x07, 0x45, 0xb7, 0x5d, 0xa4, 0x93, 0x2f, 0xa0, 0x7b,
0x18, 0xd7, 0x3f, 0x65, 0xf4, 0x12, 0xc2, 0xf0, 0x78, 0x38, 0xea, 0x1f, 0x11, 0x31, 0x7f, 0xdf,
0x24, 0xaf, 0xa1, 0xf5, 0xbd, 0xee, 0x95, 0x68, 0x02, 0x1a, 0x8e, 0xfa, 0x3d, 0x87, 0xb9, 0xc4,
0x9f, 0xab, 0xbc, 0x83, 0x70, 0xf5, 0xc2, 0x9d, 0xc0, 0xd3, 0x44, 0x1a, 0x8e, 0x19, 0xa3, 0x6c,
0x9a, 0xdb, 0xaf, 0xde, 0xb3, 0x2f, 0xd6, 0xf2, 0xcb, 0x27, 0xa0, 0x5e, 0x42, 0x87, 0xf0, 0x24,
0x97, 0x65, 0xf8, 0xfe, 0x3d, 0x74, 0xab, 0x35, 0x1d, 0x42, 0x73, 0x60, 0xe5, 0x2f, 0xff, 0xa5,
0x95, 0x5f, 0xfe, 0x11, 0x58, 0xc3, 0xf1, 0x0e, 0x60, 0x60, 0x65, 0xff, 0x0d, 0x68, 0x71, 0x31,
0x97, 0xfe, 0x35, 0x96, 0x26, 0xb5, 0xfc, 0x49, 0xa1, 0x16, 0xa9, 0x3d, 0xb0, 0x8e, 0x88, 0xc8,
0x9e, 0xfb, 0x4b, 0x7c, 0x4b, 0x9f, 0x05, 0x4b, 0x7c, 0xcb, 0x7f, 0x04, 0x7a, 0x09, 0xfd, 0x04,
0x8f, 0x07, 0x56, 0x2f, 0x22, 0x8e, 0x20, 0x0b, 0x9f, 0x33, 0x68, 0xf1, 0x86, 0xb2, 0xea, 0x6b,
0x68, 0x47, 0xbf, 0xcb, 0x24, 0x1f, 0xe1, 0x47, 0x68, 0xaa, 0xef, 0xa6, 0x63, 0x75, 0x6f, 0x5c,
0xda, 0x16, 0xc5, 0x3f, 0xb5, 0xe5, 0xe5, 0x93, 0x4d, 0x7a, 0xe9, 0x9b, 0x8d, 0xcb, 0xaa, 0xfa,
0x8f, 0xfb, 0xfd, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x4e, 0xa1, 0xc4, 0x21, 0x9d, 0x13, 0x00,
0x00,
}

View File

@ -3,6 +3,7 @@ syntax = "proto3";
package P4wnP1_grpc;
service P4WNP1 {
//USB gadget
rpc GetDeployedGadgetSetting (Empty) returns (GadgetSettings) {}
rpc DeployGadgetSetting (Empty) returns (GadgetSettings) {}
rpc GetGadgetSettings (Empty) returns (GadgetSettings) {}
@ -11,10 +12,13 @@ service P4WNP1 {
rpc SetLEDSettings (LEDSettings) returns (Empty) {}
rpc MountUMSFile (GadgetSettingsUMS) returns (Empty) {}
//Ethernet
rpc DeployEthernetInterfaceSettings(EthernetInterfaceSettings) returns (Empty) {}
// WiFi
rpc DeployWifiSettings(WiFiSettings) returns (Empty) {}
//HIDScript / job management
rpc HIDRunScript(HIDScriptRequest) returns (HIDScriptResult) {}
rpc HIDRunScriptJob(HIDScriptRequest) returns (HIDScriptJob) {}
rpc HIDGetScriptJobResult(HIDScriptJob) returns (HIDScriptResult) {}
@ -22,10 +26,32 @@ service P4WNP1 {
rpc HIDGetRunningScriptJobs(Empty) returns (HIDScriptJobList) {}
rpc HIDCancelAllScriptJobs(Empty) returns (Empty) {}
//FileSystem
rpc FSWriteFile(WriteFileRequest) returns (Empty) {}
rpc FSReadFile(ReadFileRequest) returns (ReadFileResponse) {}
rpc FSGetFileInfo(FileInfoRequest) returns (FileInfoResponse) {}
rpc FSCreateTempDirOrFile(TempDirOrFileRequest) returns (TempDirOrFileResponse) {}
//Events
rpc EventListen(EventRequest) returns (stream Event) {}
}
/* Events */
message EventRequest {
int64 listenType = 1;
}
message EventValue {
oneof val {
string tstring = 1;
bool tbool = 2;
int64 tint64 = 3;
}
}
message Event {
int64 type = 1;
repeated EventValue values = 2;
}
/* File System */

160
service/Event.go Normal file
View File

@ -0,0 +1,160 @@
package service
import (
"fmt"
pb "../proto"
"../common"
"context"
"sync"
)
var (
EvMgr *EventManager
evmMutex = &sync.Mutex{}
)
func pDEBUG(message string) {
fmt.Println("EVENT DEBUG: " + message)
}
type EventManager struct {
eventQueue chan *pb.Event
ctx context.Context
cancel context.CancelFunc
registeredReceivers map[*EventReceiver]bool
receiverDeleteList map[*EventReceiver]bool
receiverRegisterList map[*EventReceiver]bool
receiverDelListMutex *sync.Mutex
receiverRegListMutex *sync.Mutex
}
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) {
em.eventQueue <-event
fmt.Println("Event enqueued")
}
func (em *EventManager) RegisterReceiver() *EventReceiver {
ctx,cancel := context.WithCancel(context.Background())
er := &EventReceiver{
EventQueue: make(chan *pb.Event, 10), //allow buffering 10 events per receiver
Ctx: ctx,
Cancel: cancel,
}
em.receiverRegListMutex.Lock()
em.receiverRegisterList[er] = true
em.receiverRegListMutex.Unlock()
return er
}
func (em *EventManager) UnregisterReceiver(receiver *EventReceiver) {
em.receiverDelListMutex.Lock()
em.receiverDeleteList[receiver] = true
em.receiverDelListMutex.Unlock()
}
func (em *EventManager) dispatch() {
fmt.Println("Started event dispatcher")
pDEBUG("Started dispatcher")
loop:
for {
select {
case evToDispatch := <- em.eventQueue:
// distribute to registered receiver
// Note: no mutex on em.registeredReceivers needed, only accessed in this method
for receiver := range em.registeredReceivers {
select {
case <-receiver.Ctx.Done():
//receiver canceled
em.UnregisterReceiver(receiver)
continue // go on with next registered receiver
case receiver.EventQueue <- evToDispatch:
//Do nothing
}
}
// delete receivers marked for deletion (only unregister function is allowed to put data into this map)
em.receiverDelListMutex.Lock()
for delReceiver := range em.receiverDeleteList {
delete(em.registeredReceivers, delReceiver)
close(delReceiver.EventQueue)
}
//Replace the delete list with a new one and let the GC take care of the old
em.receiverDeleteList = make(map[*EventReceiver]bool)
em.receiverDelListMutex.Unlock()
//add newly registered receivers
em.receiverRegListMutex.Lock()
for addReceiver := range em.receiverRegisterList {
em.registeredReceivers[addReceiver] = true
}
//Replace the register list with a new one and let the GC take care of the old
em.receiverRegisterList = make(map[*EventReceiver]bool)
em.receiverRegListMutex.Unlock()
case <-em.ctx.Done():
//EventManage aborted
// ToDo: close all eventReceivers eventQueues, to notify them of the stopped dispatcher
pDEBUG("EvtMgr cancelled")
break loop
}
}
fmt.Println("Stopped event dispatcher")
pDEBUG("Stopped dispatcher")
}
type EventReceiver struct {
Ctx context.Context
Cancel context.CancelFunc
EventQueue chan *pb.Event
}
func ConstructEventLog(source, message string) *pb.Event {
return &pb.Event{
Type: common.EVT_LOG,
Values: []*pb.EventValue{
{Val: &pb.EventValue_Tstring{Tstring:fmt.Sprintf(source)} },
{Val: &pb.EventValue_Tstring{Tstring:fmt.Sprintf(message)} },
},
}
}

View File

@ -4,10 +4,10 @@ package service
import (
"log"
pb "../proto"
"golang.org/x/net/context"
"context"
"net"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
// "google.golang.org/grpc/reflection"
"encoding/json"
"errors"
"fmt"
@ -29,6 +29,44 @@ var (
type server struct {}
func (s *server) EventListen(eReq *pb.EventRequest, eStream pb.P4WNP1_EventListenServer) (err error) {
//ToDo: Check if this needs to be wrapped into go routine
rcv := EvMgr.RegisterReceiver()
for {
/*
// generate test event with multiple values of multiple types
ev := &pb.Event{
Type: 0,
Values: []*pb.EventValue{
{Val: &pb.EventValue_Tbool{Tbool:true} },
{Val: &pb.EventValue_Tbool{Tbool:false} },
{Val: &pb.EventValue_Tstring{Tstring:fmt.Sprintf("message %d", i)} },
{Val: &pb.EventValue_Tint64{Tint64: int64(i)}},
},
}
*/
select {
case ev := <- rcv.EventQueue:
fmt.Printf("Event dequed to send: %+v\n", ev)
if ev.Type == eReq.ListenType || eReq.ListenType == common.EVT_ANY {
//send Event to stream
err = eStream.Send(ev)
if err != nil {
rcv.Cancel()
log.Println(err)
return err
}
}
case <-rcv.Ctx.Done():
return errors.New("Service stopped event manager")
}
}
}
func (s *server) FSWriteFile(ctx context.Context, req *pb.WriteFileRequest) (empty *pb.Empty, err error) {
return &pb.Empty{}, common.WriteFile(req.Path, req.MustNotExist, req.Append, req.Data)
@ -274,8 +312,10 @@ func StartRpcServer(host string, port string) {
//Create gRPC Server
s := grpc.NewServer()
pb.RegisterP4WNP1Server(s, &server{})
/*
// Register reflection service on gRPC server.
reflection.Register(s)
*/
if err := s.Serve(lis); err != nil {
log.Fatalf("Failed to serve: %v", err)
}

View File

@ -1,23 +1,18 @@
package main
import (
"context"
"fmt"
"strings"
"time"
pb "../proto/gopherjs"
"honnef.co/go/js/dom"
"github.com/gopherjs/gopherjs/js"
"github.com/HuckRidgeSW/hvue"
"time"
"../common"
)
var (
document = dom.GetWindow().Document().(dom.HTMLDocument)
serverAddr = GetBaseURL()
Client = pb.NewP4WNP1Client(
serverAddr + ":80",
)
Client = NewRpcClient(serverAddr + ":80")
GS *pb.GadgetSettings
)
@ -39,10 +34,26 @@ type appController struct {
func main() {
println(GetBaseURL())
println("Listening for RPC events ...")
err := Client.StartListenEvents(common.EVT_ANY)
if err != nil {println(err)}
time.Sleep(time.Second * 5)
Client.StopEventListening()
println("... done listening for RPC events")
time.Sleep(time.Second)
println("Listening for RPC events ...")
err = Client.StartListenEvents(common.EVT_LOG)
if err != nil {println(err)}
/*
fmt.Printf("Address %v\n", strings.TrimSuffix(document.BaseURI(), "/"))
fmt.Printf("Client %v\n", Client)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
@ -54,6 +65,7 @@ func main() {
} else {
fmt.Printf("Error rpc call: %v\n", err)
}
*/
InitCompEthernetAddresses2()
InitCompToggleSwitch()

96
web_client/rpcClient.go Normal file
View File

@ -0,0 +1,96 @@
package main
import (
pb "../proto/gopherjs"
"context"
"io"
"sync"
"errors"
)
type Rpc struct {
*sync.Mutex
Client pb.P4WNP1Client
eventListeningOn bool
eventListeningCtx *context.Context
eventListeningCancel *context.CancelFunc
}
func (rpc *Rpc) StartListenEvents(evtType int64) (err error) {
rpc.Lock()
if rpc.eventListeningOn {
rpc.Unlock()
return errors.New("Already listening to events")
}
// shouldn't happen
if rpc.eventListeningCancel != nil {
//Cancel old eventListeners
cancel := *rpc.eventListeningCancel
cancel()
}
ctx,cancel := context.WithCancel(context.Background())
rpc.eventListeningCtx = &ctx
rpc.eventListeningCancel = &cancel
rpc.eventListeningOn = true
rpc.Unlock()
evStream, err := rpc.Client.EventListen(ctx, &pb.EventRequest{ListenType: evtType})
if err != nil { return err }
go func() {
defer rpc.StopEventListening()
for {
event, err := evStream.Recv()
if err == io.EOF { break }
if err != nil { return }
println("Event: ", event)
}
return
}()
return nil
}
func (rpc *Rpc) StopEventListening() {
rpc.Lock()
if rpc.eventListeningCancel != nil {
(*rpc.eventListeningCancel)()
}
rpc.eventListeningCancel = nil
rpc.eventListeningCtx= nil
rpc.eventListeningOn = false
rpc.Unlock()
}
func NewRpcClient(addr string) Rpc {
rcl := Rpc{}
rcl.Mutex = &sync.Mutex{}
cl := pb.NewP4WNP1Client(addr)
rcl.Client = cl
return rcl
}
/*
func ClientRegisterEvent(host string, port string, evtType int64) (err error) {
// open gRPC Client
address := host + ":" + port
connection, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {return}
defer connection.Close()
client := pb.NewP4WNP1Client(connection)
evStream, err := client.EventListen(context.Background(), &pb.EventRequest{ListenType: evtType})
if err != nil { return err }
for {
event, err := evStream.Recv()
if err == io.EOF { break }
if err != nil { return err }
log.Printf("Event: %+v", event)
}
return nil
}
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long