From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/dbus.c | 19 ++++++++++++ dlls/winebth.sys/winebth.c | 53 +++++++++++++++++++++++++++++++++ dlls/winebth.sys/winebth_priv.h | 7 +++++ 3 files changed, 79 insertions(+)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index 6e87b42cda1..bc9b6b56f64 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -1696,6 +1696,22 @@ static DBusHandlerResult bluez_filter( DBusConnection *conn, DBusMessage *msg, v event )) unix_name_free( service ); } + else if (!strcmp( interfaces[i], BLUEZ_INTERFACE_GATT_CHARACTERISTICS )) + { + struct unix_name *chrc; + union winebluetooth_watcher_event_data event; + + chrc = unix_name_get_or_create( object_path ); + if (!chrc) + { + ERR( "Failed to allocate memory for GATT characteristic path %s\n", debugstr_a( object_path ) ); + continue; + } + event.gatt_characterisic_removed.handle = (UINT_PTR)chrc; + if (!bluez_event_list_queue_new_event( event_list, BLUETOOTH_WATCHER_EVENT_TYPE_GATT_CHARACTERISTIC_REMOVED, + event )) + unix_name_free( chrc ); + } } p_dbus_free_string_array( interfaces ); } @@ -1944,6 +1960,9 @@ static void bluez_watcher_free( struct bluez_watcher_ctx *watcher ) unix_name_free( (struct unix_name *)event1->event.gatt_characteristic_added.characteristic.handle ); unix_name_free( (struct unix_name *)event1->event.gatt_characteristic_added.service.handle ); break; + case BLUETOOTH_WATCHER_EVENT_TYPE_GATT_CHARACTERISTIC_REMOVED: + unix_name_free( (struct unix_name *)event1->event.gatt_characterisic_removed.handle ); + break; } free( event1 ); } diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 685e70aedc1..11bbe5692a3 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -1283,6 +1283,56 @@ failed: winebluetooth_gatt_service_free( characteristic.service ); }
+static void bluetooth_gatt_characteristic_remove( winebluetooth_gatt_characteristic_t handle ) +{ + struct bluetooth_radio *radio; + + EnterCriticalSection( &device_list_cs ); + LIST_FOR_EACH_ENTRY( radio, &device_list, struct bluetooth_radio, entry ) + { + struct bluetooth_remote_device *device; + + EnterCriticalSection( &radio->remote_devices_cs ); + LIST_FOR_EACH_ENTRY( device, &radio->remote_devices, struct bluetooth_remote_device, entry ) + { + struct bluetooth_gatt_service *svc; + + EnterCriticalSection( &device->props_cs ); + if (!device->le) + { + LeaveCriticalSection( &device->props_cs ); + continue; + } + LIST_FOR_EACH_ENTRY( svc, &device->gatt_services, struct bluetooth_gatt_service, entry ) + { + struct bluetooth_gatt_characteristic *chrc; + EnterCriticalSection( &svc->chars_cs ); + LIST_FOR_EACH_ENTRY( chrc, &svc->characteristics, struct bluetooth_gatt_characteristic, entry ) + { + if (winebluetooth_gatt_characteristic_equal( chrc->characteristic, handle )) + { + list_remove( &chrc->entry ); + LeaveCriticalSection( &svc->chars_cs ); + LeaveCriticalSection( &device->props_cs ); + LeaveCriticalSection( &radio->remote_devices_cs ); + LeaveCriticalSection( &device_list_cs ); + + winebluetooth_gatt_characteristic_free( chrc->characteristic ); + winebluetooth_gatt_characteristic_free( handle ); + free( chrc ); + return; + } + } + LeaveCriticalSection( &svc->chars_cs ); + } + LeaveCriticalSection( &device->props_cs ); + } + LeaveCriticalSection( &radio->remote_devices_cs ); + } + LeaveCriticalSection( &device_list_cs ); + winebluetooth_gatt_characteristic_free( handle ); +} + static DWORD CALLBACK bluetooth_event_loop_thread_proc( void *arg ) { NTSTATUS status; @@ -1331,6 +1381,9 @@ static DWORD CALLBACK bluetooth_event_loop_thread_proc( void *arg ) case BLUETOOTH_WATCHER_EVENT_TYPE_GATT_CHARACTERISTIC_ADDED: bluetooth_gatt_service_add_characteristic( event->event_data.gatt_characteristic_added ); break; + case BLUETOOTH_WATCHER_EVENT_TYPE_GATT_CHARACTERISTIC_REMOVED: + bluetooth_gatt_characteristic_remove( event->event_data.gatt_characterisic_removed ); + break; default: FIXME( "Unknown bluetooth watcher event code: %#x\n", event->event_type ); } diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h index 6444678ed18..3b009c6da5d 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -233,6 +233,11 @@ static inline BOOL winebluetooth_gatt_service_equal( winebluetooth_gatt_service_ }
void winebluetooth_gatt_characteristic_free( winebluetooth_gatt_characteristic_t characteristic ); +static inline BOOL winebluetooth_gatt_characteristic_equal( winebluetooth_gatt_characteristic_t c1, + winebluetooth_gatt_characteristic_t c2) +{ + return c1.handle == c2.handle; +}
enum winebluetooth_watcher_event_type { @@ -246,6 +251,7 @@ enum winebluetooth_watcher_event_type BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_GATT_SERVICE_ADDED, BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_GATT_SERVICE_REMOVED, BLUETOOTH_WATCHER_EVENT_TYPE_GATT_CHARACTERISTIC_ADDED, + BLUETOOTH_WATCHER_EVENT_TYPE_GATT_CHARACTERISTIC_REMOVED, };
struct winebluetooth_watcher_event_radio_added @@ -333,6 +339,7 @@ union winebluetooth_watcher_event_data struct winebluetooth_watcher_event_gatt_service_added gatt_service_added; winebluetooth_gatt_service_t gatt_service_removed; struct winebluetooth_watcher_event_gatt_characteristic_added gatt_characteristic_added; + winebluetooth_gatt_characteristic_t gatt_characterisic_removed; };
struct winebluetooth_watcher_event