Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

138 lignes
2.9 KiB

  1. package main
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "encoding/json"
  6. "fmt"
  7. "io"
  8. "os"
  9. "sync"
  10. "github.com/AFASystems/presence/internal/pkg/model"
  11. )
  12. type parserConfig struct {
  13. Length int `json:"length"`
  14. Offset int `json:"offset"`
  15. Order string `json:"order"`
  16. }
  17. type beaconParser struct {
  18. name string
  19. canParse func([]byte) bool
  20. configs map[string]parserConfig
  21. }
  22. type parserRegistry struct {
  23. parserList []beaconParser
  24. rw sync.RWMutex
  25. }
  26. type config struct {
  27. Name string `json:"name"`
  28. Min int `json:"min"`
  29. Max int `json:"max"`
  30. Pattern []string `json:"pattern"`
  31. Configs map[string]parserConfig `json:"configs"`
  32. }
  33. func (pc parserConfig) GetOrder() binary.ByteOrder {
  34. if pc.Order == "bigendian" {
  35. return binary.BigEndian
  36. }
  37. return binary.LittleEndian
  38. }
  39. func (p *parserRegistry) Register(name string, c config) {
  40. p.rw.Lock()
  41. defer p.rw.Unlock()
  42. b := beaconParser{
  43. name: name,
  44. canParse: func(ad []byte) bool {
  45. return len(ad) >= c.Min && len(ad) <= c.Max && bytes.HasPrefix(ad, c.GetPatternBytes())
  46. },
  47. configs: c.Configs,
  48. }
  49. p.parserList = append(p.parserList, b)
  50. }
  51. func (b *beaconParser) Parse(ad []byte) (model.BeaconEvent, bool) {
  52. flag := false
  53. event := model.BeaconEvent{Type: b.name}
  54. if cfg, ok := b.configs["battery"]; ok {
  55. event.Battery = uint32(b.extract(ad, cfg))
  56. flag = true
  57. }
  58. if cfg, ok := b.configs["accX"]; ok {
  59. event.AccX = int16(b.extract(ad, cfg))
  60. flag = true
  61. }
  62. if cfg, ok := b.configs["accY"]; ok {
  63. event.AccY = int16(b.extract(ad, cfg))
  64. flag = true
  65. }
  66. if cfg, ok := b.configs["accZ"]; ok {
  67. event.AccZ = int16(b.extract(ad, cfg))
  68. flag = true
  69. }
  70. return event, flag
  71. }
  72. func (b *beaconParser) extract(ad []byte, pc parserConfig) uint16 {
  73. if len(ad) < pc.Offset+pc.Length {
  74. return 0
  75. }
  76. data := ad[pc.Offset : pc.Offset+pc.Length]
  77. if pc.Length == 1 {
  78. return uint16(data[0])
  79. }
  80. return pc.GetOrder().Uint16(data)
  81. }
  82. func (c config) GetPatternBytes() []byte {
  83. res := make([]byte, len(c.Pattern))
  84. for i, s := range c.Pattern {
  85. fmt.Sscanf(s, "0x%02x", &res[i])
  86. }
  87. return res
  88. }
  89. func main() {
  90. parserRegistry := parserRegistry{
  91. parserList: make([]beaconParser, 0),
  92. }
  93. seq := []byte{0x02, 0x01, 0x06, 0x64, 0x01, 0xF4, 0x00, 0x0A, 0xFF, 0x05}
  94. jsonFile, err := os.Open("configs.json")
  95. if err != nil {
  96. fmt.Println(err)
  97. }
  98. fmt.Println("succesfully opened json file")
  99. b, _ := io.ReadAll(jsonFile)
  100. var configs []config
  101. json.Unmarshal(b, &configs)
  102. for _, config := range configs {
  103. parserRegistry.Register(config.Name, config)
  104. }
  105. for _, parser := range parserRegistry.parserList {
  106. if parser.canParse(seq) {
  107. event, ok := parser.Parse(seq)
  108. if ok {
  109. fmt.Printf("Device: %s | Battery: %d%% | AccX: %d | AccY: %d | AccZ: %d\n", event.Type, event.Battery, event.AccX, event.AccY, event.AccZ)
  110. }
  111. }
  112. }
  113. fmt.Printf("configs: %+v\n", configs)
  114. jsonFile.Close()
  115. }