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

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

Issue 2256003002: components/arc: implement multi advertising (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@plumb-incoming-connections
Patch Set: now using StructTraits/EnumTraits/UnionTraits/&c. Created 4 years, 3 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 void AddTo(device::BluetoothAdvertisement::Data* data) {}
35 };
36
37 struct ServiceUUIDEntry : public AdvertisementEntry {
38 std::vector<device::BluetoothUUID> service_uuids_;
Luis Héctor Chávez 2016/09/12 19:53:00 struct data members don't have trailing underscore
39
40 void AddTo(device::BluetoothAdvertisement::Data* data) override {
41 std::vector<std::string> string_uuids;
Luis Héctor Chávez 2016/09/12 19:53:00 Can you avoid one copy (in L45) by declaring |stri
42 for (const auto& uuid : service_uuids_) {
43 string_uuids.emplace_back(uuid.value());
44 }
45 data->set_service_uuids(
46 base::MakeUnique<std::vector<std::string>>(string_uuids));
47 }
48 };
49
50 struct ServiceDataEntry : public AdvertisementEntry {
51 uint16_t service_uuid_;
52 std::vector<uint8_t> service_data_;
53
54 void AddTo(device::BluetoothAdvertisement::Data* data) override {
55 std::string string_uuid = base::StringPrintf("%04x", service_uuid_);
56 data->set_service_data(
57 base::WrapUnique(new std::map<std::string, std::vector<uint8_t>>{
58 {string_uuid, service_data_}}));
59 }
60 };
61
62 struct ManufacturerDataEntry : public AdvertisementEntry {
63 uint16_t company_id_code_;
64 std::vector<uint8_t> blob_;
65
66 void AddTo(device::BluetoothAdvertisement::Data* data) override {
67 data->set_manufacturer_data(
68 base::WrapUnique(new std::map<uint16_t, std::vector<uint8_t>>{
69 {company_id_code_, blob_}}));
70 }
71 };
72
29 } // namespace 73 } // namespace
30 74
31 namespace mojo { 75 namespace mojo {
32 76
33 // static 77 // static
34 std::vector<uint8_t> 78 std::vector<uint8_t>
35 StructTraits<arc::mojom::BluetoothUUIDDataView, device::BluetoothUUID>::uuid( 79 StructTraits<arc::mojom::BluetoothUUIDDataView, device::BluetoothUUID>::uuid(
36 const device::BluetoothUUID& input) { 80 const device::BluetoothUUID& input) {
37 std::string uuid_str = StripNonHex(input.canonical_value()); 81 std::string uuid_str = StripNonHex(input.canonical_value());
38 82
(...skipping 21 matching lines...) Expand all
60 for (auto pos : uuid_dash_pos) 104 for (auto pos : uuid_dash_pos)
61 uuid_str = uuid_str.insert(pos, "-"); 105 uuid_str = uuid_str.insert(pos, "-");
62 106
63 device::BluetoothUUID result(uuid_str); 107 device::BluetoothUUID result(uuid_str);
64 108
65 DCHECK(result.IsValid()); 109 DCHECK(result.IsValid());
66 *output = result; 110 *output = result;
67 return true; 111 return true;
68 } 112 }
69 113
114 template <>
115 struct EnumTraits<arc::mojom::BluetoothAdvertisementType,
116 device::BluetoothAdvertisement::AdvertisementType> {
117 static bool FromMojom(
118 arc::mojom::BluetoothAdvertisementType mojom_type,
119 device::BluetoothAdvertisement::AdvertisementType* type) {
120 switch (mojom_type) {
121 case arc::mojom::BluetoothAdvertisementType::ADV_TYPE_CONNECTABLE:
122 case arc::mojom::BluetoothAdvertisementType::ADV_TYPE_SCANNABLE:
123 *type = device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_PERIPHERAL;
124 break;
125 case arc::mojom::BluetoothAdvertisementType::ADV_TYPE_NON_CONNECTABLE:
126 *type = device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST;
127 break;
128 default:
Luis Héctor Chávez 2016/09/12 19:53:00 since |mojom_type| is a strongly-typed enum and we
129 NOTREACHED() << "Invalid type: " << static_cast<uint32_t>(mojom_type);
130 return false;
131 }
132 return true;
133 }
134 };
135
136 template <>
137 struct StructTraits<arc::mojom::BluetoothServiceDataDataView,
138 ServiceDataEntry> {
139 static bool Read(arc::mojom::BluetoothServiceDataDataView data,
140 ServiceDataEntry* output) {
141 output->service_uuid_ = data.uuid_16bit();
142 data.ReadData(&output->service_data_);
143 return true;
144 }
145 };
146
147 template <>
148 struct UnionTraits<arc::mojom::BluetoothAdvertisingDataDataView,
149 std::unique_ptr<AdvertisementEntry>> {
150 static bool Read(arc::mojom::BluetoothAdvertisingDataDataView data,
151 std::unique_ptr<AdvertisementEntry>* output) {
152 switch (data.tag()) {
153 case arc::mojom::BluetoothAdvertisingDataDataView::Tag::SERVICE_UUIDS: {
154 std::unique_ptr<ServiceUUIDEntry> service_uuids =
155 base::MakeUnique<ServiceUUIDEntry>();
156 data.ReadServiceUuids(&service_uuids->service_uuids_);
157 *output = std::move(service_uuids);
158 break;
159 }
160 case arc::mojom::BluetoothAdvertisingDataDataView::Tag::SERVICE_DATA: {
161 std::unique_ptr<ServiceDataEntry> service_data =
162 base::MakeUnique<ServiceDataEntry>();
163 data.ReadServiceData(service_data.get());
164 *output = std::move(service_data);
165 break;
166 }
167 case arc::mojom::BluetoothAdvertisingDataDataView::Tag::
168 MANUFACTURER_DATA: {
169 std::unique_ptr<ManufacturerDataEntry> manufacturer_data =
170 base::MakeUnique<ManufacturerDataEntry>();
171 // We get manufacturer data as a big blob. The first two bytes
172 // should be a company identifier code and the rest is manufacturer-
173 // specific.
174 std::vector<uint8_t> blob;
175 data.ReadManufacturerData(&blob);
176 if (blob.size() < sizeof(uint16_t)) {
177 LOG(WARNING) << "Advertisement had malformed manufacturer data";
178 return false;
179 }
180
181 // The company identifier code is in little-endian.
182 uint16_t company_id_code = blob[1] << 8 | blob[0];
Luis Héctor Chávez 2016/09/12 19:53:00 I've seen this snippet lots of times. Can you plea
Eric Caruso 2016/09/13 23:36:48 Where else does this occur in the Chrome codebase
Luis Héctor Chávez 2016/09/16 00:39:53 You're right, I was probably remembering the Andro
183 blob.erase(blob.begin(), blob.begin() + sizeof(uint16_t));
184 manufacturer_data->company_id_code_ = company_id_code;
185 manufacturer_data->blob_ = blob;
Luis Héctor Chávez 2016/09/12 19:53:00 Can you avoid a copy by using std::swap?
Eric Caruso 2016/09/13 23:36:48 operator=(std::vector<uint8_t>&&) should also work
186 *output = std::move(manufacturer_data);
187 break;
188 }
189 default: {
190 LOG(WARNING) << "Bluetooth advertising data case not implemented";
191 // Default AdvertisementEntry does nothing when added to the
192 // device::BluetoothAdvertisement::AdvertisementData, so data we
193 // don't know how to handle yet will be dropped but won't cause a
194 // failure to deserialize.
195 *output = base::MakeUnique<AdvertisementEntry>();
196 break;
197 }
198 }
199 return true;
200 }
201 };
202
203 // static
204 bool StructTraits<arc::mojom::BluetoothAdvertisementDataView,
205 std::unique_ptr<device::BluetoothAdvertisement::Data>>::
206 Read(arc::mojom::BluetoothAdvertisementDataView advertisement,
207 std::unique_ptr<device::BluetoothAdvertisement::Data>* output) {
208 device::BluetoothAdvertisement::AdvertisementType adv_type;
209 if (!advertisement.ReadType(&adv_type))
210 return false;
211 auto data = base::MakeUnique<device::BluetoothAdvertisement::Data>(adv_type);
212
213 std::vector<std::unique_ptr<AdvertisementEntry>> adv_entries;
214 if (!advertisement.ReadData(&adv_entries))
215 return false;
216 for (const auto& adv_entry : adv_entries)
217 adv_entry->AddTo(data.get());
218
219 data->set_include_tx_power(advertisement.include_tx_power());
220
221 *output = std::move(data);
222 return true;
223 }
224
70 } // namespace mojo 225 } // 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