| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_task_manager_win.h" | 5 #include "device/bluetooth/bluetooth_task_manager_win.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <winsock2.h> | 8 #include <winsock2.h> |
| 9 | 9 |
| 10 #include <string> | 10 #include <string> |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 void GetDeviceState(const BLUETOOTH_DEVICE_INFO& device_info, | 115 void GetDeviceState(const BLUETOOTH_DEVICE_INFO& device_info, |
| 116 device::BluetoothTaskManagerWin::DeviceState* state) { | 116 device::BluetoothTaskManagerWin::DeviceState* state) { |
| 117 state->name = base::SysWideToUTF8(device_info.szName); | 117 state->name = base::SysWideToUTF8(device_info.szName); |
| 118 state->address = BluetoothAddressToCanonicalString(device_info.Address); | 118 state->address = BluetoothAddressToCanonicalString(device_info.Address); |
| 119 state->bluetooth_class = device_info.ulClassofDevice; | 119 state->bluetooth_class = device_info.ulClassofDevice; |
| 120 state->visible = true; | 120 state->visible = true; |
| 121 state->connected = !!device_info.fConnected; | 121 state->connected = !!device_info.fConnected; |
| 122 state->authenticated = !!device_info.fAuthenticated; | 122 state->authenticated = !!device_info.fAuthenticated; |
| 123 } | 123 } |
| 124 | 124 |
| 125 struct CharacteristicValueChangedRegistration { |
| 126 CharacteristicValueChangedRegistration(); |
| 127 ~CharacteristicValueChangedRegistration(); |
| 128 |
| 129 BLUETOOTH_GATT_EVENT_HANDLE win_event_handle; |
| 130 device::BluetoothTaskManagerWin::GattCharacteristicValueChangedCallback |
| 131 callback; |
| 132 // The task runner the callback should run on. |
| 133 scoped_refptr<base::SequencedTaskRunner> callback_task_runner; |
| 134 }; |
| 135 |
| 136 CharacteristicValueChangedRegistration:: |
| 137 CharacteristicValueChangedRegistration() {} |
| 138 CharacteristicValueChangedRegistration:: |
| 139 ~CharacteristicValueChangedRegistration() {} |
| 140 |
| 141 // The key of CharacteristicValueChangedRegistrationMap is a |
| 142 // GattCharacteristicValueChangedCallback pointer (cast to PVOID) to make it |
| 143 // unique for different callbacks. It is also the context value passed into OS |
| 144 // when registering event. |
| 145 typedef std::unordered_map<PVOID, |
| 146 scoped_ptr<CharacteristicValueChangedRegistration>> |
| 147 CharacteristicValueChangedRegistrationMap; |
| 148 |
| 149 CharacteristicValueChangedRegistrationMap |
| 150 g_characteristic_value_changed_registrations; |
| 151 base::Lock g_characteristic_value_changed_registrations_lock; |
| 152 |
| 153 // Function to be registered to OS to monitor Bluetooth LE GATT event. It is |
| 154 // invoked in BluetoothApis.dll thread. |
| 155 void OnGetGattEventWin(BTH_LE_GATT_EVENT_TYPE type, |
| 156 PVOID event_parameter, |
| 157 PVOID context) { |
| 158 if (type != CharacteristicValueChangedEvent) { |
| 159 // Right now, only characteristic value changed event is supported. |
| 160 NOTREACHED(); |
| 161 return; |
| 162 } |
| 163 |
| 164 BLUETOOTH_GATT_VALUE_CHANGED_EVENT* event = |
| 165 (BLUETOOTH_GATT_VALUE_CHANGED_EVENT*)event_parameter; |
| 166 PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value_win = event->CharacteristicValue; |
| 167 scoped_ptr<std::vector<uint8_t>> new_value( |
| 168 new std::vector<uint8_t>(new_value_win->DataSize)); |
| 169 for (ULONG i = 0; i < new_value_win->DataSize; i++) |
| 170 (*new_value)[i] = new_value_win->Data[i]; |
| 171 |
| 172 base::AutoLock auto_lock(g_characteristic_value_changed_registrations_lock); |
| 173 CharacteristicValueChangedRegistrationMap::const_iterator it = |
| 174 g_characteristic_value_changed_registrations.find(context); |
| 175 if (it == g_characteristic_value_changed_registrations.end()) |
| 176 return; |
| 177 |
| 178 it->second->callback_task_runner->PostTask( |
| 179 FROM_HERE, base::Bind(it->second->callback, base::Passed(&new_value))); |
| 180 } |
| 181 |
| 125 } // namespace | 182 } // namespace |
| 126 | 183 |
| 127 namespace device { | 184 namespace device { |
| 128 | 185 |
| 129 // static | 186 // static |
| 130 const int BluetoothTaskManagerWin::kPollIntervalMs = 500; | 187 const int BluetoothTaskManagerWin::kPollIntervalMs = 500; |
| 131 | 188 |
| 132 BluetoothTaskManagerWin::AdapterState::AdapterState() : powered(false) { | 189 BluetoothTaskManagerWin::AdapterState::AdapterState() : powered(false) { |
| 133 } | 190 } |
| 134 | 191 |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 win_new_value->Data[i] = new_value[i]; | 894 win_new_value->Data[i] = new_value[i]; |
| 838 | 895 |
| 839 HRESULT hr = | 896 HRESULT hr = |
| 840 win::BluetoothLowEnergyWrapper::GetInstance()->WriteCharacteristicValue( | 897 win::BluetoothLowEnergyWrapper::GetInstance()->WriteCharacteristicValue( |
| 841 service_path, (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic), | 898 service_path, (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic), |
| 842 win_new_value.get()); | 899 win_new_value.get()); |
| 843 | 900 |
| 844 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, hr)); | 901 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, hr)); |
| 845 } | 902 } |
| 846 | 903 |
| 904 void BluetoothTaskManagerWin::RegisterGattCharacteristicValueChangedEvent( |
| 905 base::FilePath service_path, |
| 906 BTH_LE_GATT_CHARACTERISTIC characteristic, |
| 907 BTH_LE_GATT_DESCRIPTOR ccc_descriptor, |
| 908 const GattEventRegistrationCallback& callback, |
| 909 const GattCharacteristicValueChangedCallback& registered_callback) { |
| 910 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread()); |
| 911 BLUETOOTH_GATT_EVENT_HANDLE win_event_handle = NULL; |
| 912 |
| 913 BLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION win_event_parameter; |
| 914 memcpy(&(win_event_parameter.Characteristics[0]), &characteristic, |
| 915 sizeof(BTH_LE_GATT_CHARACTERISTIC)); |
| 916 win_event_parameter.NumCharacteristics = 1; |
| 917 PVOID user_event_handle = (PVOID)®istered_callback; |
| 918 HRESULT hr = |
| 919 win::BluetoothLowEnergyWrapper::GetInstance()->RegisterGattEvents( |
| 920 service_path, CharacteristicValueChangedEvent, &win_event_parameter, |
| 921 &OnGetGattEventWin, user_event_handle, &win_event_handle); |
| 922 |
| 923 // Sets the Client Characteristic Configuration descriptor. |
| 924 if (SUCCEEDED(hr)) { |
| 925 BTH_LE_GATT_DESCRIPTOR_VALUE new_cccd_value; |
| 926 RtlZeroMemory(&new_cccd_value, sizeof(new_cccd_value)); |
| 927 new_cccd_value.DescriptorType = ClientCharacteristicConfiguration; |
| 928 if (characteristic.IsNotifiable) { |
| 929 new_cccd_value.ClientCharacteristicConfiguration |
| 930 .IsSubscribeToNotification = TRUE; |
| 931 } else { |
| 932 new_cccd_value.ClientCharacteristicConfiguration.IsSubscribeToIndication = |
| 933 TRUE; |
| 934 } |
| 935 |
| 936 hr = win::BluetoothLowEnergyWrapper::GetInstance()->WriteDescriptorValue( |
| 937 service_path, (PBTH_LE_GATT_DESCRIPTOR)(&ccc_descriptor), |
| 938 &new_cccd_value); |
| 939 } |
| 940 |
| 941 if (SUCCEEDED(hr)) { |
| 942 scoped_ptr<CharacteristicValueChangedRegistration> registration( |
| 943 new CharacteristicValueChangedRegistration()); |
| 944 registration->win_event_handle = win_event_handle; |
| 945 registration->callback = registered_callback; |
| 946 registration->callback_task_runner = ui_task_runner_; |
| 947 base::AutoLock auto_lock(g_characteristic_value_changed_registrations_lock); |
| 948 g_characteristic_value_changed_registrations[user_event_handle] = |
| 949 std::move(registration); |
| 950 } |
| 951 |
| 952 ui_task_runner_->PostTask(FROM_HERE, |
| 953 base::Bind(callback, user_event_handle, hr)); |
| 954 } |
| 955 |
| 956 void BluetoothTaskManagerWin::UnregisterGattCharacteristicValueChangedEvent( |
| 957 PVOID event_handle) { |
| 958 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread()); |
| 959 |
| 960 base::AutoLock auto_lock(g_characteristic_value_changed_registrations_lock); |
| 961 CharacteristicValueChangedRegistrationMap::const_iterator it = |
| 962 g_characteristic_value_changed_registrations.find(event_handle); |
| 963 if (it != g_characteristic_value_changed_registrations.end()) { |
| 964 win::BluetoothLowEnergyWrapper::GetInstance()->UnregisterGattEvent( |
| 965 it->second->win_event_handle); |
| 966 g_characteristic_value_changed_registrations.erase(event_handle); |
| 967 } |
| 968 } |
| 969 |
| 847 void BluetoothTaskManagerWin::PostGetGattIncludedCharacteristics( | 970 void BluetoothTaskManagerWin::PostGetGattIncludedCharacteristics( |
| 848 const base::FilePath& service_path, | 971 const base::FilePath& service_path, |
| 849 const BluetoothUUID& uuid, | 972 const BluetoothUUID& uuid, |
| 850 uint16_t attribute_handle, | 973 uint16_t attribute_handle, |
| 851 const GetGattIncludedCharacteristicsCallback& callback) { | 974 const GetGattIncludedCharacteristicsCallback& callback) { |
| 852 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 975 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 853 bluetooth_task_runner_->PostTask( | 976 bluetooth_task_runner_->PostTask( |
| 854 FROM_HERE, | 977 FROM_HERE, |
| 855 base::Bind(&BluetoothTaskManagerWin::GetGattIncludedCharacteristics, this, | 978 base::Bind(&BluetoothTaskManagerWin::GetGattIncludedCharacteristics, this, |
| 856 service_path, uuid, attribute_handle, callback)); | 979 service_path, uuid, attribute_handle, callback)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 869 | 992 |
| 870 void BluetoothTaskManagerWin::PostReadGattCharacteristicValue( | 993 void BluetoothTaskManagerWin::PostReadGattCharacteristicValue( |
| 871 const base::FilePath& service_path, | 994 const base::FilePath& service_path, |
| 872 const PBTH_LE_GATT_CHARACTERISTIC characteristic, | 995 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 873 const ReadGattCharacteristicValueCallback& callback) { | 996 const ReadGattCharacteristicValueCallback& callback) { |
| 874 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 997 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 875 bluetooth_task_runner_->PostTask( | 998 bluetooth_task_runner_->PostTask( |
| 876 FROM_HERE, | 999 FROM_HERE, |
| 877 base::Bind(&BluetoothTaskManagerWin::ReadGattCharacteristicValue, this, | 1000 base::Bind(&BluetoothTaskManagerWin::ReadGattCharacteristicValue, this, |
| 878 service_path, *characteristic, callback)); | 1001 service_path, *characteristic, callback)); |
| 879 FOR_EACH_OBSERVER(BluetoothTaskManagerWin::Observer, observers_, | |
| 880 OnAttemptReadGattCharacteristic()); | |
| 881 } | 1002 } |
| 882 | 1003 |
| 883 void BluetoothTaskManagerWin::PostWriteGattCharacteristicValue( | 1004 void BluetoothTaskManagerWin::PostWriteGattCharacteristicValue( |
| 884 const base::FilePath& service_path, | 1005 const base::FilePath& service_path, |
| 885 const PBTH_LE_GATT_CHARACTERISTIC characteristic, | 1006 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 886 const std::vector<uint8_t>& new_value, | 1007 const std::vector<uint8_t>& new_value, |
| 887 const HResultCallback& callback) { | 1008 const HResultCallback& callback) { |
| 888 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 1009 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 889 bluetooth_task_runner_->PostTask( | 1010 bluetooth_task_runner_->PostTask( |
| 890 FROM_HERE, | 1011 FROM_HERE, |
| 891 base::Bind(&BluetoothTaskManagerWin::WriteGattCharacteristicValue, this, | 1012 base::Bind(&BluetoothTaskManagerWin::WriteGattCharacteristicValue, this, |
| 892 service_path, *characteristic, new_value, callback)); | 1013 service_path, *characteristic, new_value, callback)); |
| 893 FOR_EACH_OBSERVER(BluetoothTaskManagerWin::Observer, observers_, | 1014 } |
| 894 OnAttemptWriteGattCharacteristic()); | 1015 |
| 1016 void BluetoothTaskManagerWin::PostRegisterGattCharacteristicValueChangedEvent( |
| 1017 const base::FilePath& service_path, |
| 1018 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 1019 const PBTH_LE_GATT_DESCRIPTOR ccc_descriptor, |
| 1020 const GattEventRegistrationCallback& callback, |
| 1021 const GattCharacteristicValueChangedCallback& registered_callback) { |
| 1022 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1023 bluetooth_task_runner_->PostTask( |
| 1024 FROM_HERE, |
| 1025 base::Bind( |
| 1026 &BluetoothTaskManagerWin::RegisterGattCharacteristicValueChangedEvent, |
| 1027 this, service_path, *characteristic, *ccc_descriptor, callback, |
| 1028 registered_callback)); |
| 1029 } |
| 1030 |
| 1031 void BluetoothTaskManagerWin::PostUnregisterGattCharacteristicValueChangedEvent( |
| 1032 PVOID event_handle) { |
| 1033 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1034 bluetooth_task_runner_->PostTask( |
| 1035 FROM_HERE, base::Bind(&BluetoothTaskManagerWin:: |
| 1036 UnregisterGattCharacteristicValueChangedEvent, |
| 1037 this, event_handle)); |
| 895 } | 1038 } |
| 896 | 1039 |
| 897 } // namespace device | 1040 } // namespace device |
| OLD | NEW |