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

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

Powered by Google App Engine
This is Rietveld 408576698