|
- package utils
-
- import (
- "github.com/AFASystems/presence/internal/pkg/model"
- )
-
- // ParseADFast efficiently parses Advertising Data structures
- // Returns slice of [startIndex, endIndex] pairs for each AD structure
- func ParseADFast(b []byte) [][2]int {
- var res [][2]int
- i := 0
-
- for i < len(b) {
- l := int(b[i])
- if l == 0 || i+1+l > len(b) {
- break
- }
-
- res = append(res, [2]int{i, i + 1 + l})
-
- i += 1 + l
- }
-
- return res
- }
-
- // RemoveFlagBytes removes Bluetooth advertising flag bytes if present
- // Some beacons include flag bytes as the first AD structure
- func RemoveFlagBytes(b []byte) []byte {
- if len(b) > 1 && b[1] == 0x01 {
- l := int(b[0])
- if 1+l <= len(b) {
- return b[1+l:]
- }
- }
- return b
- }
-
- // Generate event based on the Beacon type
- func LoopADStructures(b []byte, i [][2]int, id string, parserRegistry *model.ParserRegistry) model.BeaconEvent {
- be := model.BeaconEvent{}
- for _, r := range i {
- ad := b[r[0]:r[1]]
- if !isValidADStructure(ad) {
- break
- }
- for name, parser := range parserRegistry.ParserList {
- if parser.CanParse(ad) {
- event, ok := parser.Parse(name, ad)
- if ok {
- event.ID = id
- event.Name = id
- return event
- }
- }
- }
- }
-
- return be
- }
-
- // IsValidADStructure validates if an AD structure is well-formed
- func isValidADStructure(data []byte) bool {
- if len(data) < 2 {
- return false
- }
-
- length := int(data[0])
- return length > 0 && int(length)+1 <= len(data)
- }
|