Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: components/proximity_auth/ble/bluetooth_low_energy_weave_packet_receiver.cc

Issue 2053013002: Weave Packet Receiver (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@proximity_auth_weave_migration
Patch Set: fixed typo in comment Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/proximity_auth/ble/bluetooth_low_energy_weave_packet_receiv er.h"
6
7 #include "base/logging.h"
8
9 using proximity_auth::BluetoothLowEnergyWeavePacketGenerator;
10
11 namespace proximity_auth {
12 namespace {
Kyle Horimoto 2016/06/09 23:59:46 The anonymous namespace should be above the proxim
jingxuy 2016/06/10 23:11:12 Done.
13 typedef BluetoothLowEnergyWeavePacketGenerator::PacketType PacketType;
14 typedef BluetoothLowEnergyWeavePacketGenerator::ControlCommand ControlCommand;
15 typedef BluetoothLowEnergyWeavePacketGenerator::ReasonForClose ReasonForClose;
16
17 const uint8_t kMaxPacketCounter = 8;
18 } // namespace
19
20 BluetoothLowEnergyWeavePacketReceiver::Factory*
21 BluetoothLowEnergyWeavePacketReceiver::Factory::factory_instance_ = nullptr;
22
23 std::unique_ptr<BluetoothLowEnergyWeavePacketReceiver>
24 BluetoothLowEnergyWeavePacketReceiver::Factory::NewInstance() {
25 if (factory_instance_ == nullptr) {
26 factory_instance_ = new Factory();
27 }
28 return std::unique_ptr<BluetoothLowEnergyWeavePacketReceiver>(
29 factory_instance_->BuildInstance());
30 }
31
32 void BluetoothLowEnergyWeavePacketReceiver::Factory::SetInstanceForTesting(
33 Factory* factory) {
34 factory_instance_ = factory;
35 }
36
37 BluetoothLowEnergyWeavePacketReceiver*
38 BluetoothLowEnergyWeavePacketReceiver::Factory::BuildInstance() {
39 return new BluetoothLowEnergyWeavePacketReceiver();
40 }
41
42 BluetoothLowEnergyWeavePacketReceiver::BluetoothLowEnergyWeavePacketReceiver()
43 : packet_size_(0),
44 packet_number_(0),
45 state_(State::EXCHANGING_CONTROLS),
46 reason_for_close_(ReasonForClose::CLOSE_WITHOUT_ERROR) {}
47
48 BluetoothLowEnergyWeavePacketReceiver::
49 ~BluetoothLowEnergyWeavePacketReceiver() {}
50
51 void BluetoothLowEnergyWeavePacketReceiver::ResetReceiver() {
52 packet_size_ = 0;
53 packet_number_ = 0;
54 state_ = State::EXCHANGING_CONTROLS;
55 reason_for_close_ = ReasonForClose::CLOSE_WITHOUT_ERROR;
56 }
57
58 BluetoothLowEnergyWeavePacketReceiver::State
59 BluetoothLowEnergyWeavePacketReceiver::GetState() {
60 return state_;
61 }
62
63 uint32_t BluetoothLowEnergyWeavePacketReceiver::GetPacketSize() {
64 // packet_size_ is well defined in every state.
65 return packet_size_;
66 }
67
68 ReasonForClose BluetoothLowEnergyWeavePacketReceiver::GetReasonForClose() {
69 DCHECK(state_ == State::CONNECTION_CLOSED);
70 return reason_for_close_;
71 }
72
73 std::string BluetoothLowEnergyWeavePacketReceiver::GetDataMessage() {
74 DCHECK(state_ == State::DATA_READY);
75 return std::string(data_message_.begin(), data_message_.end());
76 }
77
78 BluetoothLowEnergyWeavePacketReceiver::State
79 BluetoothLowEnergyWeavePacketReceiver::ReceivePacket(const Packet& packet) {
Kyle Horimoto 2016/06/09 23:59:46 General comment: You don't preserve messages if th
jingxuy 2016/06/10 23:11:12 Acknowledged.
80 VerifyPacketCounter(packet);
81
82 switch (state_) {
83 case State::EXCHANGING_CONTROLS:
84 ReceiveWithEmptyData(packet);
85 break;
86 case State::RECEIVING_DATA:
87 ReceiveWithPartialData(packet);
88 break;
89 case State::DATA_READY:
90 data_message_.clear();
91 ReceiveWithEmptyData(packet);
92 break;
93 default:
94 // Receiving an message in connection close or error state is not valid
95 state_ = State::ERROR;
96 break;
97 }
98 return state_;
99 }
100
101 void BluetoothLowEnergyWeavePacketReceiver::ReceiveWithEmptyData(
102 const Packet& packet) {
103 // TODO(jingxuy): add dcheck stuff
104 PacketType type = GetPacketType(packet);
105 switch (type) {
106 case PacketType::CONTROL:
107 switch (GetControlCommand(packet)) {
108 case ControlCommand::CONNECTION_REQUEST:
109 ReceiveConnectionRequest(packet);
110 break;
111 case ControlCommand::CONNECTION_RESPONSE:
112 ReceiveConnectionResponse(packet);
113 break;
114 case ControlCommand::CONNECTION_CLOSE:
115 ReceiveConnectionClose(packet);
116 break;
117 default:
118 state_ = State::ERROR;
119 break;
120 }
121 break;
122 case PacketType::DATA:
123 if (!IsFirstDataPacket(packet)) {
124 state_ = State::ERROR;
125 } else {
126 AppendData(packet);
Kyle Horimoto 2016/06/09 23:59:46 You also need to check that it has data at all (pa
jingxuy 2016/06/10 23:11:12 Acknowledged.
127 }
128 break;
129 default:
130 state_ = State::ERROR;
131 break;
132 }
133 }
134
135 void BluetoothLowEnergyWeavePacketReceiver::ReceiveWithPartialData(
136 const Packet& packet) {
137 // TODO(jingxuy): add dcheck stuff
138 PacketType type = GetPacketType(packet);
139 switch (type) {
140 case PacketType::CONTROL:
Kyle Horimoto 2016/06/09 23:59:46 If we're receiving partial data, we shouldn't even
jingxuy 2016/06/10 23:11:12 Pending response from Gustavo
141 if (GetControlCommand(packet) == ControlCommand::CONNECTION_CLOSE) {
142 ReceiveConnectionClose(packet);
143 } else {
144 // Shouldn't be receiving request/response in the middle of a data
Kyle Horimoto 2016/06/09 23:59:46 DLOG something here and everywhere else where ther
145 // transaction.
146 state_ = State::ERROR;
147 }
148 break;
149 case PacketType::DATA:
150 if (IsFirstDataPacket(packet)) {
151 state_ = State::ERROR;
152 } else {
153 AppendData(packet);
154 if (IsLastDataPacket(packet)) {
155 state_ = State::DATA_READY;
156 }
157 }
158 break;
159 default:
160 state_ = State::ERROR;
161 break;
162 }
163 }
164
165 void BluetoothLowEnergyWeavePacketReceiver::ReceiveConnectionRequest(
166 const Packet& packet) {
167 // TODO(jingxuy): add dcheck stuff
168 uint16_t min_version = GetShortField(packet, 1);
169 uint16_t max_version = GetShortField(packet, 3);
170 if (!(min_version == 1 && max_version == 1)) {
171 state_ = State::ERROR;
172 } else {
173 packet_size_ = GetShortField(packet, 5);
174 // TODO(jingxuy): what do I do with the 13 bytes of data?
Kyle Horimoto 2016/06/09 23:59:45 You should AppendData() and set state to DATA_READ
jingxuy 2016/06/10 23:11:12 Pending response from Gustavo
175 }
176 }
177
178 void BluetoothLowEnergyWeavePacketReceiver::ReceiveConnectionResponse(
179 const Packet& packet) {
180 // TODO(jingxuy): add dcheck stuff
181 uint16_t selected_version = GetShortField(packet, 1);
182 if (selected_version != 1) {
183 state_ = State::ERROR;
184 } else {
185 packet_size_ = GetShortField(packet, 3);
186 // TODO(jingxuy): what do I do with the 15 bytes of data?
187 }
188 }
189
190 void BluetoothLowEnergyWeavePacketReceiver::ReceiveConnectionClose(
191 const Packet& packet) {
192 // TODO(jingxuy): add dcheck stuff
193 reason_for_close_ = static_cast<ReasonForClose>(GetShortField(packet, 1));
Kyle Horimoto 2016/06/09 23:59:46 What happens if the value passed isn't a ReasonFor
jingxuy 2016/06/10 23:11:12 Done.
194 state_ = State::CONNECTION_CLOSED;
195 }
196
197 void BluetoothLowEnergyWeavePacketReceiver::AppendData(const Packet& packet) {
198 // TODO(jingxuy): add dcheck stuff
199 // Append to data_message_ bytes 1 through end of the packet.
200 data_message_.insert(data_message_.end(), packet.begin() + 1, packet.end());
201 }
202
203 uint16_t BluetoothLowEnergyWeavePacketReceiver::GetShortField(
204 const Packet& packet,
205 uint32_t index) {
206 DCHECK_LT(index, packet.size());
207 DCHECK_LT(index + 1, packet.size());
208
209 // packet[index + 1] is the upper byte and packet[index] is the lower byte.
210 return (packet[index + 1] << 8) | packet[index];
211 }
212
213 PacketType BluetoothLowEnergyWeavePacketReceiver::GetPacketType(
214 const Packet& packet) {
215 // Packet type is stored in the highest bit of the first byte.
216 return static_cast<PacketType>((packet[0] >> 7) & 1);
217 }
218
219 ControlCommand BluetoothLowEnergyWeavePacketReceiver::GetControlCommand(
220 const Packet& packet) {
221 // Control command is stored in the lower 4 bits of the first byte.
222 return static_cast<ControlCommand>((packet[0] & 0x0F));
223 }
224
225 void BluetoothLowEnergyWeavePacketReceiver::VerifyPacketCounter(
226 const Packet& packet) {
227 if (state_ == State::ERROR)
228 return;
229
230 // Packet counter is bits 4, 5, and 6 of the first byte.
231 uint8_t count = (packet[0] >> 4) & 7;
232
233 if (count == (packet_number_ % kMaxPacketCounter)) {
234 packet_number_++;
235 } else {
236 state_ = State::ERROR;
237 }
238 }
239
240 bool BluetoothLowEnergyWeavePacketReceiver::IsFirstDataPacket(
241 const Packet& packet) {
242 // Bit 3 determines whether the packet is the first packet of the message.
243 return (packet[0] >> 3) & 1;
244 }
245
246 bool BluetoothLowEnergyWeavePacketReceiver::IsLastDataPacket(
247 const Packet& packet) {
248 // Bit 2 determines whether the packet is the last packet of the message.
249 return (packet[0] >> 2) & 1;
250 }
251
252 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698