protomolecule/main.go

162 lines
3.5 KiB
Go

package main
import (
"flag"
"os"
"os/signal"
"syscall"
"time"
projVars "protomolecule/src/config"
"protomolecule/src/dust"
"protomolecule/src/eros"
"protomolecule/src/protogen"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
var (
manufLoad bool
GitVersion string
BuildDate string
)
func loginit() {
// setup json logfile
// TODO: make this a command line argument
var logDir string = "./.logs/"
err := os.MkdirAll(logDir, 0755)
if err != nil {
panic(err.Error())
}
Now := time.Now()
date := Now.Format(time.RFC3339)
logFileName := date + ".log"
lf, err := os.OpenFile(logDir+logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(err.Error())
}
// define pretty printer
consoleWriter := zerolog.ConsoleWriter{Out: os.Stderr}
// initialize simultaneous pretty printing and json logging
multi := zerolog.MultiLevelWriter(consoleWriter, lf)
log.Logger = zerolog.New(multi).With().Timestamp().Logger()
// suppress debug messages unless -d is called
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
func cliFlags() {
flag.Parse()
if *projVars.GlobalConfig.CooleanFlags.Debug {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
manufLoad = *projVars.GlobalConfig.StringFlags.MACVendorFile != ""
}
func sigHandler() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
for {
select {
case <-c:
log.Warn().
Msg("Interrupt detected, stopping scan...")
for _, scan := range protogen.ScanMgr.Scans {
for _, dev := range scan.Device {
if dev.Connected {
_ = dev.Conn.Disconnect()
}
}
_ = scan.Stop()
}
}
}
}
func init() {
// Initializing an instance of our scan manager to keep track of concurrent scans
// NOTE: Devices are kept track of per Scan via a nested map of eros.Device instances
//
// TODO: Get all of this management stuff into its own package (structs and maps and initialization of the former)
// TODO: Name these structs and maps and instances more uniformly and idiomatically
dust.PrintBanner()
protogen.ScanMgr = &protogen.Meta{
Scans: make(map[int]*protogen.Scan),
Mailbox: make(chan protogen.Postcard),
}
loginit()
cliFlags()
go sigHandler()
if len(GitVersion) > 0 {
log.Info().
Str("Version", GitVersion).
Str("Built", BuildDate).
Msg("Initializing protomolecule")
}
// see ./src/eros
log.Debug().Msg("Initializing database engine")
eros.Awaken()
// loading manufacturer info from json file determined by flag
if manufLoad {
eros.ManufLoad()
}
}
func earToTheWire() {
var sublog zerolog.Logger
// Define our IPC callbacks here
interpret := func(m protogen.Postcard) {
switch m.Command {
case "quit":
sublog.Warn().
Int("from", m.From).
Msg("IPC_QUIT")
os.Exit(0)
}
}
for {
select {
case postcard := <-protogen.ScanMgr.Mailbox:
sublog = log.With().Int("scan_id", postcard.From).Logger()
interpret(postcard)
}
}
}
func bleScan() {
var scan *protogen.Scan
// Note: the tinygo bluetooth (prototooth here) library does already have a channel system for starting and stopping scans
// the rational behind implementing an additional IPC system has to do with potentially doing more than just BLE
//
// this starts our IPC listener so that we are ready to catch any incoming IPC messages before we start any scans
go earToTheWire()
scan = protogen.ScanMgr.NewScan()
// time.Sleep(30 * time.Millisecond)
go dust.Must("Scan", scan.Start())
}
func main() {
defer eros.Slumber()
StartCLI()
}