#include "bluetooth.h"
#include "common/library.h"
#include "util/windows/unicode.h"
#include <windows.h>
#include <bluetoothapis.h>
#pragma GCC diagnostic ignored "-Wpointer-sign"
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices )
{
FF_LIBRARY_LOAD(bluetoothapis, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindFirstDevice)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindNextDevice)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindDeviceClose)
BLUETOOTH_DEVICE_INFO btdi = {
.dwSize = sizeof(btdi)
};
HBLUETOOTH_DEVICE_FIND hFind = ffBluetoothFindFirstDevice(&(BLUETOOTH_DEVICE_SEARCH_PARAMS) {
.fReturnConnected = TRUE,
.fReturnRemembered = options->showDisconnected,
.fReturnAuthenticated = options->showDisconnected,
.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS)
}, &btdi);
if(!hFind)
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
return NULL;
return "BluetoothFindFirstDevice() failed";
}
do {
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInitWS(&device->name, btdi.szName);
ffStrbufInitF(&device->address, "%02X:%02X:%02X:%02X:%02X:%02X",
btdi.Address.rgBytes[5],
btdi.Address.rgBytes[4],
btdi.Address.rgBytes[3],
btdi.Address.rgBytes[2],
btdi.Address.rgBytes[1],
btdi.Address.rgBytes[0]);
ffStrbufInit(&device->type);
device->battery = 0;
device->connected = !!btdi.fConnected;
if(BitTest(&btdi.ulClassofDevice, 13))
ffStrbufAppendS(&device->type, "Limited Discoverable Mode, ");
if(BitTest(&btdi.ulClassofDevice, 14))
ffStrbufAppendS(&device->type, "LE audio, ");
if(BitTest(&btdi.ulClassofDevice, 15))
ffStrbufAppendS(&device->type, "Reserved for future use, ");
if(BitTest(&btdi.ulClassofDevice, 16))
ffStrbufAppendS(&device->type, "Positioning, ");
if(BitTest(&btdi.ulClassofDevice, 17))
ffStrbufAppendS(&device->type, "Networking, ");
if(BitTest(&btdi.ulClassofDevice, 18))
ffStrbufAppendS(&device->type, "Rendering, ");
if(BitTest(&btdi.ulClassofDevice, 19))
ffStrbufAppendS(&device->type, "Capturing, ");
if(BitTest(&btdi.ulClassofDevice, 20))
ffStrbufAppendS(&device->type, "Object Transfer, ");
if(BitTest(&btdi.ulClassofDevice, 21))
ffStrbufAppendS(&device->type, "Audio, ");
if(BitTest(&btdi.ulClassofDevice, 22))
ffStrbufAppendS(&device->type, "Telephony, ");
if(BitTest(&btdi.ulClassofDevice, 23))
ffStrbufAppendS(&device->type, "Information, ");
if(device->type.length == 0)
{
uint32_t majorDeviceClasses = (btdi.ulClassofDevice >> 8) & ~(UINT32_MAX << 5);
switch(majorDeviceClasses)
{
case 0b00000:
ffStrbufAppendS(&device->type, "Miscellaneous");
break;
case 0b00001:
ffStrbufAppendS(&device->type, "Computer");
break;
case 0b00010:
ffStrbufAppendS(&device->type, "Phone");
break;
case 0b00011:
ffStrbufAppendS(&device->type, "LAN/Network Access point");
break;
case 0b00100:
ffStrbufAppendS(&device->type, "Audio/Video");
break;
case 0b00101:
ffStrbufAppendS(&device->type, "Peripheral");
break;
case 0b00110:
ffStrbufAppendS(&device->type, "Imaging");
break;
case 0b00111:
ffStrbufAppendS(&device->type, "Wearable");
break;
case 0b01000:
ffStrbufAppendS(&device->type, "Toy");
break;
case 0b01001:
ffStrbufAppendS(&device->type, "Health");
break;
case 0b11111:
ffStrbufAppendS(&device->type, "Uncategorized");
break;
default:
ffStrbufAppendS(&device->type, "Unknown");
break;
}
}
else
{
ffStrbufTrimRight(&device->type, ' ');
ffStrbufTrimRight(&device->type, ',');
}
} while (ffBluetoothFindNextDevice(hFind, &btdi));
ffBluetoothFindDeviceClose(hFind);
const char* ffBluetoothDetectBattery(FFlist* result);
ffBluetoothDetectBattery(devices);
return NULL;
}