Chromium Code Reviews| 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..53f556bce53378c584661efa5cc58eef52bfe77a 100644 |
| --- a/device/bluetooth/bluetooth_service_record_chromeos.cc |
| +++ b/device/bluetooth/bluetooth_service_record_chromeos.cc |
| @@ -17,16 +17,21 @@ |
| namespace { |
| static const char* kAttributeNode = "attribute"; |
| +static const char* kBooleanNode = "boolean"; |
| +static const char* kHidNormallyConnectable = "0x020d"; |
| +static const char* kHidReconnectInitiate = "0x0205"; |
| static const char* kIdAttribute = "id"; |
| static const char* kProtocolDescriptorListId = "0x0004"; |
| -static const char* kRfcommUuid = "0x0003"; |
| +static const char* kProtocolRfcommUuid = "0x0003"; |
| +static const char* kProtocolHidpUuid = "0x0011"; |
| static const char* kSdpNameId = "0x0100"; |
| static const char* kSequenceNode = "sequence"; |
| +static const char* kServiceClassUuidId = "0x0001"; |
| static const char* kTextNode = "text"; |
| static const char* kUint8Node = "uint8"; |
| -static const char* kUuidId = "0x0001"; |
| static const char* kUuidNode = "uuid"; |
| static const char* kValueAttribute = "value"; |
| +static const char* kValueTrue = "true"; |
|
keybuk
2013/02/21 21:08:58
nit: this list would be nicer if it were ordered d
deymo
2013/02/22 23:09:09
Done.
|
| bool AdvanceToTag(XmlReader* reader, const char* node_type) { |
| do { |
| @@ -44,6 +49,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 +69,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 +86,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 == kHidNormallyConnectable) { |
| + ExtractBooleanValue(&reader, &hid_normally_connectable_); |
| + } else if (id == kHidReconnectInitiate) { |
| + 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 +120,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 +156,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) { |