|
- package main
-
- import (
- "bytes"
- "encoding/binary"
- "encoding/json"
- "fmt"
- "io"
- "os"
- "sync"
-
- "github.com/AFASystems/presence/internal/pkg/model"
- )
-
- type parserConfig struct {
- Length int `json:"length"`
- Offset int `json:"offset"`
- Order string `json:"order"`
- }
-
- type beaconParser struct {
- name string
- canParse func([]byte) bool
- configs map[string]parserConfig
- }
-
- type parserRegistry struct {
- parserList []beaconParser
- rw sync.RWMutex
- }
-
- type config struct {
- Name string `json:"name"`
- Min int `json:"min"`
- Max int `json:"max"`
- Pattern []string `json:"pattern"`
- Configs map[string]parserConfig `json:"configs"`
- }
-
- func (pc parserConfig) GetOrder() binary.ByteOrder {
- if pc.Order == "bigendian" {
- return binary.BigEndian
- }
-
- return binary.LittleEndian
- }
-
- func (p *parserRegistry) Register(name string, c config) {
- p.rw.Lock()
- defer p.rw.Unlock()
-
- b := beaconParser{
- name: name,
- canParse: func(ad []byte) bool {
- return len(ad) >= c.Min && len(ad) <= c.Max && bytes.HasPrefix(ad, c.GetPatternBytes())
- },
- configs: c.Configs,
- }
-
- p.parserList = append(p.parserList, b)
- }
-
- func (b *beaconParser) Parse(ad []byte) (model.BeaconEvent, bool) {
- flag := false
- event := model.BeaconEvent{Type: b.name}
- if cfg, ok := b.configs["battery"]; ok {
- event.Battery = uint32(b.extract(ad, cfg))
- flag = true
- }
- if cfg, ok := b.configs["accX"]; ok {
- event.AccX = int16(b.extract(ad, cfg))
- flag = true
- }
- if cfg, ok := b.configs["accY"]; ok {
- event.AccY = int16(b.extract(ad, cfg))
- flag = true
- }
- if cfg, ok := b.configs["accZ"]; ok {
- event.AccZ = int16(b.extract(ad, cfg))
- flag = true
- }
- return event, flag
- }
-
- func (b *beaconParser) extract(ad []byte, pc parserConfig) uint16 {
- if len(ad) < pc.Offset+pc.Length {
- return 0
- }
- data := ad[pc.Offset : pc.Offset+pc.Length]
-
- if pc.Length == 1 {
- return uint16(data[0])
- }
-
- return pc.GetOrder().Uint16(data)
- }
-
- func (c config) GetPatternBytes() []byte {
- res := make([]byte, len(c.Pattern))
- for i, s := range c.Pattern {
- fmt.Sscanf(s, "0x%02x", &res[i])
- }
- return res
- }
-
- func main() {
- parserRegistry := parserRegistry{
- parserList: make([]beaconParser, 0),
- }
- seq := []byte{0x02, 0x01, 0x06, 0x64, 0x01, 0xF4, 0x00, 0x0A, 0xFF, 0x05}
-
- jsonFile, err := os.Open("configs.json")
- if err != nil {
- fmt.Println(err)
- }
-
- fmt.Println("succesfully opened json file")
-
- b, _ := io.ReadAll(jsonFile)
- var configs []config
- json.Unmarshal(b, &configs)
- for _, config := range configs {
- parserRegistry.Register(config.Name, config)
- }
-
- for _, parser := range parserRegistry.parserList {
- if parser.canParse(seq) {
- event, ok := parser.Parse(seq)
- if ok {
- fmt.Printf("Device: %s | Battery: %d%% | AccX: %d | AccY: %d | AccZ: %d\n", event.Type, event.Battery, event.AccX, event.AccY, event.AccZ)
- }
- }
- }
-
- fmt.Printf("configs: %+v\n", configs)
- jsonFile.Close()
- }
|