@@ -11,13 +11,16 @@ const (
11
11
AppleCompanyID = 0x004C
12
12
13
13
// Offline Finding type
14
- FindMyPayloadType = 0x12
14
+ PayloadType = 0x12
15
15
16
16
// Length of the payload
17
- FindMyPayloadLength = 0x19
17
+ PayloadLength = 0x19
18
18
19
19
// Hint byte
20
- FindMyHint = 0x00
20
+ Hint = 0x00
21
+
22
+ // Default Status byte
23
+ DefaultStatus = 0x10
21
24
)
22
25
23
26
var (
@@ -34,15 +37,15 @@ func ParseData(address bluetooth.Address, data []byte) (byte, []byte, error) {
34
37
return 0 , nil , ErrorDataTooShort
35
38
}
36
39
37
- if data [0 ] != FindMyPayloadType {
40
+ if data [0 ] != PayloadType {
38
41
return 0 , nil , ErrorInvalidPayloadType
39
42
}
40
43
41
- if data [1 ] != FindMyPayloadLength {
44
+ if data [1 ] != PayloadLength {
42
45
return 0 , nil , ErrorInvalidPayloadLength
43
46
}
44
47
45
- if data [26 ] != FindMyHint {
48
+ if data [26 ] != Hint {
46
49
return 0 , nil , ErrorInvalidHint
47
50
}
48
51
@@ -60,3 +63,19 @@ func ParseData(address bluetooth.Address, data []byte) (byte, []byte, error) {
60
63
61
64
return findMyStatus , key [:], nil
62
65
}
66
+
67
+ // NewData creates the ManufacturerDataElement for the advertising data used by FindMy devices.
68
+ // See https://adamcatley.com/AirTag.html#advertising-data
69
+ func NewData (keyData []byte ) bluetooth.ManufacturerDataElement {
70
+ data := make ([]byte , 0 , 27 )
71
+ data = append (data , PayloadType , PayloadLength )
72
+ data = append (data , DefaultStatus )
73
+ data = append (data , keyData [6 :]... ) // copy last 22 bytes of advertising key
74
+ data = append (data , (keyData [0 ] >> 6 )) // first two bits of advertising key
75
+ data = append (data , Hint )
76
+
77
+ return bluetooth.ManufacturerDataElement {
78
+ CompanyID : AppleCompanyID ,
79
+ Data : data ,
80
+ }
81
+ }
0 commit comments