| Index: chrome/browser/chromeos/bluetooth/bluetooth_service_record.cc
|
| diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_service_record.cc b/chrome/browser/chromeos/bluetooth/bluetooth_service_record.cc
|
| index e93004d243336684877a421f9e5367e2b588f1ef..1a92b9b82fdd96d31583f1c7a99f8812438345c8 100644
|
| --- a/chrome/browser/chromeos/bluetooth/bluetooth_service_record.cc
|
| +++ b/chrome/browser/chromeos/bluetooth/bluetooth_service_record.cc
|
| @@ -5,18 +5,26 @@
|
| #include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h"
|
|
|
| #include <string>
|
| +#include <vector>
|
|
|
| +#include "base/logging.h"
|
| +#include "base/string_number_conversions.h"
|
| #include "chrome/common/libxml_utils.h"
|
|
|
| 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* kSequenceNode = "sequence";
|
| static const char* kTextNode = "text";
|
| +static const char* kUint8Node = "uint8";
|
| +static const char* kUuidNode = "uuid";
|
| static const char* kValueAttribute = "value";
|
|
|
| -bool advanceToTag(XmlReader* reader, const char* node_type) {
|
| +bool AdvanceToTag(XmlReader* reader, const char* node_type) {
|
| do {
|
| if (!reader->Read())
|
| return false;
|
| @@ -24,29 +32,70 @@ bool advanceToTag(XmlReader* reader, const char* node_type) {
|
| return true;
|
| }
|
|
|
| +bool ExtractTextValue(XmlReader* reader, std::string* value_out) {
|
| + if (AdvanceToTag(reader, kTextNode)) {
|
| + reader->NodeAttribute(kValueAttribute, value_out);
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace chromeos {
|
|
|
| -BluetoothServiceRecord::BluetoothServiceRecord(const std::string& xml_data) {
|
| +BluetoothServiceRecord::BluetoothServiceRecord(
|
| + const std::string& address,
|
| + const std::string& xml_data)
|
| + : address_(address),
|
| + supports_rfcomm_(false) {
|
| +
|
| XmlReader reader;
|
| if (!reader.Load(xml_data))
|
| return;
|
|
|
| - while (advanceToTag(&reader, kAttributeNode)) {
|
| + while (AdvanceToTag(&reader, kAttributeNode)) {
|
| std::string id;
|
| if (reader.NodeAttribute(kIdAttribute, &id)) {
|
| if (id == kSdpNameId) {
|
| - if (advanceToTag(&reader, kTextNode)) {
|
| - std::string value;
|
| - if (reader.NodeAttribute(kValueAttribute, &value))
|
| - name_ = value;
|
| + ExtractTextValue(&reader, &name_);
|
| + } else if (id == kProtocolDescriptorListId) {
|
| + if (AdvanceToTag(&reader, kSequenceNode)) {
|
| + ExtractChannels(&reader);
|
| }
|
| }
|
| }
|
| // We don't care about anything else here, so find the closing tag
|
| - advanceToTag(&reader, kAttributeNode);
|
| + AdvanceToTag(&reader, kAttributeNode);
|
| }
|
| }
|
|
|
| +void BluetoothServiceRecord::ExtractChannels(XmlReader* reader) {
|
| + const int start_depth = reader->Depth();
|
| + 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;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + } while (AdvanceToTag(reader, kSequenceNode) &&
|
| + reader->Depth() != start_depth);
|
| +}
|
| +
|
| } // namespace chromeos
|
|
|