Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

72 řádky
1.8 KiB

  1. package decoder
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/hex"
  6. "fmt"
  7. "log/slog"
  8. "strings"
  9. "github.com/AFASystems/presence/internal/pkg/common/appcontext"
  10. "github.com/AFASystems/presence/internal/pkg/common/utils"
  11. "github.com/AFASystems/presence/internal/pkg/model"
  12. "github.com/segmentio/kafka-go"
  13. )
  14. // AlertWriter writes decoded beacon events (e.g. to alertbeacons topic).
  15. type AlertWriter interface {
  16. WriteMessages(ctx context.Context, msgs ...kafka.Message) error
  17. }
  18. // ProcessIncoming decodes a beacon advertisement and writes the event to the writer if it changed.
  19. func ProcessIncoming(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer AlertWriter, registry *model.ParserRegistry) {
  20. if err := DecodeBeacon(adv, appState, writer, registry); err != nil {
  21. slog.Error("decoding beacon", "err", err, "id", adv.ID)
  22. }
  23. }
  24. // DecodeBeacon hex-decodes the payload, runs the parser registry, dedupes by event hash, and writes to writer.
  25. func DecodeBeacon(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer AlertWriter, registry *model.ParserRegistry) error {
  26. beacon := strings.TrimSpace(adv.Data)
  27. id := adv.ID
  28. if beacon == "" {
  29. return nil
  30. }
  31. b, err := hex.DecodeString(beacon)
  32. if err != nil {
  33. return err
  34. }
  35. b = utils.RemoveFlagBytes(b)
  36. indices := utils.ParseADFast(b)
  37. event := utils.LoopADStructures(b, indices, id, registry)
  38. if event.ID == "" {
  39. return nil
  40. }
  41. prevEvent, ok := appState.GetBeaconEvent(id)
  42. appState.UpdateBeaconEvent(id, event)
  43. if event.Type == "iBeacon" {
  44. event.BtnPressed = true
  45. }
  46. if ok && bytes.Equal(prevEvent.Hash(), event.Hash()) {
  47. return nil
  48. }
  49. eMsg, err := event.ToJSON()
  50. if err != nil {
  51. return err
  52. }
  53. if err := writer.WriteMessages(context.Background(), kafka.Message{Value: eMsg}); err != nil {
  54. return fmt.Errorf("write alert: %w", err)
  55. }
  56. return nil
  57. }