From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/Makefile.in | 1 + dlls/bluetoothapis/bluetoothapis.spec | 2 +- dlls/bluetoothapis/gatt.c | 121 ++++++++++++++++++++++++++ include/Makefile.in | 1 + include/bluetoothleapis.h | 32 +++++++ include/bthledef.h | 18 ++++ 6 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 dlls/bluetoothapis/gatt.c create mode 100644 include/bluetoothleapis.h
diff --git a/dlls/bluetoothapis/Makefile.in b/dlls/bluetoothapis/Makefile.in index d4568065953..aaa85e26f84 100644 --- a/dlls/bluetoothapis/Makefile.in +++ b/dlls/bluetoothapis/Makefile.in @@ -6,5 +6,6 @@ EXTRADLLFLAGS = -Wb,--prefer-native
SOURCES = \ bluetoothapis.rc \ + gatt.c \ main.c \ sdp.c diff --git a/dlls/bluetoothapis/bluetoothapis.spec b/dlls/bluetoothapis/bluetoothapis.spec index e26932496dc..2cc00f46c9d 100644 --- a/dlls/bluetoothapis/bluetoothapis.spec +++ b/dlls/bluetoothapis/bluetoothapis.spec @@ -39,7 +39,7 @@ @ stub BluetoothGATTGetDescriptorValue @ stub BluetoothGATTGetDescriptors @ stub BluetoothGATTGetIncludedServices -@ stub BluetoothGATTGetServices +@ stdcall BluetoothGATTGetServices(ptr long ptr ptr long) @ stub BluetoothGATTRegisterEvent @ stub BluetoothGATTSetCharacteristicValue @ stub BluetoothGATTSetDescriptorValue diff --git a/dlls/bluetoothapis/gatt.c b/dlls/bluetoothapis/gatt.c new file mode 100644 index 00000000000..dd7cb619b46 --- /dev/null +++ b/dlls/bluetoothapis/gatt.c @@ -0,0 +1,121 @@ +/* + * BLE General Attribute Profile (GATT) APIs + * + * Copyright 2025 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#include <stdarg.h> +#include <stdint.h> + +#include <windef.h> +#include <winbase.h> + +#include <bthsdpdef.h> +#include <bluetoothapis.h> +#include <bthdef.h> +#include <winioctl.h> +#include <wine/winebth.h> + +#include <initguid.h> +#include <bthledef.h> +#include <bluetoothleapis.h> + +#include "wine/debug.h" +#include "winerror.h" + +WINE_DEFAULT_DEBUG_CHANNEL( bluetoothapis ); + +static void uuid_to_le( const GUID *uuid, BTH_LE_UUID *le_uuid ) +{ + if (uuid->Data1 <= UINT16_MAX && uuid->Data2 == BTH_LE_ATT_BLUETOOTH_BASE_GUID.Data2 + && uuid->Data3 == BTH_LE_ATT_BLUETOOTH_BASE_GUID.Data3 + && !memcmp( uuid->Data4, BTH_LE_ATT_BLUETOOTH_BASE_GUID.Data4, sizeof( uuid->Data4 ) )) + { + le_uuid->IsShortUuid = TRUE; + le_uuid->Value.ShortUuid = uuid->Data1; + } + else + { + le_uuid->IsShortUuid = FALSE; + le_uuid->Value.LongUuid = *uuid; + } +} + +HRESULT WINAPI BluetoothGATTGetServices( HANDLE le_device, USHORT count, BTH_LE_GATT_SERVICE *buf, + USHORT *actual, ULONG flags ) +{ + struct winebth_le_device_get_gatt_services_params *services; + SIZE_T services_count = 1, i; + + TRACE( "(%p, %u, %p, %p, %#lx)\n", le_device, count, buf, actual, flags ); + + if (!actual) + return E_POINTER; + + if ((!buf && count) || (buf && !count) || !actual) + return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); + + for (;;) + { + DWORD size, bytes; + + size = offsetof( struct winebth_le_device_get_gatt_services_params, services[services_count] ); + services = calloc( 1, size ); + if (!services) + return HRESULT_FROM_WIN32( ERROR_NO_SYSTEM_RESOURCES ); + if (!DeviceIoControl( le_device, IOCTL_WINEBTH_LE_DEVICE_GET_GATT_SERVICES, NULL, 0, services, size, &bytes, NULL ) + && GetLastError() != ERROR_MORE_DATA) + { + free( services ); + return HRESULT_FROM_WIN32( GetLastError() ); + } + if (!services->count) + { + *actual = 0; + free( services ); + return S_OK; + } + if (services_count != services->count) + { + services_count = services->count; + free( services ); + continue; + } + break; + } + + *actual = services_count; + if (!buf) + { + free( services ); + return HRESULT_FROM_WIN32( ERROR_MORE_DATA ); + } + + for (i = 0; i < services_count && i < count; i++) + { + memset( &buf[i], 0, sizeof( *buf ) ); + uuid_to_le( &services->services[i].uuid, &buf[i].ServiceUuid ); + buf[i].AttributeHandle = services->services[i].handle; + } + + free( services ); + if (count < services_count) + return HRESULT_FROM_WIN32( ERROR_INVALID_USER_BUFFER ); + + return S_OK; +} diff --git a/include/Makefile.in b/include/Makefile.in index d9190ec2599..5b542b34f24 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -58,6 +58,7 @@ SOURCES = \ bits5_0.idl \ bitsmsg.h \ bluetoothapis.h \ + bluetoothleapis.h \ bthdef.h \ bthledef.h \ bthioctl.h \ diff --git a/include/bluetoothleapis.h b/include/bluetoothleapis.h new file mode 100644 index 00000000000..64cdd366f7d --- /dev/null +++ b/include/bluetoothleapis.h @@ -0,0 +1,32 @@ +/* + * Copyright 2025 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#ifndef __BLUETOOTHLEAPIS_H +#define __BLUETOOTHLEAPIS_H + +#include <bthledef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI BluetoothGATTGetServices( HANDLE, USHORT, BTH_LE_GATT_SERVICE *, USHORT *, ULONG ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/bthledef.h b/include/bthledef.h index f689260c7fe..d3d0393be99 100644 --- a/include/bthledef.h +++ b/include/bthledef.h @@ -17,5 +17,23 @@ */ #ifndef __BTHLEDEFS_H #define __BTHLEDEFS_H + +typedef struct _BTH_LE_UUID +{ + BOOLEAN IsShortUuid; + union + { + USHORT ShortUuid; + GUID LongUuid; + } Value; +} BTH_LE_UUID, *PBTH_LE_UUID; + +typedef struct _BTH_LE_GATT_SERVICE +{ + BTH_LE_UUID ServiceUuid; + USHORT AttributeHandle; +} BTH_LE_GATT_SERVICE, *PBTH_LE_GATT_SERVICE; + DEFINE_GUID( GUID_BLUETOOTHLE_DEVICE_INTERFACE, 0x781aee18, 0x7733, 0x4ce4, 0xad, 0xd0, 0x91, 0xf4, 0x1c, 0x67, 0xb5, 0x92 ); +DEFINE_GUID( BTH_LE_ATT_BLUETOOTH_BASE_GUID, 0, 0, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb ); #endif