162 lines
3.5 KiB
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()
|
|
}
|