package main import ( "flag" "os" "os/signal" "protomolecule/src/dust" "protomolecule/src/eros" "protomolecule/src/protogen" projVars "protomolecule/src/vars" "syscall" "time" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) var ( manufLoad bool ) 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.AFlag { projVars.AttackMode = true } if *projVars.DFlag { zerolog.SetGlobalLevel(zerolog.DebugLevel) } if *projVars.TFlag { projVars.TrackingMode = true } if *projVars.MFlag != "0" { projVars.ManuFile = *projVars.MFlag manufLoad = true } } func sigHandler() { c := make(chan os.Signal) signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { <-c log.Warn().Msg("Interrupt detected, shutting down gracefully...") eros.Slumber() os.Exit(0) }() } 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{ Count: 0, Scans: make(map[int]*protogen.Scan), Mailbox: make(chan protogen.Postcard), } loginit() cliFlags() sigHandler() log.Debug().Msg("Logging initialized") // 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 main() { defer eros.Slumber() 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()) }