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

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

Issue 2031953003: Weave Packet Generator (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: include the header that actually enables platform dependent include of headers Created 4 years, 5 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_genera tor.h"
6
7 #ifdef OS_WIN
8 #include <winsock2.h>
9 #else
10 #include <netinet/in.h>
11 #endif
12
13 #include <string.h>
14
15 #include <algorithm>
16
17 #include "base/logging.h"
18
19 namespace {
20
21 typedef proximity_auth::BluetoothLowEnergyWeavePacketGenerator::Packet Packet;
22
23 const uint16_t kMinSupportedWeaveVersion = 1;
24 const uint16_t kMaxSupportedWeaveVersion = 1;
25 const uint16_t kServerWeaveVersion = 1;
26 const uint16_t kMinConnectionRequestSize = 7;
27 const uint16_t kMinConnectionResponseSize = 5;
28 const uint16_t kMinConnectionCloseSize = 3;
29 const uint32_t kDefaultMaxPacketSize = 20;
30 // Max packet size is 0, which means defer the decision to the server.
31 const uint16_t kMaxSupportedPacketSize = 0;
32 const uint8_t kMaxPacketCounter = 8;
33
34 } // namespace
35
36 namespace proximity_auth {
37
38 // static.
39 BluetoothLowEnergyWeavePacketGenerator::Factory*
40 BluetoothLowEnergyWeavePacketGenerator::Factory::factory_instance_ =
41 nullptr;
42
43 // static.
44 std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator>
45 BluetoothLowEnergyWeavePacketGenerator::Factory::NewInstance() {
46 if (factory_instance_ == nullptr) {
47 factory_instance_ = new Factory();
48 }
49 return factory_instance_->BuildInstance();
50 }
51
52 // static.
53 void BluetoothLowEnergyWeavePacketGenerator::Factory::SetInstanceForTesting(
54 Factory* factory) {
55 factory_instance_ = factory;
56 }
57
58 std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator>
59 BluetoothLowEnergyWeavePacketGenerator::Factory::BuildInstance() {
60 return std::unique_ptr<BluetoothLowEnergyWeavePacketGenerator>(
61 new BluetoothLowEnergyWeavePacketGenerator());
62 }
63
64 BluetoothLowEnergyWeavePacketGenerator::BluetoothLowEnergyWeavePacketGenerator()
65 : max_packet_size_(kDefaultMaxPacketSize), next_packet_counter_(0) {}
66
67 Packet BluetoothLowEnergyWeavePacketGenerator::CreateConnectionRequest() {
68 Packet packet(kMinConnectionRequestSize, 0);
69
70 SetPacketTypeBit(PacketType::CONTROL, &packet);
71 // Since it only make sense for connection request to be the 0th packet,
72 // resets the packet counter.
73 next_packet_counter_ = 1;
74 SetControlCommand(ControlCommand::CONNECTION_REQUEST, &packet);
75 SetShortField(1, kMinSupportedWeaveVersion, &packet);
76 SetShortField(3, kMaxSupportedWeaveVersion, &packet);
77 SetShortField(5, kMaxSupportedPacketSize, &packet);
78
79 return packet;
80 }
81
82 Packet BluetoothLowEnergyWeavePacketGenerator::CreateConnectionResponse() {
83 Packet packet(kMinConnectionResponseSize, 0);
84
85 SetPacketTypeBit(PacketType::CONTROL, &packet);
86 // Since it only make sense for connection response to be the 0th packet,
87 // resets the next packet counter.
88 next_packet_counter_ = 1;
89 SetControlCommand(ControlCommand::CONNECTION_RESPONSE, &packet);
90 SetShortField(1, kServerWeaveVersion, &packet);
91 SetShortField(3, max_packet_size_, &packet);
92
93 return packet;
94 }
95
96 Packet BluetoothLowEnergyWeavePacketGenerator::CreateConnectionClose(
97 ReasonForClose reason_for_close) {
98 Packet packet(kMinConnectionCloseSize, 0);
99
100 SetPacketTypeBit(PacketType::CONTROL, &packet);
101 SetPacketCounter(&packet);
102 SetControlCommand(ControlCommand::CONNECTION_CLOSE, &packet);
103 SetShortField(1, reason_for_close, &packet);
104
105 return packet;
106 }
107
108 void BluetoothLowEnergyWeavePacketGenerator::SetMaxPacketSize(uint32_t size) {
109 DCHECK(size >= kDefaultMaxPacketSize);
110 max_packet_size_ = size;
111 }
112
113 std::vector<Packet> BluetoothLowEnergyWeavePacketGenerator::EncodeDataMessage(
114 std::string message) {
115 DCHECK(!message.empty());
116
117 // The first byte of a packet is used by the uWeave protocol,
118 // hence the payload is 1 byte smaller than the packet size.
119 uint32_t packet_payload_size = max_packet_size_ - 1;
120
121 uint32_t message_length = message.length();
122 // (packet_payload_size - 1) is used to enforce rounding up.
123 uint32_t num_packets =
124 (message_length + (packet_payload_size - 1)) / packet_payload_size;
125
126 std::vector<Packet> weave_message(num_packets);
127
128 const char* byte_message = message.c_str();
129
130 for (uint32_t i = 0; i < num_packets; ++i) {
131 Packet* packet = &weave_message[i];
132 uint32_t begin = packet_payload_size * i;
133 uint32_t end = std::min(begin + packet_payload_size, message_length);
134
135 packet->push_back(0);
136
137 SetPacketTypeBit(PacketType::DATA, packet);
138 SetPacketCounter(packet);
139
140 for (uint32_t j = begin; j < end; ++j) {
141 packet->push_back(byte_message[j]);
142 }
143 }
144
145 // Guaranteed to have at least one packet since message is not empty.
146 SetDataFirstBit(&weave_message[0]);
147 SetDataLastBit(&weave_message[num_packets - 1]);
148
149 return weave_message;
150 }
151
152 void BluetoothLowEnergyWeavePacketGenerator::SetShortField(uint32_t byte_offset,
153 uint16_t val,
154 Packet* packet) {
155 DCHECK(packet);
156 DCHECK_LT(byte_offset, packet->size());
157 DCHECK_LT(byte_offset + 1, packet->size());
158
159 uint16_t network_val = htons(val);
160 uint8_t* network_val_ptr = reinterpret_cast<uint8_t*>(&network_val);
161
162 packet->at(byte_offset) = network_val_ptr[0];
163 packet->at(byte_offset + 1) = network_val_ptr[1];
164 }
165
166 void BluetoothLowEnergyWeavePacketGenerator::SetPacketTypeBit(PacketType type,
167 Packet* packet) {
168 DCHECK(packet);
169 DCHECK(!packet->empty());
170
171 // Type bit is the highest bit of the first byte of the packet.
172 // So clear the highest bit and set it according to val.
173 packet->at(0) = (packet->at(0) & 0x7F) | (type << 7);
174 }
175
176 void BluetoothLowEnergyWeavePacketGenerator::SetControlCommand(
177 ControlCommand command,
178 Packet* packet) {
179 DCHECK(packet);
180 DCHECK(!packet->empty());
181
182 // Control Command is the lower 4 bits of the packet's first byte.
183 // So clear the lower 4 bites and set it according to val.
184 packet->at(0) = (packet->at(0) & 0xF0) | command;
185 }
186
187 void BluetoothLowEnergyWeavePacketGenerator::SetPacketCounter(Packet* packet) {
188 DCHECK(packet);
189 DCHECK(!packet->empty());
190 uint8_t counter = next_packet_counter_ % kMaxPacketCounter;
191
192 // Packet counter is the bits 4, 5, and 6 of the packet's first byte.
193 // So clear those bits and set them according to current packet counter
194 // modular max packet counter.
195 packet->at(0) = (packet->at(0) & 0x8F) | (counter << 4);
196 next_packet_counter_++;
197 }
198
199 void BluetoothLowEnergyWeavePacketGenerator::SetDataFirstBit(Packet* packet) {
200 DCHECK(packet);
201 DCHECK(!packet->empty());
202
203 // First bit is bit 3 of the packet's first byte and set it to 1.
204 packet->at(0) = packet->at(0) | (1 << 3);
205 }
206
207 void BluetoothLowEnergyWeavePacketGenerator::SetDataLastBit(Packet* packet) {
208 DCHECK(packet);
209 DCHECK(!packet->empty());
210
211 // Last bit is the bit 2 of the packet's first byte and set it to 1.
212 packet->at(0) = packet->at(0) | (1 << 2);
213 }
214
215 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698