| 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) {
|
|
|