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..e321ec208be02a6003a623edded5c2f62480e9d8 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,69 @@ 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) |
keybuk
2012/04/19 23:30:11
nit: style guide requires that the first arg be on
bryeung
2012/04/20 00:17:56
Done.
|
+ : 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 |