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

Side by Side Diff: components/arc/bluetooth/bluetooth_struct_traits.cc

Issue 2394683007: Reland "components/arc: implement multi advertising" (Closed)
Patch Set: Created 4 years, 2 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/arc/bluetooth/bluetooth_struct_traits.h" 5 #include "components/arc/bluetooth/bluetooth_struct_traits.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h"
12 #include "device/bluetooth/bluetooth_advertisement.h"
11 #include "device/bluetooth/bluetooth_uuid.h" 13 #include "device/bluetooth/bluetooth_uuid.h"
12 14
13 namespace { 15 namespace {
14 16
17 // BluetoothUUID helpers.
15 constexpr size_t kUUIDSize = 16; 18 constexpr size_t kUUIDSize = 16;
16 19
17 bool IsNonHex(char c) { 20 bool IsNonHex(char c) {
18 return !isxdigit(c); 21 return !isxdigit(c);
19 } 22 }
20 23
21 std::string StripNonHex(const std::string& str) { 24 std::string StripNonHex(const std::string& str) {
22 std::string result = str; 25 std::string result = str;
23 result.erase(std::remove_if(result.begin(), result.end(), IsNonHex), 26 result.erase(std::remove_if(result.begin(), result.end(), IsNonHex),
24 result.end()); 27 result.end());
25 28
26 return result; 29 return result;
27 } 30 }
28 31
32 // BluetoothAdvertisement helpers.
33 struct AdvertisementEntry {
34 virtual ~AdvertisementEntry() {}
Eric Caruso 2016/10/06 19:00:50 This line and the other virtual destructors are th
Luis Héctor Chávez 2016/10/06 19:23:53 The next time you reland something, can you please
35 virtual void AddTo(device::BluetoothAdvertisement::Data* data) {}
36 };
37
38 struct ServiceUUIDEntry : public AdvertisementEntry {
39 std::vector<device::BluetoothUUID> service_uuids;
40
41 ~ServiceUUIDEntry() override {}
42
43 void AddTo(device::BluetoothAdvertisement::Data* data) override {
44 auto string_uuids = base::MakeUnique<std::vector<std::string>>();
45 for (const auto& uuid : service_uuids) {
46 string_uuids->emplace_back(uuid.value());
47 }
48 data->set_service_uuids(std::move(string_uuids));
49 }
50 };
51
52 struct ServiceDataEntry : public AdvertisementEntry {
53 uint16_t service_uuid;
54 std::vector<uint8_t> service_data;
55
56 ~ServiceDataEntry() override {}
57
58 void AddTo(device::BluetoothAdvertisement::Data* data) override {
59 std::string string_uuid = base::StringPrintf("%04x", service_uuid);
60 data->set_service_data(
61 base::WrapUnique(new std::map<std::string, std::vector<uint8_t>>{
62 {string_uuid, service_data}}));
63 }
64 };
65
66 struct ManufacturerDataEntry : public AdvertisementEntry {
67 uint16_t company_id_code;
68 std::vector<uint8_t> blob;
69
70 ~ManufacturerDataEntry() override {}
71
72 void AddTo(device::BluetoothAdvertisement::Data* data) override {
73 data->set_manufacturer_data(base::WrapUnique(
74 new std::map<uint16_t, std::vector<uint8_t>>{{company_id_code, blob}}));
75 }
76 };
77
78 uint16_t ExtractCompanyIdentifierCode(std::vector<uint8_t>* blob) {
79 // The company identifier code is in little-endian.
80 uint16_t company_id_code = (*blob)[1] << 8 | (*blob)[0];
81 blob->erase(blob->begin(), blob->begin() + sizeof(uint16_t));
82 return company_id_code;
83 }
84
29 } // namespace 85 } // namespace
30 86
31 namespace mojo { 87 namespace mojo {
32 88
33 // static 89 // static
34 std::vector<uint8_t> 90 std::vector<uint8_t>
35 StructTraits<arc::mojom::BluetoothUUIDDataView, device::BluetoothUUID>::uuid( 91 StructTraits<arc::mojom::BluetoothUUIDDataView, device::BluetoothUUID>::uuid(
36 const device::BluetoothUUID& input) { 92 const device::BluetoothUUID& input) {
37 // TODO(dcheng): Figure out what to do here, this is called twice on 93 // TODO(dcheng): Figure out what to do here, this is called twice on
38 // serialization. Building a vector is a little inefficient. 94 // serialization. Building a vector is a little inefficient.
(...skipping 24 matching lines...) Expand all
63 for (auto pos : kUuidDashPos) 119 for (auto pos : kUuidDashPos)
64 uuid_str = uuid_str.insert(pos, "-"); 120 uuid_str = uuid_str.insert(pos, "-");
65 121
66 device::BluetoothUUID result(uuid_str); 122 device::BluetoothUUID result(uuid_str);
67 123
68 DCHECK(result.IsValid()); 124 DCHECK(result.IsValid());
69 *output = result; 125 *output = result;
70 return true; 126 return true;
71 } 127 }
72 128
129 template <>
130 struct EnumTraits<arc::mojom::BluetoothAdvertisementType,
131 device::BluetoothAdvertisement::AdvertisementType> {
132 static bool FromMojom(
133 arc::mojom::BluetoothAdvertisementType mojom_type,
134 device::BluetoothAdvertisement::AdvertisementType* type) {
135 switch (mojom_type) {
136 case arc::mojom::BluetoothAdvertisementType::ADV_TYPE_CONNECTABLE:
137 case arc::mojom::BluetoothAdvertisementType::ADV_TYPE_SCANNABLE:
138 *type = device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_PERIPHERAL;
139 return true;
140 case arc::mojom::BluetoothAdvertisementType::ADV_TYPE_NON_CONNECTABLE:
141 *type = device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST;
142 return true;
143 }
144 NOTREACHED() << "Invalid type: " << static_cast<uint32_t>(mojom_type);
145 return false;
146 }
147 };
148
149 template <>
150 struct StructTraits<arc::mojom::BluetoothServiceDataDataView,
151 ServiceDataEntry> {
152 static bool Read(arc::mojom::BluetoothServiceDataDataView data,
153 ServiceDataEntry* output) {
154 output->service_uuid = data.uuid_16bit();
155 return data.ReadData(&output->service_data);
156 }
157 };
158
159 template <>
160 struct UnionTraits<arc::mojom::BluetoothAdvertisingDataDataView,
161 std::unique_ptr<AdvertisementEntry>> {
162 static bool Read(arc::mojom::BluetoothAdvertisingDataDataView data,
163 std::unique_ptr<AdvertisementEntry>* output) {
164 switch (data.tag()) {
165 case arc::mojom::BluetoothAdvertisingDataDataView::Tag::SERVICE_UUIDS: {
166 std::unique_ptr<ServiceUUIDEntry> service_uuids =
167 base::MakeUnique<ServiceUUIDEntry>();
168 if (!data.ReadServiceUuids(&service_uuids->service_uuids))
169 return false;
170 *output = std::move(service_uuids);
171 break;
172 }
173 case arc::mojom::BluetoothAdvertisingDataDataView::Tag::SERVICE_DATA: {
174 std::unique_ptr<ServiceDataEntry> service_data =
175 base::MakeUnique<ServiceDataEntry>();
176 if (!data.ReadServiceData(service_data.get()))
177 return false;
178 *output = std::move(service_data);
179 break;
180 }
181 case arc::mojom::BluetoothAdvertisingDataDataView::Tag::
182 MANUFACTURER_DATA: {
183 std::unique_ptr<ManufacturerDataEntry> manufacturer_data =
184 base::MakeUnique<ManufacturerDataEntry>();
185 // We get manufacturer data as a big blob. The first two bytes
186 // should be a company identifier code and the rest is manufacturer-
187 // specific.
188 std::vector<uint8_t> blob;
189 if (!data.ReadManufacturerData(&blob))
190 return false;
191 if (blob.size() < sizeof(uint16_t)) {
192 LOG(WARNING) << "Advertisement had malformed manufacturer data";
193 return false;
194 }
195
196 manufacturer_data->company_id_code =
197 ExtractCompanyIdentifierCode(&blob);
198 manufacturer_data->blob = std::move(blob);
199 *output = std::move(manufacturer_data);
200 break;
201 }
202 default: {
203 LOG(WARNING) << "Bluetooth advertising data case not implemented";
204 // Default AdvertisementEntry does nothing when added to the
205 // device::BluetoothAdvertisement::AdvertisementData, so data we
206 // don't know how to handle yet will be dropped but won't cause a
207 // failure to deserialize.
208 *output = base::MakeUnique<AdvertisementEntry>();
209 break;
210 }
211 }
212 return true;
213 }
214 };
215
216 // static
217 bool StructTraits<arc::mojom::BluetoothAdvertisementDataView,
218 std::unique_ptr<device::BluetoothAdvertisement::Data>>::
219 Read(arc::mojom::BluetoothAdvertisementDataView advertisement,
220 std::unique_ptr<device::BluetoothAdvertisement::Data>* output) {
221 device::BluetoothAdvertisement::AdvertisementType adv_type;
222 if (!advertisement.ReadType(&adv_type))
223 return false;
224 auto data = base::MakeUnique<device::BluetoothAdvertisement::Data>(adv_type);
225
226 std::vector<std::unique_ptr<AdvertisementEntry>> adv_entries;
227 if (!advertisement.ReadData(&adv_entries))
228 return false;
229 for (const auto& adv_entry : adv_entries)
230 adv_entry->AddTo(data.get());
231
232 data->set_include_tx_power(advertisement.include_tx_power());
233
234 *output = std::move(data);
235 return true;
236 }
237
73 } // namespace mojo 238 } // namespace mojo
OLDNEW
« no previous file with comments | « components/arc/bluetooth/bluetooth_struct_traits.h ('k') | components/arc/bluetooth/bluetooth_struct_traits_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698