Index: components/arc/bluetooth/bluetooth_type_converters.cc |
diff --git a/components/arc/bluetooth/bluetooth_type_converters.cc b/components/arc/bluetooth/bluetooth_type_converters.cc |
index f91139d0434d9b248e64f0b3e9456cfd2ea3c44a..4712a8977ac0db4a189bad2a4a8db592baf1a4f8 100644 |
--- a/components/arc/bluetooth/bluetooth_type_converters.cc |
+++ b/components/arc/bluetooth/bluetooth_type_converters.cc |
@@ -6,6 +6,9 @@ |
#include <cctype> |
#include <iomanip> |
#include <ios> |
+#include <map> |
+#include <memory> |
+#include <set> |
#include <sstream> |
#include <string> |
#include <vector> |
@@ -23,6 +26,13 @@ constexpr size_t kAddressSize = 6; |
constexpr size_t kUUIDSize = 16; |
constexpr char kInvalidAddress[] = "00:00:00:00:00:00"; |
+// SDP Service attribute IDs. |
+constexpr uint16_t kServiceClassIDList = 0x0001; |
+constexpr uint16_t kProtocolDescriptorList = 0x0004; |
+constexpr uint16_t kBrowseGroupList = 0x0005; |
+constexpr uint16_t kBluetoothProfileDescriptorList = 0x0009; |
+constexpr uint16_t kServiceName = 0x0100; |
+ |
bool IsNonHex(char c) { |
return !isxdigit(c); |
} |
@@ -150,4 +160,277 @@ TypeConverter<arc::mojom::BluetoothGattStatus, |
return ret; |
} |
+// static |
+arc::mojom::BluetoothSdpServiceAttrPtr |
+TypeConverter<arc::mojom::BluetoothSdpServiceAttrPtr, |
+ bluez::BluetoothServiceAttributeValueBlueZ>:: |
+ Convert(const bluez::BluetoothServiceAttributeValueBlueZ& attr_bluez) { |
+ arc::mojom::BluetoothSdpServiceAttrPtr result = |
+ arc::mojom::BluetoothSdpServiceAttr::New(); |
+ result->type = |
+ static_cast<arc::mojom::BluetoothSdpAttrType>(attr_bluez.type()); |
+ |
+ switch (attr_bluez.type()) { |
+ case bluez::BluetoothServiceAttributeValueBlueZ::Type::NULLTYPE: |
+ break; |
+ case bluez::BluetoothServiceAttributeValueBlueZ::Type::UINT: |
+ // Fall through |
+ case bluez::BluetoothServiceAttributeValueBlueZ::Type::INT: { |
+ int32_t n; |
+ uint8_t* val; |
+ std::vector<uint8_t> data; |
+ if (!attr_bluez.value().GetAsInteger(&n)) break; |
+ switch (attr_bluez.size()) { |
+ case 1: { |
+ uint8_t v8 = static_cast<uint8_t>(n); |
+ val = reinterpret_cast<uint8_t*>(&v8); |
+ data.insert(data.begin(), val, val + attr_bluez.size()); |
+ break; |
+ } |
+ case 2: { |
+ uint16_t v16 = static_cast<uint16_t>(n); |
+ val = reinterpret_cast<uint8_t*>(&v16); |
+ data.insert(data.begin(), val, val + attr_bluez.size()); |
+ break; |
+ } |
+ case 4: { |
+ uint32_t v32 = static_cast<uint32_t>(n); |
+ val = reinterpret_cast<uint8_t*>(&v32); |
+ data.insert(data.begin(), val, val + attr_bluez.size()); |
+ break; |
+ } |
+ default: |
+ break; |
+ } |
+ result->value.Swap(&data); |
+ result->type_size = attr_bluez.size(); |
+ break; |
+ } |
+ case bluez::BluetoothServiceAttributeValueBlueZ::Type::UUID: |
+ // Fall through |
+ case bluez::BluetoothServiceAttributeValueBlueZ::Type::STRING: |
+ // Fall through |
+ case bluez::BluetoothServiceAttributeValueBlueZ::Type::URL: { |
+ std::string str; |
+ if (!attr_bluez.value().GetAsString(&str)) break; |
+ std::copy(str.begin(), str.end(), result->value.begin()); |
+ break; |
+ } |
+ case bluez::BluetoothServiceAttributeValueBlueZ::Type::BOOL: { |
+ bool b; |
+ if (!attr_bluez.value().GetAsBoolean(&b)) break; |
+ uint8_t v = b ? 1 : 0; |
+ result->value.push_back(v); |
+ result->type_size = result->value.size(); |
+ break; |
+ } |
+ case bluez::BluetoothServiceAttributeValueBlueZ::Type::SEQUENCE: |
+ for (unsigned int i = 0; i < attr_bluez.sequence().size(); i++) { |
+ result->sequence.push_back( |
+ ConvertTo<arc::mojom::BluetoothSdpServiceAttrPtr>( |
+ attr_bluez.sequence().at(i))); |
+ } |
+ result->type_size = result->sequence.size(); |
+ break; |
+ default: |
+ break; |
+ } |
+ |
+ return result; |
+} |
+ |
+// static |
+bluez::BluetoothServiceAttributeValueBlueZ |
+TypeConverter<bluez::BluetoothServiceAttributeValueBlueZ, |
+ arc::mojom::BluetoothSdpServiceAttrPtr>:: |
+ Convert(const arc::mojom::BluetoothSdpServiceAttrPtr& attr) { |
+ uint32_t size = attr->type_size; |
+ bluez::BluetoothServiceAttributeValueBlueZ::Type type = |
+ static_cast<bluez::BluetoothServiceAttributeValueBlueZ::Type>(attr->type); |
+ std::unique_ptr<base::Value> value; |
+ |
+ switch (attr->type) { |
+ case arc::mojom::BluetoothSdpAttrType::NULLTYPE: |
+ break; |
+ case arc::mojom::BluetoothSdpAttrType::UINT: |
+ // Fall through |
+ case arc::mojom::BluetoothSdpAttrType::INT: { |
+ if (size != attr->value.size()) break; |
+ |
+ void* v = attr->value.To<std::vector<uint8_t>>().data(); |
+ if (!v) break; |
+ |
+ switch (attr->type_size) { |
+ case 1: { |
+ uint8_t* v8 = static_cast<uint8_t*>(v); |
+ value = base::MakeUnique<base::FundamentalValue>( |
+ static_cast<int32_t>(*v8)); |
+ break; |
+ } |
+ case 2: { |
+ uint16_t* v16 = static_cast<uint16_t*>(v); |
+ value = base::MakeUnique<base::FundamentalValue>( |
+ static_cast<int32_t>(*v16)); |
+ break; |
+ } |
+ case 4: { |
+ uint32_t* v32 = static_cast<uint32_t*>(v); |
+ value = base::MakeUnique<base::FundamentalValue>( |
+ static_cast<int32_t>(*v32)); |
+ break; |
+ } |
+ default: |
+ value = base::Value::CreateNullValue(); |
+ break; |
+ } |
+ |
+ return bluez::BluetoothServiceAttributeValueBlueZ(type, size, |
+ std::move(value)); |
+ } |
+ case arc::mojom::BluetoothSdpAttrType::BOOL: |
+ if (size != attr->value.size() || attr->value.size() != 1) break; |
+ |
+ if (attr->value[0]) |
+ value = base::MakeUnique<base::FundamentalValue>(true); |
+ else |
+ value = base::MakeUnique<base::FundamentalValue>(false); |
+ |
+ return bluez::BluetoothServiceAttributeValueBlueZ(type, size, |
+ std::move(value)); |
+ case arc::mojom::BluetoothSdpAttrType::SEQUENCE: { |
+ std::unique_ptr<std::vector<bluez::BluetoothServiceAttributeValueBlueZ>> |
+ seq = base::MakeUnique< |
+ std::vector<bluez::BluetoothServiceAttributeValueBlueZ>>(); |
+ |
+ for (unsigned int i = 0; i < attr->sequence.size(); i++) { |
+ bluez::BluetoothServiceAttributeValueBlueZ attr_bluez = |
+ mojo::ConvertTo<bluez::BluetoothServiceAttributeValueBlueZ>( |
rickyz (no longer on Chrome)
2016/08/16 23:55:07
Can this lead to stack overflow via too much recur
Miao
2016/08/17 14:30:20
There will be at most two layer of sequences, so i
rickyz (no longer on Chrome)
2016/08/17 18:54:54
Sorry, I didn't give the full background here - fr
puthik_chromium
2016/08/19 21:21:56
I propose the we should change the mojo to somethi
|
+ attr->sequence[i]); |
+ if (attr_bluez.type() != |
+ bluez::BluetoothServiceAttributeValueBlueZ::Type::NULLTYPE) |
+ seq->push_back(attr_bluez); |
+ } |
+ return bluez::BluetoothServiceAttributeValueBlueZ(std::move(seq)); |
+ } |
+ case arc::mojom::BluetoothSdpAttrType::UUID: |
+ // Fall through |
+ case arc::mojom::BluetoothSdpAttrType::STRING: |
+ // Fall through |
+ case arc::mojom::BluetoothSdpAttrType::URL: { |
+ std::string str; |
+ if (size != attr->value.size()) break; |
+ |
+ std::copy(attr->value.begin(), attr->value.begin(), str.begin()); |
+ value = base::MakeUnique<base::StringValue>(str); |
+ return bluez::BluetoothServiceAttributeValueBlueZ(type, size, |
+ std::move(value)); |
+ break; |
+ } |
+ default: |
+ break; |
+ } |
+ return bluez::BluetoothServiceAttributeValueBlueZ( |
+ type, 0, base::Value::CreateNullValue()); |
+} |
+ |
+// static |
+arc::mojom::BluetoothSdpRecordPtr |
+TypeConverter<arc::mojom::BluetoothSdpRecordPtr, |
+ bluez::BluetoothServiceRecordBlueZ>:: |
+ Convert(const bluez::BluetoothServiceRecordBlueZ& rcd_bluez) { |
+ arc::mojom::BluetoothSdpRecordPtr result = |
+ arc::mojom::BluetoothSdpRecord::New(); |
+ |
+ std::vector<uint16_t> v = rcd_bluez.GetAttributeIds(); |
+ std::set<uint16_t> ids(v.begin(), v.end()); |
rickyz (no longer on Chrome)
2016/08/16 23:55:07
Not used.
Miao
2016/08/17 14:30:19
Removed.
|
+ |
+ for (auto it : v) { |
+ switch (it) { |
+ case kServiceClassIDList: |
+ result->attrs[kServiceClassIDList] = |
+ arc::mojom::BluetoothSdpServiceAttr::From( |
+ rcd_bluez.GetAttributeValue(kServiceClassIDList)); |
+ break; |
+ case kProtocolDescriptorList: |
+ result->attrs[kProtocolDescriptorList] = |
+ arc::mojom::BluetoothSdpServiceAttr::From( |
+ rcd_bluez.GetAttributeValue(kProtocolDescriptorList)); |
+ break; |
+ case kBrowseGroupList: |
+ result->attrs[kBrowseGroupList] = |
+ arc::mojom::BluetoothSdpServiceAttr::From( |
+ rcd_bluez.GetAttributeValue(kBrowseGroupList)); |
+ break; |
+ case kBluetoothProfileDescriptorList: |
+ result->attrs[kBluetoothProfileDescriptorList] = |
+ arc::mojom::BluetoothSdpServiceAttr::From( |
+ rcd_bluez.GetAttributeValue(kBluetoothProfileDescriptorList)); |
+ break; |
+ case kServiceName: |
+ result->attrs[kServiceName] = arc::mojom::BluetoothSdpServiceAttr::From( |
+ rcd_bluez.GetAttributeValue(kServiceName)); |
+ break; |
+ default: |
+ break; |
+ } |
+ } |
+ |
+ return result; |
+} |
+ |
+// static |
+bluez::BluetoothServiceRecordBlueZ |
+TypeConverter<bluez::BluetoothServiceRecordBlueZ, |
+ arc::mojom::BluetoothSdpRecordPtr>:: |
+ Convert(const arc::mojom::BluetoothSdpRecordPtr& rcd) { |
+ bluez::BluetoothServiceRecordBlueZ rcd_bluez; |
+ std::unique_ptr<bluez::BluetoothServiceAttributeValueBlueZ> attr_bluez; |
+ std::map<uint16_t, arc::mojom::BluetoothSdpServiceAttrPtr>::const_iterator it; |
+ |
+ for (it = rcd->attrs.begin(); it != rcd->attrs.end(); it++) { |
Luis Héctor Chávez
2016/08/16 15:56:03
for (const auto& it : rcd->attrs) ?
Miao
2016/08/17 14:30:20
Done.
|
+ switch (it->first) { |
+ case kServiceClassIDList: |
+ *attr_bluez = |
rickyz (no longer on Chrome)
2016/08/16 23:55:07
Does this work? attr_bluez is nullptr.
Also, this
Miao
2016/08/17 14:30:19
Create a new attribute inside each case.
rickyz (no longer on Chrome)
2016/08/17 18:54:54
This would have been caught by a test :-) Mind add
|
+ mojo::ConvertTo<bluez::BluetoothServiceAttributeValueBlueZ>( |
+ it->second); |
+ if (attr_bluez->size() != 0) |
+ rcd_bluez.AddRecordEntry(kServiceClassIDList, *attr_bluez); |
+ break; |
+ case kProtocolDescriptorList: |
+ *attr_bluez = |
+ mojo::ConvertTo<bluez::BluetoothServiceAttributeValueBlueZ>( |
+ it->second); |
+ if (attr_bluez->size() != 0) |
+ rcd_bluez.AddRecordEntry(kProtocolDescriptorList, *attr_bluez); |
+ break; |
+ case kBrowseGroupList: |
+ *attr_bluez = |
+ mojo::ConvertTo<bluez::BluetoothServiceAttributeValueBlueZ>( |
+ it->second); |
+ if (attr_bluez->size() != 0) |
+ rcd_bluez.AddRecordEntry(kBrowseGroupList, *attr_bluez); |
+ break; |
+ case kBluetoothProfileDescriptorList: |
+ *attr_bluez = |
+ mojo::ConvertTo<bluez::BluetoothServiceAttributeValueBlueZ>( |
+ it->second); |
+ if (attr_bluez->size() != 0) |
+ rcd_bluez.AddRecordEntry(kBluetoothProfileDescriptorList, |
+ *attr_bluez); |
+ break; |
+ case kServiceName: |
+ *attr_bluez = |
+ mojo::ConvertTo<bluez::BluetoothServiceAttributeValueBlueZ>( |
+ it->second); |
+ if (attr_bluez->size() != 0) |
+ rcd_bluez.AddRecordEntry(kServiceName, *attr_bluez); |
+ break; |
+ default: |
+ break; |
+ } |
+ } |
+ |
+ return rcd_bluez; |
+} |
+ |
} // namespace mojo |