Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : * Copyright (c) 2019 Google LLC.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * Definitions for chip BLE service advertisement data.
22 : */
23 :
24 : #pragma once
25 :
26 : #ifndef _CHIP_BLE_BLE_H
27 : #error "Please include <ble/Ble.h> instead!"
28 : #endif
29 :
30 : #include <cstdint>
31 :
32 : #include <lib/core/CHIPEncoding.h>
33 :
34 : namespace chip {
35 : namespace Ble {
36 :
37 : /**
38 : * chip data block types that may appear with chip BLE service advertisement data.
39 : */
40 : enum chipBLEServiceDataType
41 : {
42 : kchipBLEServiceDataType_DeviceIdentificationInfo = 0x01,
43 : kchipBLEServiceDataType_TokenIdentificationInfo = 0x02,
44 : };
45 :
46 : /**
47 : * chip BLE Device Identification Information Block
48 : *
49 : * Defines the over-the-air encoded format of the device identification information block that appears
50 : * within chip BLE service advertisement data.
51 : */
52 : // TODO: Support Network Recovery service data block
53 : struct ChipBLEDeviceIdentificationInfo
54 : {
55 : constexpr static uint16_t kDiscriminatorMask = 0xfff;
56 : constexpr static uint8_t kAdditionalDataFlagMask = 0x1;
57 : constexpr static uint8_t kExtendedAnnouncementFlagMask = 0x2;
58 : constexpr static uint8_t kAdvertisementVersionMask = 0xf0;
59 : constexpr static uint8_t kAdvertisementVersionShiftBits = 4u;
60 :
61 : uint8_t OpCode;
62 : // DeviceDiscriminatorAndAdvVersion[0] contains the low 8 bits of the 12-bit discriminator.
63 : // DeviceDiscriminatorAndAdvVersion[1] contains the high 8 bits of the 12-bit discriminator in its low 4 bits and
64 : // the 4 bits of the advertisement version in its high 4 bits.
65 : uint8_t DeviceDiscriminatorAndAdvVersion[2];
66 : uint8_t DeviceVendorId[2];
67 : uint8_t DeviceProductId[2];
68 : uint8_t AdditionalDataFlag;
69 :
70 0 : void Init() { memset(this, 0, sizeof(*this)); }
71 :
72 : uint16_t GetVendorId() const { return chip::Encoding::LittleEndian::Get16(DeviceVendorId); }
73 :
74 0 : void SetVendorId(uint16_t vendorId) { chip::Encoding::LittleEndian::Put16(DeviceVendorId, vendorId); }
75 :
76 : uint16_t GetProductId() const { return chip::Encoding::LittleEndian::Get16(DeviceProductId); }
77 :
78 0 : void SetProductId(uint16_t productId) { chip::Encoding::LittleEndian::Put16(DeviceProductId, productId); }
79 :
80 : uint8_t GetAdvertisementVersion() const
81 : {
82 : uint8_t advertisementVersion = static_cast<uint8_t>((DeviceDiscriminatorAndAdvVersion[1] & kAdvertisementVersionMask) >>
83 : kAdvertisementVersionShiftBits);
84 : return advertisementVersion;
85 : }
86 :
87 : // Use only 4 bits to set advertisement version
88 0 : void SetAdvertisementVersion(uint8_t advertisementVersion)
89 : {
90 : // Advertisement Version is 4 bit long from 12th to 15th
91 0 : advertisementVersion =
92 0 : static_cast<uint8_t>((advertisementVersion << kAdvertisementVersionShiftBits) & kAdvertisementVersionMask);
93 0 : DeviceDiscriminatorAndAdvVersion[1] =
94 0 : static_cast<uint8_t>((DeviceDiscriminatorAndAdvVersion[1] & ~kAdvertisementVersionMask) | advertisementVersion);
95 0 : }
96 :
97 0 : uint16_t GetDeviceDiscriminator() const
98 : {
99 0 : return chip::Encoding::LittleEndian::Get16(DeviceDiscriminatorAndAdvVersion) & kDiscriminatorMask;
100 : }
101 :
102 0 : void SetDeviceDiscriminator(uint16_t deviceDiscriminator)
103 : {
104 : // Discriminator is 12-bit long, so don't overwrite bits 12th through 15th
105 0 : auto advVersion = static_cast<uint16_t>(DeviceDiscriminatorAndAdvVersion[1] << 8u & ~kDiscriminatorMask);
106 0 : deviceDiscriminator = static_cast<uint16_t>(advVersion | (deviceDiscriminator & kDiscriminatorMask));
107 0 : chip::Encoding::LittleEndian::Put16(DeviceDiscriminatorAndAdvVersion, deviceDiscriminator);
108 0 : }
109 :
110 : uint8_t GetAdditionalDataFlag() const { return (AdditionalDataFlag & kAdditionalDataFlagMask); }
111 :
112 : void SetAdditionalDataFlag(bool flag)
113 : {
114 : if (flag)
115 : {
116 : AdditionalDataFlag |= kAdditionalDataFlagMask;
117 : }
118 : else
119 : {
120 : AdditionalDataFlag &= static_cast<uint8_t>(~kAdditionalDataFlagMask);
121 : }
122 : }
123 :
124 : void SetExtendedAnnouncementFlag(bool flag)
125 : {
126 : if (flag)
127 : {
128 : AdditionalDataFlag |= kExtendedAnnouncementFlagMask;
129 : }
130 : else
131 : {
132 : AdditionalDataFlag &= static_cast<uint8_t>(~kExtendedAnnouncementFlagMask);
133 : }
134 : }
135 :
136 : } __attribute__((packed));
137 :
138 : /**
139 : * chip BLE Device Proximity Ranging Identification Information Block
140 : *
141 : * Defines the over-the-air encoded format of the proximity ranging identification
142 : * information block that appears within chip BLE service advertisement data.
143 : * Total size: 21 bytes.
144 : */
145 : struct ChipBLEProximityRangingIdentificationInfo
146 : {
147 : /**
148 : * OpCode for Proximity Ranging BLE advertisement.
149 : * Note: Shares value 0x02 with kchipBLEServiceDataType_TokenIdentificationInfo.
150 : * Proximity Ranging payloads are distinguished by their unique struct layout (21 bytes).
151 : */
152 : constexpr static uint8_t kOpCode = 0x02;
153 :
154 : constexpr static uint8_t kAdvertisementVersionMask = 0xf0;
155 : constexpr static uint8_t kAdvertisementVersionShiftBits = 4u;
156 :
157 : uint8_t OpCode; // Byte 0: 0x02 = Proximity Ranging
158 : uint8_t AdvVersionAndReserved; // Byte 1: Bits[7:4] = Adv version, Bits[3:0] = Reserved
159 : uint8_t MsgCounter[2]; // Bytes 2-3: 16-bit Message Counter (big-endian)
160 : uint8_t ObfuscatedBLEDeviceId[16]; // Bytes 4-19: HMAC-SHA256 obfuscated BLEDeviceId
161 : int8_t TxPower; // Byte 20: Tx Power
162 :
163 : void Init()
164 : {
165 : memset(this, 0, sizeof(*this));
166 : OpCode = kOpCode;
167 : }
168 :
169 : uint8_t GetAdvVersion() const
170 : {
171 : return static_cast<uint8_t>((AdvVersionAndReserved & kAdvertisementVersionMask) >> kAdvertisementVersionShiftBits);
172 : }
173 :
174 : void SetAdvVersion(uint8_t version)
175 : {
176 : AdvVersionAndReserved = static_cast<uint8_t>((AdvVersionAndReserved & ~kAdvertisementVersionMask) |
177 : ((version << kAdvertisementVersionShiftBits) & kAdvertisementVersionMask));
178 : }
179 :
180 : uint16_t GetMsgCounter() const { return chip::Encoding::BigEndian::Get16(MsgCounter); }
181 :
182 : void SetMsgCounter(uint16_t counter) { chip::Encoding::BigEndian::Put16(MsgCounter, counter); }
183 :
184 : int8_t GetTxPower() const { return TxPower; }
185 :
186 : void SetTxPower(int8_t txPower) { TxPower = txPower; }
187 :
188 : const uint8_t * GetObfuscatedBLEDeviceId() const { return ObfuscatedBLEDeviceId; }
189 :
190 : void SetObfuscatedBLEDeviceId(const uint8_t * id)
191 : {
192 : if (id == nullptr)
193 : {
194 : return;
195 : }
196 : memcpy(ObfuscatedBLEDeviceId, id, sizeof(ObfuscatedBLEDeviceId));
197 : }
198 :
199 : } __attribute__((packed));
200 :
201 : static_assert(sizeof(ChipBLEProximityRangingIdentificationInfo) == 21,
202 : "Proximity Ranging identification info must be exactly 21 bytes");
203 :
204 : } /* namespace Ble */
205 : } /* namespace chip */
|