|
|
|
package I2C
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os/exec"
|
|
|
|
"bytes"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
"sync"
|
|
|
|
"strconv"
|
|
|
|
pb "FRMS/internal/pkg/grpc"
|
|
|
|
)
|
|
|
|
|
|
|
|
type I2Cdev struct {
|
|
|
|
Addr int
|
|
|
|
Active bool
|
|
|
|
Bus int // may be redundant but need to see if I can get around central struct
|
|
|
|
LastSeen time.Time
|
|
|
|
}
|
|
|
|
|
|
|
|
type I2CMonitor struct { // used in RLC to synchronize accesses
|
|
|
|
Bus int // bus to use {0,1,2}
|
|
|
|
Devices map[int]I2Cdev // mapping to quickly index addresses to their device structs
|
|
|
|
Id string //ip for gRPC
|
|
|
|
Port int
|
|
|
|
mu sync.Mutex
|
|
|
|
pb.UnimplementedMonitoringServer
|
|
|
|
}
|
|
|
|
|
|
|
|
func I2Cconnected(bus int) map[int]bool {
|
|
|
|
/*
|
|
|
|
I2CConnect takes an integer specifying the bus to search as input
|
|
|
|
Returns a slice of type I2Cdev
|
|
|
|
*/
|
|
|
|
b := strconv.Itoa(bus)
|
|
|
|
cmd := exec.Command("i2cdetect", "-y", "-r", b)
|
|
|
|
var out bytes.Buffer
|
|
|
|
cmd.Stdout = &out
|
|
|
|
err:= cmd.Run()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
}
|
|
|
|
outString := out.String()
|
|
|
|
// could split by \n too
|
|
|
|
split := strings.SplitAfter(outString,":")
|
|
|
|
// 1st entry is garbage headers and ending is always \n##:
|
|
|
|
split = split[1:]
|
|
|
|
// create empty slice for all the devices
|
|
|
|
//var devices []i2cdev
|
|
|
|
devices := map[int]bool{} //maps device addresses to active bool
|
|
|
|
for i,v := range split {
|
|
|
|
lst := strings.Index(v,"\n")
|
|
|
|
trimmed := v[:lst]
|
|
|
|
trimmed = strings.Trim(trimmed," ")
|
|
|
|
// trimmed now holds just possible sensor addresses
|
|
|
|
count := strings.Split(trimmed," ")
|
|
|
|
for j,d := range count {
|
|
|
|
// the first row has to be offset by 3 but after its just i*16 + j
|
|
|
|
offset := 0
|
|
|
|
if i == 0 {
|
|
|
|
offset = 3
|
|
|
|
}
|
|
|
|
addr := i*16 + j + offset
|
|
|
|
if strings.Contains(d,"--") || strings.Contains(d,"UU") {
|
|
|
|
// address is unconnected or reserved
|
|
|
|
//devices = append(devices, I2Cdev{Addr:addr,Active:false})
|
|
|
|
devices[addr] = false
|
|
|
|
} else {
|
|
|
|
//devices = append(devices, I2Cdev{Addr:addr,Active:true,LastSeen:now})
|
|
|
|
devices[addr] = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return devices
|
|
|
|
}
|