Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 

109 righe
2.4 KiB

  1. package main
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/hex"
  6. "fmt"
  7. "strings"
  8. "github.com/AFASystems/presence/internal/pkg/common/appcontext"
  9. "github.com/AFASystems/presence/internal/pkg/common/utils"
  10. "github.com/AFASystems/presence/internal/pkg/config"
  11. "github.com/AFASystems/presence/internal/pkg/kafkaclient"
  12. "github.com/AFASystems/presence/internal/pkg/model"
  13. "github.com/segmentio/kafka-go"
  14. )
  15. func main() {
  16. // Load global context to init beacons and latest list
  17. appState := appcontext.NewAppState()
  18. cfg := config.Load()
  19. // Kafka reader for Raw MQTT beacons
  20. rawReader := kafkaclient.KafkaReader(cfg.KafkaURL, "rawbeacons", "gid-raw")
  21. defer rawReader.Close()
  22. // Kafka reader for API server updates
  23. apiReader := kafkaclient.KafkaReader(cfg.KafkaURL, "apibeacons", "gid-api")
  24. defer apiReader.Close()
  25. alertWriter := kafkaclient.KafkaWriter(cfg.KafkaURL, "alertbeacons")
  26. defer alertWriter.Close()
  27. fmt.Println("Decoder initialized, subscribed to Kafka topics")
  28. chRaw := make(chan model.BeaconAdvertisement, 2000)
  29. chApi := make(chan model.ApiUpdate, 2000)
  30. go kafkaclient.Consume(rawReader, chRaw)
  31. go kafkaclient.Consume(apiReader, chApi)
  32. for {
  33. select {
  34. case msg := <-chRaw:
  35. processIncoming(msg, appState, alertWriter)
  36. case msg := <-chApi:
  37. switch msg.Method {
  38. case "POST":
  39. id := msg.Beacon.ID
  40. appState.AddBeaconToLookup(id)
  41. case "DELETE":
  42. fmt.Println("Incoming delete message")
  43. }
  44. }
  45. }
  46. }
  47. func processIncoming(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer) {
  48. id := adv.MAC
  49. ok := appState.BeaconExists(id)
  50. if !ok {
  51. return
  52. }
  53. err := decodeBeacon(adv, appState, writer)
  54. if err != nil {
  55. fmt.Println("error in decoding")
  56. return
  57. }
  58. }
  59. func decodeBeacon(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer) error {
  60. beacon := strings.TrimSpace(adv.Data)
  61. id := adv.MAC
  62. if beacon == "" {
  63. return nil
  64. }
  65. b, err := hex.DecodeString(beacon)
  66. if err != nil {
  67. return err
  68. }
  69. b = utils.RemoveFlagBytes(b)
  70. indeces := utils.ParseADFast(b)
  71. event := utils.LoopADStructures(b, indeces, id)
  72. if event.ID == "" {
  73. return nil
  74. }
  75. prevEvent, ok := appState.GetBeaconEvent(id)
  76. appState.UpdateBeaconEvent(id, event)
  77. if ok && bytes.Equal(prevEvent.Hash(), event.Hash()) {
  78. return nil
  79. }
  80. eMsg, err := event.ToJSON()
  81. if err != nil {
  82. return err
  83. }
  84. if err := writer.WriteMessages(context.Background(), kafka.Message{Value: eMsg}); err != nil {
  85. return err
  86. }
  87. return nil
  88. }