Chromium Code Reviews| 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. | |
| 154 void OnGetGattEventWin(BTH_LE_GATT_EVENT_TYPE type, | |
|
scheib
2016/04/06 23:56:39
Move thread comment here so that the thread of the
gogerald1
2016/04/08 17:03:30
Done.
| |
| 155 PVOID event_parameter, | |
| 156 PVOID context) { | |
| 157 if (type != CharacteristicValueChangedEvent) { | |
| 158 // Right now, only characteristic value changed event is supported. | |
| 159 NOTREACHED(); | |
| 160 return; | |
| 161 } | |
| 162 | |
| 163 BLUETOOTH_GATT_VALUE_CHANGED_EVENT* event = | |
| 164 (BLUETOOTH_GATT_VALUE_CHANGED_EVENT*)event_parameter; | |
| 165 PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value_win = event->CharacteristicValue; | |
| 166 scoped_ptr<std::vector<uint8_t>> new_value( | |
| 167 new std::vector<uint8_t>(new_value_win->DataSize)); | |
| 168 for (ULONG i = 0; i < new_value_win->DataSize; i++) | |
| 169 (*new_value)[i] = new_value_win->Data[i]; | |
| 170 | |
| 171 // Lock shared data structure since this callback is invoked in | |
| 172 // BluetoothApis.dll thread. | |
| 173 base::AutoLock auto_lock(g_characteristic_value_changed_registrations_lock); | |
| 174 CharacteristicValueChangedRegistrationMap::const_iterator it = | |
| 175 g_characteristic_value_changed_registrations.find(context); | |
| 176 if (it == g_characteristic_value_changed_registrations.end()) | |
| 177 return; | |
| 178 | |
| 179 it->second->callback_task_runner->PostTask( | |
| 180 FROM_HERE, base::Bind(it->second->callback, base::Passed(&new_value))); | |
| 181 } | |
| 182 | |
| 125 } // namespace | 183 } // namespace |
| 126 | 184 |
| 127 namespace device { | 185 namespace device { |
| 128 | 186 |
| 129 // static | 187 // static |
| 130 const int BluetoothTaskManagerWin::kPollIntervalMs = 500; | 188 const int BluetoothTaskManagerWin::kPollIntervalMs = 500; |
| 131 | 189 |
| 132 BluetoothTaskManagerWin::AdapterState::AdapterState() : powered(false) { | 190 BluetoothTaskManagerWin::AdapterState::AdapterState() : powered(false) { |
| 133 } | 191 } |
| 134 | 192 |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 win_new_value->Data[i] = new_value[i]; | 895 win_new_value->Data[i] = new_value[i]; |
| 838 | 896 |
| 839 HRESULT hr = | 897 HRESULT hr = |
| 840 win::BluetoothLowEnergyWrapper::GetInstance()->WriteCharacteristicValue( | 898 win::BluetoothLowEnergyWrapper::GetInstance()->WriteCharacteristicValue( |
| 841 service_path, (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic), | 899 service_path, (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic), |
| 842 win_new_value.get()); | 900 win_new_value.get()); |
| 843 | 901 |
| 844 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, hr)); | 902 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, hr)); |
| 845 } | 903 } |
| 846 | 904 |
| 905 void BluetoothTaskManagerWin::RegisterGattCharacteristicValueChangedEvent( | |
| 906 base::FilePath service_path, | |
| 907 BTH_LE_GATT_CHARACTERISTIC characteristic, | |
| 908 BTH_LE_GATT_DESCRIPTOR ccc_descriptor, | |
| 909 const GattEventRegistrationCallback& callback, | |
| 910 const GattCharacteristicValueChangedCallback& registered_callback) { | |
| 911 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread()); | |
| 912 BLUETOOTH_GATT_EVENT_HANDLE win_event_handle = NULL; | |
| 913 | |
| 914 BLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION win_event_parameter; | |
| 915 memcpy(&(win_event_parameter.Characteristics[0]), &characteristic, | |
| 916 sizeof(BTH_LE_GATT_CHARACTERISTIC)); | |
| 917 win_event_parameter.NumCharacteristics = 1; | |
| 918 PVOID user_event_handle = (PVOID)®istered_callback; | |
| 919 HRESULT hr = | |
| 920 win::BluetoothLowEnergyWrapper::GetInstance()->RegisterGattEvents( | |
| 921 service_path, CharacteristicValueChangedEvent, &win_event_parameter, | |
| 922 &OnGetGattEventWin, user_event_handle, &win_event_handle); | |
| 923 | |
| 924 // Sets the Client Characteristic Configuration descriptor. | |
| 925 if (SUCCEEDED(hr)) { | |
| 926 BTH_LE_GATT_DESCRIPTOR_VALUE new_cccd_value; | |
| 927 RtlZeroMemory(&new_cccd_value, sizeof(new_cccd_value)); | |
| 928 new_cccd_value.DescriptorType = ClientCharacteristicConfiguration; | |
| 929 if (characteristic.IsNotifiable) { | |
| 930 new_cccd_value.ClientCharacteristicConfiguration | |
| 931 .IsSubscribeToNotification = TRUE; | |
| 932 } else { | |
| 933 new_cccd_value.ClientCharacteristicConfiguration.IsSubscribeToIndication = | |
| 934 TRUE; | |
| 935 } | |
| 936 | |
| 937 hr = win::BluetoothLowEnergyWrapper::GetInstance()->WriteDescriptorValue( | |
| 938 service_path, (PBTH_LE_GATT_DESCRIPTOR)(&ccc_descriptor), | |
| 939 &new_cccd_value); | |
| 940 } | |
| 941 | |
| 942 if (SUCCEEDED(hr)) { | |
| 943 scoped_ptr<CharacteristicValueChangedRegistration> registration( | |
| 944 new CharacteristicValueChangedRegistration()); | |
| 945 registration->win_event_handle = win_event_handle; | |
| 946 registration->callback = registered_callback; | |
| 947 registration->callback_task_runner = ui_task_runner_; | |
| 948 base::AutoLock auto_lock(g_characteristic_value_changed_registrations_lock); | |
| 949 g_characteristic_value_changed_registrations[user_event_handle] = | |
| 950 std::move(registration); | |
| 951 } | |
| 952 | |
| 953 ui_task_runner_->PostTask(FROM_HERE, | |
| 954 base::Bind(callback, user_event_handle, hr)); | |
| 955 } | |
| 956 | |
| 957 void BluetoothTaskManagerWin::UnregisterGattCharacteristicValueChangedEvent( | |
| 958 PVOID event_handle) { | |
| 959 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread()); | |
| 960 | |
| 961 base::AutoLock auto_lock(g_characteristic_value_changed_registrations_lock); | |
| 962 CharacteristicValueChangedRegistrationMap::const_iterator it = | |
| 963 g_characteristic_value_changed_registrations.find(event_handle); | |
| 964 if (it != g_characteristic_value_changed_registrations.end()) { | |
| 965 win::BluetoothLowEnergyWrapper::GetInstance()->UnregisterGattEvent( | |
| 966 it->second->win_event_handle); | |
| 967 g_characteristic_value_changed_registrations.erase(event_handle); | |
| 968 } | |
| 969 } | |
| 970 | |
| 847 void BluetoothTaskManagerWin::PostGetGattIncludedCharacteristics( | 971 void BluetoothTaskManagerWin::PostGetGattIncludedCharacteristics( |
| 848 const base::FilePath& service_path, | 972 const base::FilePath& service_path, |
| 849 const BluetoothUUID& uuid, | 973 const BluetoothUUID& uuid, |
| 850 uint16_t attribute_handle, | 974 uint16_t attribute_handle, |
| 851 const GetGattIncludedCharacteristicsCallback& callback) { | 975 const GetGattIncludedCharacteristicsCallback& callback) { |
| 852 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 976 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 853 bluetooth_task_runner_->PostTask( | 977 bluetooth_task_runner_->PostTask( |
| 854 FROM_HERE, | 978 FROM_HERE, |
| 855 base::Bind(&BluetoothTaskManagerWin::GetGattIncludedCharacteristics, this, | 979 base::Bind(&BluetoothTaskManagerWin::GetGattIncludedCharacteristics, this, |
| 856 service_path, uuid, attribute_handle, callback)); | 980 service_path, uuid, attribute_handle, callback)); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 869 | 993 |
| 870 void BluetoothTaskManagerWin::PostReadGattCharacteristicValue( | 994 void BluetoothTaskManagerWin::PostReadGattCharacteristicValue( |
| 871 const base::FilePath& service_path, | 995 const base::FilePath& service_path, |
| 872 const PBTH_LE_GATT_CHARACTERISTIC characteristic, | 996 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 873 const ReadGattCharacteristicValueCallback& callback) { | 997 const ReadGattCharacteristicValueCallback& callback) { |
| 874 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 998 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 875 bluetooth_task_runner_->PostTask( | 999 bluetooth_task_runner_->PostTask( |
| 876 FROM_HERE, | 1000 FROM_HERE, |
| 877 base::Bind(&BluetoothTaskManagerWin::ReadGattCharacteristicValue, this, | 1001 base::Bind(&BluetoothTaskManagerWin::ReadGattCharacteristicValue, this, |
| 878 service_path, *characteristic, callback)); | 1002 service_path, *characteristic, callback)); |
| 879 FOR_EACH_OBSERVER(BluetoothTaskManagerWin::Observer, observers_, | |
| 880 OnAttemptReadGattCharacteristic()); | |
| 881 } | 1003 } |
| 882 | 1004 |
| 883 void BluetoothTaskManagerWin::PostWriteGattCharacteristicValue( | 1005 void BluetoothTaskManagerWin::PostWriteGattCharacteristicValue( |
| 884 const base::FilePath& service_path, | 1006 const base::FilePath& service_path, |
| 885 const PBTH_LE_GATT_CHARACTERISTIC characteristic, | 1007 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 886 const std::vector<uint8_t>& new_value, | 1008 const std::vector<uint8_t>& new_value, |
| 887 const HResultCallback& callback) { | 1009 const HResultCallback& callback) { |
| 888 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 1010 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 889 bluetooth_task_runner_->PostTask( | 1011 bluetooth_task_runner_->PostTask( |
| 890 FROM_HERE, | 1012 FROM_HERE, |
| 891 base::Bind(&BluetoothTaskManagerWin::WriteGattCharacteristicValue, this, | 1013 base::Bind(&BluetoothTaskManagerWin::WriteGattCharacteristicValue, this, |
| 892 service_path, *characteristic, new_value, callback)); | 1014 service_path, *characteristic, new_value, callback)); |
| 893 FOR_EACH_OBSERVER(BluetoothTaskManagerWin::Observer, observers_, | 1015 } |
| 894 OnAttemptWriteGattCharacteristic()); | 1016 |
| 1017 void BluetoothTaskManagerWin::PostRegisterGattCharacteristicValueChangedEvent( | |
| 1018 const base::FilePath& service_path, | |
| 1019 const PBTH_LE_GATT_CHARACTERISTIC characteristic, | |
| 1020 const PBTH_LE_GATT_DESCRIPTOR ccc_descriptor, | |
| 1021 const GattEventRegistrationCallback& callback, | |
| 1022 const GattCharacteristicValueChangedCallback& registered_callback) { | |
| 1023 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
| 1024 bluetooth_task_runner_->PostTask( | |
| 1025 FROM_HERE, | |
| 1026 base::Bind( | |
| 1027 &BluetoothTaskManagerWin::RegisterGattCharacteristicValueChangedEvent, | |
| 1028 this, service_path, *characteristic, *ccc_descriptor, callback, | |
| 1029 registered_callback)); | |
| 1030 } | |
| 1031 | |
| 1032 void BluetoothTaskManagerWin::PostUnregisterGattCharacteristicValueChangedEvent( | |
| 1033 PVOID event_handle) { | |
| 1034 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
| 1035 bluetooth_task_runner_->PostTask( | |
| 1036 FROM_HERE, base::Bind(&BluetoothTaskManagerWin:: | |
| 1037 UnregisterGattCharacteristicValueChangedEvent, | |
| 1038 this, event_handle)); | |
| 895 } | 1039 } |
| 896 | 1040 |
| 897 } // namespace device | 1041 } // namespace device |
| OLD | NEW |