From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/dbus.c | 19 ++++++++++++++ dlls/winebth.sys/winebth.c | 45 +++++++++++++++++++++++++++++++++ dlls/winebth.sys/winebth_priv.h | 6 +++++ 3 files changed, 70 insertions(+)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index 08d63ceb307..5f736583f79 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -1677,6 +1677,22 @@ static DBusHandlerResult bluez_filter( DBusConnection *conn, DBusMessage *msg, v event )) unix_name_free( device ); } + else if (!strcmp( interfaces[i], BLUEZ_INTERFACE_GATT_SERVICE )) + { + struct unix_name *service; + union winebluetooth_watcher_event_data event; + + service = unix_name_get_or_create( object_path ); + if (!service) + { + ERR( "Failed to allocate memory for GATT service path %s\n", debugstr_a( object_path ) ); + continue; + } + event.gatt_service_removed.handle = (UINT_PTR)service; + if (!bluez_event_list_queue_new_event( event_list, BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_GATT_SERVICE_REMOVED, + event )) + unix_name_free( service ); + } } p_dbus_free_string_array( interfaces ); } @@ -1918,6 +1934,9 @@ static void bluez_watcher_free( struct bluez_watcher_ctx *watcher ) unix_name_free( (struct unix_name *)event1->event.gatt_service_added.device.handle ); unix_name_free( (struct unix_name *)event1->event.gatt_service_added.service.handle ); break; + case BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_GATT_SERVICE_REMOVED: + unix_name_free( (struct unix_name *)event1->event.gatt_service_removed.handle ); + break; } free( event1 ); } diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index bc880019740..637a080e470 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -1080,6 +1080,48 @@ static void bluetooth_device_add_gatt_service( struct winebluetooth_watcher_even winebluetooth_gatt_service_free( event.service ); }
+static void bluetooth_gatt_service_remove( winebluetooth_gatt_service_t service ) +{ + 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 ) + { + if (winebluetooth_gatt_service_equal( svc->service, service )) + { + list_remove( &svc->entry ); + LeaveCriticalSection( &device->props_cs ); + LeaveCriticalSection( &radio->remote_devices_cs ); + LeaveCriticalSection( &device_list_cs ); + winebluetooth_gatt_service_free( svc->service ); + free( svc ); + winebluetooth_gatt_service_free( service ); + return; + } + } + LeaveCriticalSection( &device->props_cs ); + } + LeaveCriticalSection( &radio->remote_devices_cs ); + } + LeaveCriticalSection( &device_list_cs ); + winebluetooth_gatt_service_free( service ); +} + static DWORD CALLBACK bluetooth_event_loop_thread_proc( void *arg ) { NTSTATUS status; @@ -1122,6 +1164,9 @@ static DWORD CALLBACK bluetooth_event_loop_thread_proc( void *arg ) case BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_GATT_SERVICE_ADDED: bluetooth_device_add_gatt_service( event->event_data.gatt_service_added ); break; + case BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_GATT_SERVICE_REMOVED: + bluetooth_gatt_service_remove( event->event_data.gatt_service_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 afacccdfb2c..6ba90f36615 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -222,6 +222,10 @@ NTSTATUS winebluetooth_auth_send_response( winebluetooth_device_t device, BLUETO NTSTATUS winebluetooth_device_start_pairing( winebluetooth_device_t device, IRP *irp );
void winebluetooth_gatt_service_free( winebluetooth_gatt_service_t service ); +static inline BOOL winebluetooth_gatt_service_equal( winebluetooth_gatt_service_t s1, winebluetooth_gatt_service_t s2) +{ + return s1.handle == s2.handle; +}
enum winebluetooth_watcher_event_type { @@ -233,6 +237,7 @@ enum winebluetooth_watcher_event_type BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_PROPERTIES_CHANGED, BLUETOOTH_WATCHER_EVENT_TYPE_PAIRING_FINISHED, BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_GATT_SERVICE_ADDED, + BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_GATT_SERVICE_REMOVED, };
struct winebluetooth_watcher_event_radio_added @@ -300,6 +305,7 @@ union winebluetooth_watcher_event_data struct winebluetooth_watcher_event_device_props_changed device_props_changed; struct winebluetooth_watcher_event_pairing_finished pairing_finished; struct winebluetooth_watcher_event_gatt_service_added gatt_service_added; + winebluetooth_gatt_service_t gatt_service_removed; };
struct winebluetooth_watcher_event