diff --git a/CMakeLists.txt b/CMakeLists.txt index d585a6b1c..e1fc0fdae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -438,7 +438,7 @@ elseif(APPLE) src/common/sysctl.c src/detection/battery/battery_apple.c src/detection/bios/bios_apple.c - src/detection/bluetooth/bluetooth_nosupport.c + src/detection/bluetooth/bluetooth_apple.m src/detection/board/board_nosupport.c src/detection/brightness/brightness_apple.c src/detection/chassis/chassis_nosupport.c @@ -676,6 +676,7 @@ if(APPLE) PRIVATE "-framework Cocoa" PRIVATE "-framework CoreWLAN" PRIVATE "-framework CoreVideo" + PRIVATE "-framework IOBluetooth" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" PRIVATE "-weak_framework DisplayServices -F /System/Library/PrivateFrameworks" ) diff --git a/src/detection/bluetooth/bluetooth_apple.m b/src/detection/bluetooth/bluetooth_apple.m new file mode 100644 index 000000000..8affb9074 --- /dev/null +++ b/src/detection/bluetooth/bluetooth_apple.m @@ -0,0 +1,93 @@ +#include "bluetooth.h" + +#import + +void ffDetectBluetoothImpl(FF_MAYBE_UNUSED const FFinstance* instance, FFBluetoothResult* bluetooth) +{ + NSArray* ioDevices = IOBluetoothDevice.pairedDevices; + if(!ioDevices) + { + ffStrbufAppendS(&bluetooth->error, "IOBluetoothDevice.pairedDevices failed"); + return; + } + + for(IOBluetoothDevice* ioDevice in ioDevices) + { + FFBluetoothDevice* device = ffListAdd(&bluetooth->devices); + ffStrbufInitS(&device->name, ioDevice.name.UTF8String); + ffStrbufInitS(&device->address, ioDevice.addressString.UTF8String); + ffStrbufInit(&device->type); + device->battery = 0; + device->connected = !!ioDevice.isConnected; + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorLimitedDiscoverableMode) + ffStrbufAppendS(&device->type, "Limited Discoverable Mode, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorReserved1) + ffStrbufAppendS(&device->type, "LE audio, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorReserved2) + ffStrbufAppendS(&device->type, "Reserved for future use, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorPositioning) + ffStrbufAppendS(&device->type, "Positioning, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorNetworking) + ffStrbufAppendS(&device->type, "Networking, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorRendering) + ffStrbufAppendS(&device->type, "Rendering, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorCapturing) + ffStrbufAppendS(&device->type, "Capturing, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorObjectTransfer) + ffStrbufAppendS(&device->type, "Object Transfer, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorAudio) + ffStrbufAppendS(&device->type, "Audio, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorTelephony) + ffStrbufAppendS(&device->type, "Telephony, "); + if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorInformation) + ffStrbufAppendS(&device->type, "Information, "); + + if(device->type.length == 0) + { + switch(ioDevice.deviceClassMajor) + { + case kBluetoothDeviceClassMajorMiscellaneous: + ffStrbufAppendS(&device->type, "Miscellaneous"); + break; + case kBluetoothDeviceClassMajorComputer: + ffStrbufAppendS(&device->type, "Computer"); + break; + case kBluetoothDeviceClassMajorPhone: + ffStrbufAppendS(&device->type, "Phone"); + break; + case kBluetoothDeviceClassMajorLANAccessPoint: + ffStrbufAppendS(&device->type, "LAN/Network Access point"); + break; + case kBluetoothDeviceClassMajorAudio: + ffStrbufAppendS(&device->type, "Audio/Video"); + break; + case kBluetoothDeviceClassMajorPeripheral: + ffStrbufAppendS(&device->type, "Peripheral"); + break; + case kBluetoothDeviceClassMajorImaging: + ffStrbufAppendS(&device->type, "Imaging"); + break; + case kBluetoothDeviceClassMajorWearable: + ffStrbufAppendS(&device->type, "Wearable"); + break; + case kBluetoothDeviceClassMajorToy: + ffStrbufAppendS(&device->type, "Toy"); + break; + case kBluetoothDeviceClassMajorHealth: + ffStrbufAppendS(&device->type, "Health"); + break; + case kBluetoothDeviceClassMajorUnclassified: + ffStrbufAppendS(&device->type, "Uncategorized"); + break; + default: + ffStrbufAppendS(&device->type, "Unknown"); + break; + } + } + else + { + ffStrbufTrimRight(&device->type, ' '); + ffStrbufTrimRight(&device->type, ','); + } + } +}