| OLD | NEW | 
|    1 // Copyright 2015 The Chromium Authors. All rights reserved. |    1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "device/bluetooth/bluetooth_low_energy_device_mac.h" |    5 #include "device/bluetooth/bluetooth_low_energy_device_mac.h" | 
|    6  |    6  | 
|    7 #import <CoreFoundation/CoreFoundation.h> |    7 #import <CoreFoundation/CoreFoundation.h> | 
|    8 #include <stddef.h> |    8 #include <stddef.h> | 
|    9  |    9  | 
|   10 #include "base/mac/mac_util.h" |   10 #include "base/mac/mac_util.h" | 
|   11 #include "base/mac/scoped_cftyperef.h" |   11 #include "base/mac/scoped_cftyperef.h" | 
|   12 #include "base/mac/sdk_forward_declarations.h" |   12 #include "base/mac/sdk_forward_declarations.h" | 
|   13 #include "base/memory/ptr_util.h" |   13 #include "base/memory/ptr_util.h" | 
|   14 #include "base/strings/string_number_conversions.h" |   14 #include "base/strings/string_number_conversions.h" | 
|   15 #include "base/strings/sys_string_conversions.h" |   15 #include "base/strings/sys_string_conversions.h" | 
|   16 #include "device/bluetooth/bluetooth_adapter_mac.h" |   16 #include "device/bluetooth/bluetooth_adapter_mac.h" | 
|   17 #include "device/bluetooth/bluetooth_device.h" |   17 #include "device/bluetooth/bluetooth_device.h" | 
|   18 #include "device/bluetooth/bluetooth_low_energy_peripheral_delegate.h" |   18 #include "device/bluetooth/bluetooth_low_energy_peripheral_delegate.h" | 
|   19 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h" |   19 #include "device/bluetooth/bluetooth_remote_gatt_service_mac.h" | 
|   20  |   20  | 
|   21 using device::BluetoothDevice; |   21 using device::BluetoothDevice; | 
|   22 using device::BluetoothLowEnergyDeviceMac; |   22 using device::BluetoothLowEnergyDeviceMac; | 
|   23  |   23  | 
|   24 BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac( |   24 BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac( | 
|   25     BluetoothAdapterMac* adapter, |   25     BluetoothAdapterMac* adapter, | 
|   26     CBPeripheral* peripheral, |   26     CBPeripheral* peripheral) | 
|   27     NSDictionary* advertisement_data, |  | 
|   28     int rssi) |  | 
|   29     : BluetoothDeviceMac(adapter), |   27     : BluetoothDeviceMac(adapter), | 
|   30       peripheral_(peripheral, base::scoped_policy::RETAIN) { |   28       peripheral_(peripheral, base::scoped_policy::RETAIN) { | 
|   31   DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); |   29   DCHECK(BluetoothAdapterMac::IsLowEnergyAvailable()); | 
|   32   DCHECK(peripheral_.get()); |   30   DCHECK(peripheral_.get()); | 
|   33   peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc] |   31   peripheral_delegate_.reset([[BluetoothLowEnergyPeripheralDelegate alloc] | 
|   34       initWithBluetoothLowEnergyDeviceMac:this]); |   32       initWithBluetoothLowEnergyDeviceMac:this]); | 
|   35   [peripheral_ setDelegate:peripheral_delegate_]; |   33   [peripheral_ setDelegate:peripheral_delegate_]; | 
|   36   identifier_ = GetPeripheralIdentifier(peripheral); |   34   identifier_ = GetPeripheralIdentifier(peripheral); | 
|   37   hash_address_ = GetPeripheralHashAddress(peripheral); |   35   hash_address_ = GetPeripheralHashAddress(peripheral); | 
|   38   Update(advertisement_data, rssi); |  | 
|   39 } |   36 } | 
|   40  |   37  | 
|   41 BluetoothLowEnergyDeviceMac::~BluetoothLowEnergyDeviceMac() { |   38 BluetoothLowEnergyDeviceMac::~BluetoothLowEnergyDeviceMac() { | 
|   42   if (IsGattConnected()) { |   39   if (IsGattConnected()) { | 
|   43     GetMacAdapter()->DisconnectGatt(this); |   40     GetMacAdapter()->DisconnectGatt(this); | 
|   44   } |   41   } | 
|   45 } |   42 } | 
|   46  |   43  | 
|   47 void BluetoothLowEnergyDeviceMac::Update(NSDictionary* advertisement_data, |  | 
|   48                                          int rssi) { |  | 
|   49   UpdateTimestamp(); |  | 
|   50   rssi_ = rssi; |  | 
|   51   NSNumber* connectable = |  | 
|   52       [advertisement_data objectForKey:CBAdvertisementDataIsConnectable]; |  | 
|   53   connectable_ = [connectable boolValue]; |  | 
|   54   ClearServiceData(); |  | 
|   55   NSDictionary* service_data = |  | 
|   56       [advertisement_data objectForKey:CBAdvertisementDataServiceDataKey]; |  | 
|   57   for (CBUUID* uuid in service_data) { |  | 
|   58     NSData* data = [service_data objectForKey:uuid]; |  | 
|   59     BluetoothUUID service_uuid = |  | 
|   60         BluetoothAdapterMac::BluetoothUUIDWithCBUUID(uuid); |  | 
|   61     SetServiceData(service_uuid, static_cast<const char*>([data bytes]), |  | 
|   62                    [data length]); |  | 
|   63   } |  | 
|   64  |  | 
|   65   std::unordered_set<BluetoothUUID, BluetoothUUIDHash> uuid_set; |  | 
|   66   NSArray* service_uuids = |  | 
|   67       [advertisement_data objectForKey:CBAdvertisementDataServiceUUIDsKey]; |  | 
|   68   for (CBUUID* uuid in service_uuids) { |  | 
|   69     uuid_set.emplace([[uuid UUIDString] UTF8String]); |  | 
|   70   } |  | 
|   71   NSArray* overflow_service_uuids = [advertisement_data |  | 
|   72       objectForKey:CBAdvertisementDataOverflowServiceUUIDsKey]; |  | 
|   73   for (CBUUID* uuid in overflow_service_uuids) { |  | 
|   74     uuid_set.emplace([[uuid UUIDString] UTF8String]); |  | 
|   75   } |  | 
|   76  |  | 
|   77   advertised_uuids_ = UUIDList(uuid_set.begin(), uuid_set.end()); |  | 
|   78 } |  | 
|   79  |  | 
|   80 std::string BluetoothLowEnergyDeviceMac::GetIdentifier() const { |   44 std::string BluetoothLowEnergyDeviceMac::GetIdentifier() const { | 
|   81   return identifier_; |   45   return identifier_; | 
|   82 } |   46 } | 
|   83  |   47  | 
|   84 uint32_t BluetoothLowEnergyDeviceMac::GetBluetoothClass() const { |   48 uint32_t BluetoothLowEnergyDeviceMac::GetBluetoothClass() const { | 
|   85   return 0x1F00;  // Unspecified Device Class |   49   return 0x1F00;  // Unspecified Device Class | 
|   86 } |   50 } | 
|   87  |   51  | 
|   88 std::string BluetoothLowEnergyDeviceMac::GetAddress() const { |   52 std::string BluetoothLowEnergyDeviceMac::GetAddress() const { | 
|   89   return hash_address_; |   53   return hash_address_; | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  112   NOTIMPLEMENTED(); |   76   NOTIMPLEMENTED(); | 
|  113   return 0; |   77   return 0; | 
|  114 } |   78 } | 
|  115  |   79  | 
|  116 base::Optional<std::string> BluetoothLowEnergyDeviceMac::GetName() const { |   80 base::Optional<std::string> BluetoothLowEnergyDeviceMac::GetName() const { | 
|  117   if ([peripheral_ name]) |   81   if ([peripheral_ name]) | 
|  118     return base::SysNSStringToUTF8([peripheral_ name]); |   82     return base::SysNSStringToUTF8([peripheral_ name]); | 
|  119   return base::nullopt; |   83   return base::nullopt; | 
|  120 } |   84 } | 
|  121  |   85  | 
|  122 int BluetoothLowEnergyDeviceMac::GetRSSI() const { |  | 
|  123   return rssi_; |  | 
|  124 } |  | 
|  125  |  | 
|  126 bool BluetoothLowEnergyDeviceMac::IsPaired() const { |   86 bool BluetoothLowEnergyDeviceMac::IsPaired() const { | 
|  127   return false; |   87   return false; | 
|  128 } |   88 } | 
|  129  |   89  | 
|  130 bool BluetoothLowEnergyDeviceMac::IsConnected() const { |   90 bool BluetoothLowEnergyDeviceMac::IsConnected() const { | 
|  131   return IsGattConnected(); |   91   return IsGattConnected(); | 
|  132 } |   92 } | 
|  133  |   93  | 
|  134 bool BluetoothLowEnergyDeviceMac::IsGattConnected() const { |   94 bool BluetoothLowEnergyDeviceMac::IsGattConnected() const { | 
|  135   return ([peripheral_ state] == CBPeripheralStateConnected); |   95   return ([peripheral_ state] == CBPeripheralStateConnected); | 
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  294   // Notify when all services have been discovered. |  254   // Notify when all services have been discovered. | 
|  295   bool discovery_complete = |  255   bool discovery_complete = | 
|  296       std::find_if_not( |  256       std::find_if_not( | 
|  297           gatt_services_.begin(), gatt_services_.end(), |  257           gatt_services_.begin(), gatt_services_.end(), | 
|  298           [](std::pair<std::string, BluetoothRemoteGattService*> pair) { |  258           [](std::pair<std::string, BluetoothRemoteGattService*> pair) { | 
|  299             BluetoothRemoteGattService* gatt_service = pair.second; |  259             BluetoothRemoteGattService* gatt_service = pair.second; | 
|  300             return static_cast<BluetoothRemoteGattServiceMac*>(gatt_service) |  260             return static_cast<BluetoothRemoteGattServiceMac*>(gatt_service) | 
|  301                 ->IsDiscoveryComplete(); |  261                 ->IsDiscoveryComplete(); | 
|  302           }) == gatt_services_.end(); |  262           }) == gatt_services_.end(); | 
|  303   if (discovery_complete) { |  263   if (discovery_complete) { | 
|  304     UpdateServiceUUIDs(); |  264     device_uuids_.ReplaceServiceUUIDs(gatt_services_); | 
|  305     SetGattServicesDiscoveryComplete(true); |  265     SetGattServicesDiscoveryComplete(true); | 
|  306     adapter_->NotifyGattServicesDiscovered(this); |  266     adapter_->NotifyGattServicesDiscovered(this); | 
 |  267     adapter_->NotifyDeviceChanged(this); | 
|  307   } |  268   } | 
|  308 } |  269 } | 
|  309  |  270  | 
|  310 void BluetoothLowEnergyDeviceMac::DidModifyServices( |  271 void BluetoothLowEnergyDeviceMac::DidModifyServices( | 
|  311     NSArray* invalidatedServices) { |  272     NSArray* invalidatedServices) { | 
|  312   for (CBService* cb_service in invalidatedServices) { |  273   for (CBService* cb_service in invalidatedServices) { | 
|  313     BluetoothRemoteGattServiceMac* gatt_service = |  274     BluetoothRemoteGattServiceMac* gatt_service = | 
|  314         GetBluetoothRemoteGattService(cb_service); |  275         GetBluetoothRemoteGattService(cb_service); | 
|  315     DCHECK(gatt_service); |  276     DCHECK(gatt_service); | 
|  316     std::unique_ptr<BluetoothRemoteGattService> scoped_service = |  277     std::unique_ptr<BluetoothRemoteGattService> scoped_service = | 
|  317         gatt_services_.take_and_erase(gatt_service->GetIdentifier()); |  278         gatt_services_.take_and_erase(gatt_service->GetIdentifier()); | 
|  318     adapter_->NotifyGattServiceRemoved(scoped_service.get()); |  279     adapter_->NotifyGattServiceRemoved(scoped_service.get()); | 
|  319   } |  280   } | 
|  320   service_uuids_.clear(); |  281   device_uuids_.ClearServiceUUIDs(); | 
|  321   SetGattServicesDiscoveryComplete(false); |  282   SetGattServicesDiscoveryComplete(false); | 
 |  283   adapter_->NotifyDeviceChanged(this); | 
|  322   [GetPeripheral() discoverServices:nil]; |  284   [GetPeripheral() discoverServices:nil]; | 
|  323 } |  285 } | 
|  324  |  286  | 
|  325 void BluetoothLowEnergyDeviceMac::DidUpdateValue( |  287 void BluetoothLowEnergyDeviceMac::DidUpdateValue( | 
|  326     CBCharacteristic* characteristic, |  288     CBCharacteristic* characteristic, | 
|  327     NSError* error) { |  289     NSError* error) { | 
|  328   BluetoothRemoteGattServiceMac* gatt_service = |  290   BluetoothRemoteGattServiceMac* gatt_service = | 
|  329       GetBluetoothRemoteGattService(characteristic.service); |  291       GetBluetoothRemoteGattService(characteristic.service); | 
|  330   DCHECK(gatt_service); |  292   DCHECK(gatt_service); | 
|  331   gatt_service->DidUpdateValue(characteristic, error); |  293   gatt_service->DidUpdateValue(characteristic, error); | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  392 } |  354 } | 
|  393  |  355  | 
|  394 void BluetoothLowEnergyDeviceMac::DidDisconnectPeripheral( |  356 void BluetoothLowEnergyDeviceMac::DidDisconnectPeripheral( | 
|  395     BluetoothDevice::ConnectErrorCode error_code) { |  357     BluetoothDevice::ConnectErrorCode error_code) { | 
|  396   SetGattServicesDiscoveryComplete(false); |  358   SetGattServicesDiscoveryComplete(false); | 
|  397   // Removing all services at once to ensure that calling GetGattService on |  359   // Removing all services at once to ensure that calling GetGattService on | 
|  398   // removed service in GattServiceRemoved returns null. |  360   // removed service in GattServiceRemoved returns null. | 
|  399   GattServiceMap gatt_services_swapped; |  361   GattServiceMap gatt_services_swapped; | 
|  400   gatt_services_swapped.swap(gatt_services_); |  362   gatt_services_swapped.swap(gatt_services_); | 
|  401   gatt_services_swapped.clear(); |  363   gatt_services_swapped.clear(); | 
|  402   UpdateServiceUUIDs(); |  364   device_uuids_.ClearServiceUUIDs(); | 
|  403   if (create_gatt_connection_error_callbacks_.empty()) { |  365   if (create_gatt_connection_error_callbacks_.empty()) { | 
|  404     // TODO(http://crbug.com/585897): Need to pass the error. |  366     // TODO(http://crbug.com/585897): Need to pass the error. | 
|  405     DidDisconnectGatt(); |  367     DidDisconnectGatt(); | 
|  406   } else { |  368   } else { | 
|  407     DidFailToConnectGatt(error_code); |  369     DidFailToConnectGatt(error_code); | 
|  408   } |  370   } | 
|  409 } |  371 } | 
| OLD | NEW |