diff --git a/cmd/P4wnP1_service/P4wnP1_service.go b/cmd/P4wnP1_service/P4wnP1_service.go index e0c223d..036d5f7 100644 --- a/cmd/P4wnP1_service/P4wnP1_service.go +++ b/cmd/P4wnP1_service/P4wnP1_service.go @@ -3,17 +3,16 @@ package main import ( + "github.com/mame82/P4wnP1_go/common" "log" + "strconv" + "time" + "fmt" "github.com/mame82/P4wnP1_go/service" "os" "os/signal" "syscall" - "fmt" - pb "github.com/mame82/P4wnP1_go/proto" - "github.com/mame82/P4wnP1_go/common" - "time" - "strconv" ) @@ -40,13 +39,25 @@ func main() { */ // ToDo: The webroot has to be changed to /usr/local/P4wnP1/www - service.StartRpcServerAndWeb("0.0.0.0", "50051", "8000", "/usr/local/P4wnP1/www") //start gRPC service + //service.StartRpcServerAndWeb("0.0.0.0", "50051", "8000", "/usr/local/P4wnP1/www") //start gRPC service + /* //Indicate servers up with LED blink count 1 state.Led.SetLed(&pb.LEDSettings{1}) + */ + + + + + svc,err := service.NewService() + if err != nil { + panic(err) + } + svc.Start() + //service.StartEventManager(20) -// log.SetOutput(state.EvMgr) + // log.SetOutput(state.EvMgr) go func() { err := common.RunBashScript("/usr/local/P4wnP1/scripts/servicestart.sh") if err != nil { log.Printf("Error executing service startup script: %v\n", err) } @@ -66,7 +77,6 @@ func main() { }() - //use a channel to wait for SIGTERM or SIGINT fmt.Println("P4wnP1 service initialized, stop with SIGTERM or SIGINT") sig := make(chan os.Signal) diff --git a/service/SubSysLED.go b/service/SubSysLED.go new file mode 100644 index 0000000..466f2b5 --- /dev/null +++ b/service/SubSysLED.go @@ -0,0 +1,91 @@ +package service + +import ( + pb "github.com/mame82/P4wnP1_go/proto" + "io/ioutil" + "log" + "os" + "sync/atomic" + "time" +) + +const ( + pLED_TRIGGER_PATH = "/sys/class/leds/led0/trigger" + pLED_BRIGHTNESS_PATH = "/sys/class/leds/led0/brightness" + pLED_TRIGGER_MANUAL = "none" + pLED_ON = "0" + pLED_OFF = "1" + pLED_DELAY_ON = 200 * time.Millisecond + pLED_DELAY_OFF = 200 * time.Millisecond + pLED_DELAY_PAUSE = 500 * time.Millisecond +) + +type LedState1 struct { + Available bool + IsRunning bool + BlinkCount *uint32 +} + +type LedService struct { + state *LedState1 +} + +func NewLedService() (res *LedService) { + res = &LedService{ + state: &LedState1{}, + } + bc := uint32(0) + res.state.BlinkCount = &bc + + return res +} + +func (l *LedService) led_loop() { + ioutil.WriteFile(pLED_BRIGHTNESS_PATH, []byte(pLED_ON), os.ModePerm) + + for l.state.IsRunning{ + for i := uint32(0); i < atomic.LoadUint32(l.state.BlinkCount) && l.state.IsRunning; i++ { + ioutil.WriteFile(pLED_BRIGHTNESS_PATH, []byte(pLED_ON), os.ModePerm) + time.Sleep(pLED_DELAY_ON) + + //Don't turn off led if blink_count >= 255 (solid) + if 255 > atomic.LoadUint32(l.state.BlinkCount) { + ioutil.WriteFile(pLED_BRIGHTNESS_PATH, []byte(pLED_OFF), os.ModePerm) + time.Sleep(pLED_DELAY_OFF) + } + } + time.Sleep(pLED_DELAY_PAUSE) + } + + ioutil.WriteFile(pLED_BRIGHTNESS_PATH, []byte(pLED_ON), os.ModePerm) +} + +func (l *LedService) Start() error { + //set trigger of LED to manual + log.Println("Setting LED to manual trigger ...") + ioutil.WriteFile(pLED_TRIGGER_PATH, []byte(pLED_TRIGGER_MANUAL), os.ModePerm) + l.state.IsRunning = true + go l.led_loop() + + return nil +} + +func (l *LedService) Stop() { + l.state.IsRunning = false +} + +func (l *LedService) GetState() *LedState1 { + return l.state +} + +func (l *LedService) DeploySettings(sets *pb.LEDSettings) { + atomic.StoreUint32(l.state.BlinkCount, sets.BlinkCount) +} + +func (LedService) LoadSettings() { + panic("implement me") +} + +func (LedService) StoreSettings() { + panic("implement me") +} diff --git a/service/Temp.go b/service/Temp.go new file mode 100644 index 0000000..10069d3 --- /dev/null +++ b/service/Temp.go @@ -0,0 +1,11 @@ +package service + +type SubSys interface { + GetState() + DeploySettings() + LoadSettings() + StoreSettings() + SetLogger() + Start() + Stop() +} diff --git a/service/rpc_server.go b/service/rpc_server.go index 5373b3b..3471704 100644 --- a/service/rpc_server.go +++ b/service/rpc_server.go @@ -31,7 +31,26 @@ const ( cSTORE_PREFIX_WIFI_SETTINGS = "ws_" ) -type server struct {} +type server struct { + rootSvc *Service + + listenAddrGrpc string + listenAddrWeb string +} + +func NewRpcServerService(root *Service) *server { + return &server{ + rootSvc:root, + } +} + +func (s *server) Start() error { + return nil +} + +func (s *server) Stop() error { + return nil +} func (s *server) StoreDeployedWifiSettings(ctx context.Context, m *pb.StringMessage) (e *pb.Empty, err error) { return s.StoreWifiSettings(ctx, &pb.WifiRequestSettingsStorage{ @@ -366,18 +385,22 @@ func (s *server) SetGadgetSettings(ctx context.Context, gs *pb.GadgetSettings) ( } func (s *server) GetLEDSettings(context.Context, *pb.Empty) (res *pb.LEDSettings, err error) { - res, err = ServiceState.Led.GetLed() +// res, err = ServiceState.Led.GetLed() + state := s.rootSvc.SubSysLed.GetState() + res = &pb.LEDSettings{ + BlinkCount: *state.BlinkCount, + } log.Printf("GetLEDSettings, result: %+v", res) return } func (s *server) SetLEDSettings(ctx context.Context, ls *pb.LEDSettings) (*pb.Empty, error) { log.Printf("SetLEDSettings %+v", ls) - ServiceState.Led.SetLed(ls) + s.rootSvc.SubSysLed.DeploySettings(ls) return &pb.Empty{}, nil } - +/* func StartRpcServer(host string, port string) { listen_address := host + ":" + port //Open TCP listener @@ -390,14 +413,11 @@ 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) } } +*/ func folderReader(fn http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { @@ -409,6 +429,7 @@ func folderReader(fn http.Handler) http.HandlerFunc { } } +/* func StartRpcWebServer(host string, port string) { //Create gRPC Server s := grpc.NewServer() @@ -417,18 +438,6 @@ func StartRpcWebServer(host string, port string) { //grpc_web_srv := grpcweb.WrapServer(s, grpcweb.WithWebsockets(true)) //Wrap server to improbable grpc-web with websockets grpc_web_srv := grpcweb.WrapServer(s) //Wrap server to improbable grpc-web with websockets - /* - http_handler := func(resp http.ResponseWriter, req *http.Request) { - if req.ProtoMajor == 2 && strings.Contains(req.Header.Get("Content-Type"), "application/grpc") || - websocket.IsWebSocketUpgrade(req) { - grpc_web_srv.ServeHTTP(resp, req) - } else { - //No gRPC request - folderReader(http.FileServer(http.Dir("/home/pi/P4wnP1_go"))).ServeHTTP(resp, req) - } - } - */ - http_handler := func(resp http.ResponseWriter, req *http.Request) { grpc_web_srv.ServeHTTP(resp, req) } @@ -446,8 +455,9 @@ func StartRpcWebServer(host string, port string) { log.Printf("P4wnP1 gRPC-web server listening on " + listen_address) log.Fatal(http_srv.ListenAndServe()) } +*/ -func StartRpcServerAndWeb(host string, gRPCPort string, webPort string, absWebRoot string) () { +func (srv *server) StartRpcServerAndWeb(host string, gRPCPort string, webPort string, absWebRoot string) () { //ToDo: Return servers/TCP listener to allow closing from caller listen_address_grpc := host + ":" + gRPCPort listen_address_web := host + ":" + webPort @@ -455,7 +465,7 @@ func StartRpcServerAndWeb(host string, gRPCPort string, webPort string, absWebRo //Create gRPC Server s := grpc.NewServer() - pb.RegisterP4WNP1Server(s, &server{}) + pb.RegisterP4WNP1Server(s, srv) diff --git a/service/service.go b/service/service.go new file mode 100644 index 0000000..47452b4 --- /dev/null +++ b/service/service.go @@ -0,0 +1,35 @@ +package service + +import ( + "github.com/mame82/P4wnP1_go/service/datastore" +) + + +type Service struct { + SubSysState interface{} + SubSysLogging interface{} + SubSysDataStore *datastore.Store + SubSysEvent *EventManager + SubSysUSB *UsbGadgetManager + SubSysLed *LedService + SubSysWifi *WiFiService + SubSysBluetooth *BtService + SubSysRPC *server + SubSysTriggerActions interface{} +} + +func NewService() (svc *Service, err error) { + svc = &Service{} + svc.SubSysLed = NewLedService() + svc.SubSysRPC = NewRpcServerService(svc) + return +} + +func (s *Service) Start() { + s.SubSysLed.Start() + s.SubSysRPC.StartRpcServerAndWeb("0.0.0.0", "50051", "8000", "/usr/local/P4wnP1/www") //start gRPC service +} + +func (s *Service) Stop() { + s.SubSysLed.Stop() +} diff --git a/service/state.go b/service/state.go index 15b503e..0e06eb4 100644 --- a/service/state.go +++ b/service/state.go @@ -14,11 +14,16 @@ const ( var ServiceState *GlobalServiceState + +type SubSysState struct { + Led *LedState +} + type GlobalServiceState struct { Store *datastore.Store EvMgr *EventManager UsbGM *UsbGadgetManager - Led *LedState +// Led *LedState HidDevPath map[string]string //stores device path for HID devices StoredNetworkSettings map[string]*pb.EthernetInterfaceSettings WifiSvc *WiFiService @@ -70,13 +75,13 @@ func InitGlobalServiceState() (err error) { } state.BtSvc = NewBtService() - +/* ledState, err := NewLed(false) if err != nil { return } state.Led = ledState - +*/ return nil }