|
|
|
@ -16,109 +16,105 @@ import (
|
|
|
|
|
pb "FRMS/internal/pkg/grpc"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Hardware struct {
|
|
|
|
|
Id uint32
|
|
|
|
|
Ip string
|
|
|
|
|
Bus int
|
|
|
|
|
Model string
|
|
|
|
|
Port int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type HWinfo interface {
|
|
|
|
|
Get() (*Hardware, error)
|
|
|
|
|
type Hardware interface {
|
|
|
|
|
GetId() uint32
|
|
|
|
|
GetIp() string
|
|
|
|
|
GetBus() int
|
|
|
|
|
GetModel() string
|
|
|
|
|
GetPort() int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Coordinator struct {
|
|
|
|
|
Server string
|
|
|
|
|
HW Hardware
|
|
|
|
|
Connected <-chan int
|
|
|
|
|
Disconnected <-chan int
|
|
|
|
|
Sensors map[int]SensorManager
|
|
|
|
|
I2CMonitor I2Cmonitor
|
|
|
|
|
Sensors *SensorManagers // struct for fine grain locking
|
|
|
|
|
Err chan error
|
|
|
|
|
mu sync.Mutex
|
|
|
|
|
pb.UnimplementedMonitoringServer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type SensorManagers struct {
|
|
|
|
|
Managers map[int]SensorManager
|
|
|
|
|
mu sync.Mutex
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type SensorManager interface {
|
|
|
|
|
Start()
|
|
|
|
|
GetStatus() bool
|
|
|
|
|
GetStatus() string
|
|
|
|
|
GetType() string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewSensorManager(addr int) SensorManager {
|
|
|
|
|
return sensor.NewSensorManager(addr)
|
|
|
|
|
type I2Cmonitor interface {
|
|
|
|
|
CreateDevice(int) error
|
|
|
|
|
GetStatus(int) bool
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewSensorManager(addr int,m I2Cmonitor) (SensorManager, error) {
|
|
|
|
|
return sensor.NewSensorManager(addr,m)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewCoordinator(s string,ch chan error) *Coordinator {
|
|
|
|
|
c := make(Coordinator{Server:s,Err:ch}
|
|
|
|
|
c.Connected = make(<-chan int)
|
|
|
|
|
c.Disconnected = make(<-chan int)
|
|
|
|
|
return c
|
|
|
|
|
sen := new(SensorManagers)
|
|
|
|
|
sen.Managers = make(map[int]SensorManager)
|
|
|
|
|
return &Coordinator{Server:s,Err:ch,Sensors:sen}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewI2CMonitor(c, dc <-chan int, b int) error {
|
|
|
|
|
return I2C.NewMonitor(b)
|
|
|
|
|
func NewI2CMonitor(c chan<- int, b int) (I2Cmonitor, error) {
|
|
|
|
|
return I2C.NewMonitor(c,b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetHWInfo() Hwinfo {
|
|
|
|
|
return system.NewHWMonitor()
|
|
|
|
|
func GetHWInfo() (Hardware, error) {
|
|
|
|
|
return system.NewHWinfo()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Coordinator) Start() error {
|
|
|
|
|
// should discover hwinfo and sensors on its own
|
|
|
|
|
// now setting up sensor managers
|
|
|
|
|
c.HW, err = GetHWInfo()
|
|
|
|
|
hw, err := GetHWInfo()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
err = NewI2CMonitor(c.Connect,c.Disconnect,c.Bus)
|
|
|
|
|
c.HW = hw
|
|
|
|
|
con := make(chan int)
|
|
|
|
|
c.Connected = con
|
|
|
|
|
monitor, err := NewI2CMonitor(con,c.HW.GetBus())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
fmt.Printf("Reactor at IP addr %v using I2C bus %v\n",c.Ip,c.Bus)
|
|
|
|
|
response := c.EstablishConnection()
|
|
|
|
|
for response != nil {
|
|
|
|
|
fmt.Println("Connection failed!, Retrying")
|
|
|
|
|
response = c.EstablishConnection()
|
|
|
|
|
c.I2CMonitor = monitor
|
|
|
|
|
fmt.Printf("Reactor at IP addr %v using I2C bus %v\n",c.HW.GetIp(),c.HW.GetBus())
|
|
|
|
|
err = c.EstablishConnection()
|
|
|
|
|
for err != nil {
|
|
|
|
|
fmt.Printf("Connection failed: %v \n Retrying!\n",err)
|
|
|
|
|
}
|
|
|
|
|
c.Register()
|
|
|
|
|
go c.Monitor()
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Coordinator) Monitor() {
|
|
|
|
|
// function to automatically create and destroy sm
|
|
|
|
|
for {
|
|
|
|
|
select {
|
|
|
|
|
case addr := <-c.Connect:
|
|
|
|
|
//check if sm exists and add sm for addr
|
|
|
|
|
c.Connected(addr)
|
|
|
|
|
case addr := <-c.Disconnect:
|
|
|
|
|
// kill sm for addr
|
|
|
|
|
c.Disconnected(addr)
|
|
|
|
|
}
|
|
|
|
|
addr := <-c.Connected
|
|
|
|
|
go c.Connect(addr)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Coordinator) Connected(addr int) {
|
|
|
|
|
c.mu.Lock()
|
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
|
sm, exists := c.Sensors[addr]
|
|
|
|
|
func (c *Coordinator) Connect(addr int) {
|
|
|
|
|
c.Sensors.mu.Lock()
|
|
|
|
|
defer c.Sensors.mu.Unlock()
|
|
|
|
|
_, exists := c.Sensors.Managers[addr]
|
|
|
|
|
if !exists {
|
|
|
|
|
sm := NewSensorManager(addr)
|
|
|
|
|
c.Sensors[addr] = sm
|
|
|
|
|
go sm.Start()
|
|
|
|
|
} // ignoring case of existing sm
|
|
|
|
|
go c.I2CMonitor.CreateDevice(addr)
|
|
|
|
|
sm, err := NewSensorManager(addr,c.I2CMonitor)
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.Err <-err
|
|
|
|
|
}
|
|
|
|
|
c.Sensors.Managers[addr] = sm
|
|
|
|
|
} // ignoring case of existing sm eventually will have to check for alive
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Coordinator) Disconnected(addr int) {
|
|
|
|
|
c.mu.Lock()
|
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
|
sm, exists := c.Sensors[addr]
|
|
|
|
|
if exists {
|
|
|
|
|
c.Sensors = delete(c.Sensors,addr)
|
|
|
|
|
sm.Kill()
|
|
|
|
|
} // not dealing with kill requests for not existing sm
|
|
|
|
|
|
|
|
|
|
func (c *Coordinator) EstablishConnection() error {
|
|
|
|
|
// function connects to central server and passes hwinfo
|
|
|
|
|
var opts []grpc.DialOption
|
|
|
|
@ -129,7 +125,7 @@ func (c *Coordinator) EstablishConnection() error {
|
|
|
|
|
}
|
|
|
|
|
defer conn.Close()
|
|
|
|
|
client := pb.NewHandshakeClient(conn)
|
|
|
|
|
req := &pb.ReactorDiscoveryRequest{Id:c.Id,Ip:c.Ip,Port:c.Port,Model:c.Model}
|
|
|
|
|
req := &pb.ReactorDiscoveryRequest{Id:c.HW.GetId(),Ip:c.HW.GetIp(),Port:int32(c.HW.GetPort()),Model:c.HW.GetModel()}
|
|
|
|
|
resp, err := client.ReactorDiscoveryHandler(context.Background(), req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
@ -143,8 +139,8 @@ func (c *Coordinator) EstablishConnection() error {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Coordinator) Register() error {
|
|
|
|
|
fmt.Printf("Listing for pings on %v:%v\n",c.Ip,c.Port)
|
|
|
|
|
lis, err := net.Listen("tcp", fmt.Sprintf("%v:%v",c.Ip(),c.Port))
|
|
|
|
|
fmt.Printf("Listing for pings on %v:%v\n",c.HW.GetIp(),c.HW.GetPort())
|
|
|
|
|
lis, err := net.Listen("tcp", fmt.Sprintf("%v:%v",c.HW.GetIp(),c.HW.GetPort()))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@ -154,12 +150,13 @@ func (c *Coordinator) Register() error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// sensor status stuff
|
|
|
|
|
func (c *Coordinator) SensorStatusHandler(ctx context.Context, ping *pb.SensorStatusRequest) (*pb.SensorStatusResponse,error) {
|
|
|
|
|
c.mu.Lock()
|
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
|
c.Sensors.mu.Lock()
|
|
|
|
|
defer c.Sensors.mu.Unlock()
|
|
|
|
|
var sensors []*pb.SensorStatus
|
|
|
|
|
resp := &pb.SensorStatusResponse{Id:c.Id,Sensors:sensors}
|
|
|
|
|
for a, s := range c.Sensors {
|
|
|
|
|
resp := &pb.SensorStatusResponse{Id:c.HW.GetId(),Sensors:sensors}
|
|
|
|
|
for a, s := range c.Sensors.Managers {
|
|
|
|
|
resp.Sensors = append(resp.Sensors,&pb.SensorStatus{Addr:int32(a), Type:s.GetType(), Status:s.GetStatus()})
|
|
|
|
|
}
|
|
|
|
|
return resp, nil
|
|
|
|
|