Home | History | Annotate | Download | only in bluetooth
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "device/bluetooth/bluetooth_uuid.h"
      6 
      7 #include <stddef.h>
      8 
      9 #include "base/logging.h"
     10 #include "base/strings/string_util.h"
     11 
     12 namespace device {
     13 
     14 namespace {
     15 
     16 const char kCommonUuidPostfix[] = "-0000-1000-8000-00805f9b34fb";
     17 const char kCommonUuidPrefix[] = "0000";
     18 
     19 // Returns the canonical, 128-bit canonical, and the format of the UUID
     20 // in |canonical|, |canonical_128|, and |format| based on |uuid|.
     21 void GetCanonicalUuid(std::string uuid,
     22                       std::string* canonical,
     23                       std::string* canonical_128,
     24                       BluetoothUUID::Format* format) {
     25   // Initialize the values for the failure case.
     26   canonical->clear();
     27   canonical_128->clear();
     28   *format = BluetoothUUID::kFormatInvalid;
     29 
     30   if (uuid.empty())
     31     return;
     32 
     33   if (uuid.size() < 11 &&
     34       base::StartsWith(uuid, "0x", base::CompareCase::SENSITIVE)) {
     35     uuid = uuid.substr(2);
     36   }
     37 
     38   if (!(uuid.size() == 4 || uuid.size() == 8 || uuid.size() == 36))
     39     return;
     40 
     41   for (size_t i = 0; i < uuid.size(); ++i) {
     42     if (i == 8 || i == 13 || i == 18 || i == 23) {
     43       if (uuid[i] != '-')
     44         return;
     45     } else {
     46       if (!base::IsHexDigit(uuid[i]))
     47         return;
     48       uuid[i] = base::ToLowerASCII(uuid[i]);
     49     }
     50   }
     51 
     52   canonical->assign(uuid);
     53   if (uuid.size() == 4) {
     54     canonical_128->assign(kCommonUuidPrefix + uuid + kCommonUuidPostfix);
     55     *format = BluetoothUUID::kFormat16Bit;
     56   } else if (uuid.size() == 8) {
     57     canonical_128->assign(uuid + kCommonUuidPostfix);
     58     *format = BluetoothUUID::kFormat32Bit;
     59   } else {
     60     canonical_128->assign(uuid);
     61     *format = BluetoothUUID::kFormat128Bit;
     62   }
     63 }
     64 
     65 }  // namespace
     66 
     67 
     68 BluetoothUUID::BluetoothUUID(const std::string& uuid) {
     69   GetCanonicalUuid(uuid, &value_, &canonical_value_, &format_);
     70 }
     71 
     72 BluetoothUUID::BluetoothUUID() : format_(kFormatInvalid) {
     73 }
     74 
     75 BluetoothUUID::~BluetoothUUID() {
     76 }
     77 
     78 bool BluetoothUUID::IsValid() const {
     79   return format_ != kFormatInvalid;
     80 }
     81 
     82 bool BluetoothUUID::operator<(const BluetoothUUID& uuid) const {
     83   return canonical_value_ < uuid.canonical_value_;
     84 }
     85 
     86 bool BluetoothUUID::operator==(const BluetoothUUID& uuid) const {
     87   return canonical_value_ == uuid.canonical_value_;
     88 }
     89 
     90 bool BluetoothUUID::operator!=(const BluetoothUUID& uuid) const {
     91   return canonical_value_ != uuid.canonical_value_;
     92 }
     93 
     94 void PrintTo(const BluetoothUUID& uuid, std::ostream* out) {
     95   *out << uuid.canonical_value();
     96 }
     97 
     98 }  // namespace device
     99