Index: device/bluetooth/bluetooth_service_record_chromeos.cc |
diff --git a/device/bluetooth/bluetooth_service_record_chromeos.cc b/device/bluetooth/bluetooth_service_record_chromeos.cc |
index 6464bddb50fb4644fa0ae077a4ba7def5f1a6109..b7ab878b1015602e68dcbad50878e74be7ceb240 100644 |
--- a/device/bluetooth/bluetooth_service_record_chromeos.cc |
+++ b/device/bluetooth/bluetooth_service_record_chromeos.cc |
@@ -17,16 +17,24 @@ |
namespace { |
static const char* kAttributeNode = "attribute"; |
-static const char* kIdAttribute = "id"; |
-static const char* kProtocolDescriptorListId = "0x0004"; |
-static const char* kRfcommUuid = "0x0003"; |
-static const char* kSdpNameId = "0x0100"; |
+static const char* kBooleanNode = "boolean"; |
static const char* kSequenceNode = "sequence"; |
static const char* kTextNode = "text"; |
static const char* kUint8Node = "uint8"; |
-static const char* kUuidId = "0x0001"; |
static const char* kUuidNode = "uuid"; |
+ |
+static const char* kIdAttribute = "id"; |
static const char* kValueAttribute = "value"; |
+static const char* kValueTrue = "true"; |
+ |
+static const char* kHidNormallyConnectableId = "0x020d"; |
+static const char* kHidReconnectInitiateId = "0x0205"; |
+static const char* kProtocolDescriptorListId = "0x0004"; |
+static const char* kSdpNameId = "0x0100"; |
+static const char* kServiceClassUuidId = "0x0001"; |
+ |
+static const char* kProtocolRfcommUuid = "0x0003"; |
+static const char* kProtocolHidpUuid = "0x0011"; |
bool AdvanceToTag(XmlReader* reader, const char* node_type) { |
do { |
@@ -44,6 +52,17 @@ bool ExtractTextValue(XmlReader* reader, std::string* value_out) { |
return false; |
} |
+bool ExtractBooleanValue(XmlReader* reader, bool* value_out) { |
+ if (AdvanceToTag(reader, kBooleanNode)) { |
+ std::string str_value; |
+ if (!reader->NodeAttribute(kValueAttribute, &str_value)) |
+ return false; |
+ *value_out = str_value == kValueTrue; |
+ return true; |
+ } |
+ return false; |
+} |
+ |
} // namespace |
namespace chromeos { |
@@ -53,6 +72,11 @@ BluetoothServiceRecordChromeOS::BluetoothServiceRecordChromeOS( |
const std::string& xml_data) { |
address_ = address; |
supports_rfcomm_ = false; |
+ supports_hid_ = false; |
+ |
+ // For HID services the default is false when the attribute is not present. |
+ hid_reconnect_initiate_ = false; |
+ hid_normally_connectable_ = false; |
XmlReader reader; |
if (!reader.Load(xml_data)) |
@@ -65,17 +89,26 @@ BluetoothServiceRecordChromeOS::BluetoothServiceRecordChromeOS( |
ExtractTextValue(&reader, &name_); |
} else if (id == kProtocolDescriptorListId) { |
if (AdvanceToTag(&reader, kSequenceNode)) { |
- ExtractChannels(&reader); |
+ ExtractProtocolDescriptors(&reader); |
} |
- } else if (id == kUuidId) { |
+ } else if (id == kServiceClassUuidId) { |
if (AdvanceToTag(&reader, kSequenceNode)) { |
- ExtractUuid(&reader); |
+ ExtractServiceClassUuid(&reader); |
} |
+ } else if (id == kHidNormallyConnectableId) { |
+ ExtractBooleanValue(&reader, &hid_normally_connectable_); |
+ } else if (id == kHidReconnectInitiateId) { |
+ ExtractBooleanValue(&reader, &hid_reconnect_initiate_); |
} |
} |
// We don't care about anything else here, so find the closing tag |
AdvanceToTag(&reader, kAttributeNode); |
} |
+ if (!supports_hid_) { |
+ // For non-HID services the default is true. |
+ hid_normally_connectable_ = true; |
+ hid_reconnect_initiate_ = true; |
+ } |
} |
void BluetoothServiceRecordChromeOS::GetBluetoothAddress( |
@@ -90,26 +123,34 @@ void BluetoothServiceRecordChromeOS::GetBluetoothAddress( |
out_address->b[5 - i] = address_bytes[i]; |
} |
-void BluetoothServiceRecordChromeOS::ExtractChannels(XmlReader* reader) { |
+void BluetoothServiceRecordChromeOS::ExtractProtocolDescriptors( |
+ XmlReader* reader) { |
const int start_depth = reader->Depth(); |
+ // The ProtocolDescriptorList can have one or more sequence of sequence of |
+ // stack, where each stack starts with an UUID and the remaining tags (if |
+ // present) are protocol-specific. |
do { |
if (reader->NodeName() == kSequenceNode) { |
if (AdvanceToTag(reader, kUuidNode)) { |
- std::string type; |
- if (reader->NodeAttribute(kValueAttribute, &type) && |
- type == kRfcommUuid) { |
- if (AdvanceToTag(reader, kUint8Node)) { |
- std::string channel_string; |
- if (reader->NodeAttribute(kValueAttribute, &channel_string)) { |
- std::vector<uint8> channel_bytes; |
- if (base::HexStringToBytes(channel_string.substr(2), |
- &channel_bytes)) { |
- if (channel_bytes.size() == 1) { |
- rfcomm_channel_ = channel_bytes[0]; |
- supports_rfcomm_ = true; |
+ std::string protocolUuid; |
+ if (reader->NodeAttribute(kValueAttribute, &protocolUuid)) { |
+ // Per protocol parameters parsing. |
+ if (protocolUuid == kProtocolRfcommUuid) { |
+ if (AdvanceToTag(reader, kUint8Node)) { |
+ std::string channel_string; |
+ if (reader->NodeAttribute(kValueAttribute, &channel_string)) { |
+ std::vector<uint8> channel_bytes; |
+ if (base::HexStringToBytes(channel_string.substr(2), |
+ &channel_bytes)) { |
+ if (channel_bytes.size() == 1) { |
+ rfcomm_channel_ = channel_bytes[0]; |
+ supports_rfcomm_ = true; |
+ } |
} |
} |
} |
+ } else if (protocolUuid == kProtocolHidpUuid) { |
+ supports_hid_ = true; |
} |
} |
} |
@@ -118,7 +159,8 @@ void BluetoothServiceRecordChromeOS::ExtractChannels(XmlReader* reader) { |
reader->Depth() != start_depth); |
} |
-void BluetoothServiceRecordChromeOS::ExtractUuid(XmlReader* reader) { |
+void BluetoothServiceRecordChromeOS::ExtractServiceClassUuid( |
+ XmlReader* reader) { |
const int start_depth = reader->Depth(); |
do { |
if (reader->NodeName() == kSequenceNode) { |