From c14ba32b82e39e5ea0db7c8c23dda87791d23ea4 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 28 Jul 2024 15:26:37 +0800 Subject: [PATCH] BluetoothRadio: add more props; remove hciVersion; code cleanup --- src/detection/bluetooth/bluetooth_windows.c | 5 +- src/detection/bluetoothradio/bluetoothradio.h | 9 ++-- .../bluetoothradio/bluetoothradio_apple.m | 9 ++-- .../bluetoothradio/bluetoothradio_linux.c | 25 ++++++---- .../bluetoothradio/bluetoothradio_windows.c | 9 ++-- src/modules/bluetoothradio/bluetoothradio.c | 48 +++++++++++++------ 6 files changed, 68 insertions(+), 37 deletions(-) diff --git a/src/detection/bluetooth/bluetooth_windows.c b/src/detection/bluetooth/bluetooth_windows.c index 2ac377d01..58322be19 100644 --- a/src/detection/bluetooth/bluetooth_windows.c +++ b/src/detection/bluetooth/bluetooth_windows.c @@ -27,10 +27,7 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */) }, &btdi); if(!hFind) { - if (GetLastError() == ERROR_NO_MORE_ITEMS) - return "No Bluetooth devices found"; - else - return "BluetoothFindFirstDevice() failed"; + return "BluetoothFindFirstDevice() failed"; } do { diff --git a/src/detection/bluetoothradio/bluetoothradio.h b/src/detection/bluetoothradio/bluetoothradio.h index 669f8bc5c..ad68ca2fd 100644 --- a/src/detection/bluetoothradio/bluetoothradio.h +++ b/src/detection/bluetoothradio/bluetoothradio.h @@ -6,11 +6,12 @@ typedef struct FFBluetoothRadioResult { FFstrbuf name; FFstrbuf address; - uint8_t lmpVersion; - uint8_t hciVersion; - uint16_t lmpSubversion; - uint16_t hciRevision; + int32_t lmpVersion; + int32_t lmpSubversion; const char* vendor; + bool enabled; + bool discoverable; + bool connectable; } FFBluetoothRadioResult; const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */); diff --git a/src/detection/bluetoothradio/bluetoothradio_apple.m b/src/detection/bluetoothradio/bluetoothradio_apple.m index c68e9eee1..77414a5f6 100644 --- a/src/detection/bluetoothradio/bluetoothradio_apple.m +++ b/src/detection/bluetoothradio/bluetoothradio_apple.m @@ -11,10 +11,11 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothResult */) FFBluetoothRadioResult* device = ffListAdd(devices); ffStrbufInitS(&device->name, ctrl.nameAsString.UTF8String); ffStrbufInitS(&device->address, ctrl.addressAsString.UTF8String); - device->lmpVersion = 0; - device->hciVersion = 0; - device->lmpSubversion = 0; - device->hciRevision = 0; + device->lmpVersion = -1; + device->lmpSubversion = -1; + device->enabled = ctrl.powerState == kBluetoothHCIPowerStateON; + device->discoverable = false; + device->connectable = true; #ifdef __aarch64__ device->vendor = "Apple"; diff --git a/src/detection/bluetoothradio/bluetoothradio_linux.c b/src/detection/bluetoothradio/bluetoothradio_linux.c index a0f44dda0..8a1ac0108 100644 --- a/src/detection/bluetoothradio/bluetoothradio_linux.c +++ b/src/detection/bluetoothradio/bluetoothradio_linux.c @@ -51,8 +51,8 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue DBusMessageIter dictIter; dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter); - // if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING) - // return; + if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING) + return; const char* deviceProperty; dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &deviceProperty); @@ -61,7 +61,7 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue if(ffStrEquals(deviceProperty, "Address")) ffDBusGetString(dbus, &dictIter, &device->address); - else if(ffStrEquals(deviceProperty, "Name")) + else if(ffStrEquals(deviceProperty, "Alias")) ffDBusGetString(dbus, &dictIter, &device->name); else if(ffStrEquals(deviceProperty, "Manufacturer")) { @@ -70,7 +70,17 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue device->vendor = ffBluetoothRadioGetVendor(detection); } else if(ffStrEquals(deviceProperty, "Version")) - ffDBusGetByte(dbus, &dictIter, &device->lmpVersion); + { + uint8_t byte; + if (ffDBusGetByte(dbus, &dictIter, &byte)) + device->lmpVersion = byte; + } + else if(ffStrEquals(deviceProperty, "Powered")) + ffDBusGetBool(dbus, &dictIter, &device->enabled); + else if(ffStrEquals(deviceProperty, "Discoverable")) + ffDBusGetBool(dbus, &dictIter, &device->discoverable); + else if(ffStrEquals(deviceProperty, "Pairable")) + ffDBusGetBool(dbus, &dictIter, &device->connectable); } static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothRadioResult* device) @@ -134,11 +144,10 @@ static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessage FFBluetoothRadioResult* device = ffListAdd(devices); ffStrbufInit(&device->name); ffStrbufInit(&device->address); - device->lmpVersion = 0; - device->hciVersion = 0; - device->lmpSubversion = 0; - device->hciRevision = 0; + device->lmpVersion = -1; + device->lmpSubversion = -1; device->vendor = "Unknown"; + device->enabled = false; while(true) { diff --git a/src/detection/bluetoothradio/bluetoothradio_windows.c b/src/detection/bluetoothradio/bluetoothradio_windows.c index db1d86234..20693c04a 100644 --- a/src/detection/bluetoothradio/bluetoothradio_windows.c +++ b/src/detection/bluetoothradio/bluetoothradio_windows.c @@ -58,6 +58,8 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindFirstRadio) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindNextRadio) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindRadioClose) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothIsConnectable) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothIsDiscoverable) HANDLE hRadio = NULL; HBLUETOOTH_DEVICE_FIND hFind = ffBluetoothFindFirstRadio(&(BLUETOOTH_FIND_RADIO_PARAMS) { @@ -66,7 +68,7 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */) if(!hFind) { if (GetLastError() == ERROR_NO_MORE_ITEMS) - return "No Bluetooth radios found"; + return "No Bluetooth radios found or service disabled"; else return "BluetoothFindFirstRadio() failed"; } @@ -91,9 +93,10 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */) device->lmpVersion = blri.radioInfo.lmpVersion; device->lmpSubversion = blri.radioInfo.lmpSubversion; - device->hciVersion = blri.hciVersion; - device->hciRevision = blri.hciRevision; device->vendor = ffBluetoothRadioGetVendor(blri.radioInfo.mfg); + device->enabled = true; + device->connectable = ffBluetoothIsConnectable(hRadio); + device->discoverable = ffBluetoothIsDiscoverable(hRadio); } while (ffBluetoothFindNextRadio(hFind, &hRadio)); ffBluetoothFindRadioClose(hFind); diff --git a/src/modules/bluetoothradio/bluetoothradio.c b/src/modules/bluetoothradio/bluetoothradio.c index 0d966647e..8adf49e9c 100644 --- a/src/modules/bluetoothradio/bluetoothradio.c +++ b/src/modules/bluetoothradio/bluetoothradio.c @@ -5,7 +5,7 @@ #include "modules/bluetoothradio/bluetoothradio.h" #include "util/stringUtils.h" -#define FF_BLUETOOTHRADIO_NUM_FORMAT_ARGS 6 +#define FF_BLUETOOTHRADIO_NUM_FORMAT_ARGS 8 #define FF_BLUETOOTHRADIO_DISPLAY_NAME "Bluetooth Radio" static void printDevice(FFBluetoothRadioOptions* options, const FFBluetoothRadioResult* radio, uint8_t index) @@ -55,16 +55,15 @@ static void printDevice(FFBluetoothRadioOptions* options, const FFBluetoothRadio } else { - FF_STRBUF_AUTO_DESTROY lmpVersion = ffStrbufCreateF("%u.%u", radio->lmpVersion, radio->lmpSubversion); - FF_STRBUF_AUTO_DESTROY hciVersion = ffStrbufCreateF("%u.%u", radio->hciVersion, radio->hciRevision); - FF_PRINT_FORMAT_CHECKED(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BLUETOOTHRADIO_NUM_FORMAT_ARGS, ((FFformatarg[]) { {FF_FORMAT_ARG_TYPE_STRBUF, &radio->name, "name"}, {FF_FORMAT_ARG_TYPE_STRBUF, &radio->address, "address"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &lmpVersion, "lmp-version"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &hciVersion, "hci-version"}, + {FF_FORMAT_ARG_TYPE_INT, &radio->lmpVersion, "lmp-version"}, + {FF_FORMAT_ARG_TYPE_INT, &radio->lmpSubversion, "lmp-subversion"}, {FF_FORMAT_ARG_TYPE_STRING, version, "version"}, {FF_FORMAT_ARG_TYPE_STRING, radio->vendor, "vendor"}, + {FF_FORMAT_ARG_TYPE_BOOL, &radio->discoverable, "discoverable"}, + {FF_FORMAT_ARG_TYPE_BOOL, &radio->connectable, "connectable"}, })); } } @@ -80,10 +79,22 @@ void ffPrintBluetoothRadio(FFBluetoothRadioOptions* options) } else { - for(uint32_t i = 0; i < radios.length; i++) + uint8_t index = 0; + FF_LIST_FOR_EACH(FFBluetoothRadioResult, radio, radios) { - uint8_t index = (uint8_t) (radios.length == 1 ? 0 : i + 1); - printDevice(options, FF_LIST_GET(FFBluetoothRadioResult, radios, i), index); + if (!radio->enabled) + continue; + + index++; + printDevice(options, radio, index); + } + + if (index == 0) + { + if (radios.length > 0) + ffPrintError(FF_BLUETOOTHRADIO_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Bluetooth radios found but none enabled"); + else + ffPrintError(FF_BLUETOOTHRADIO_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "No devices detected"); } } @@ -147,11 +158,18 @@ void ffGenerateBluetoothRadioJsonResult(FF_MAYBE_UNUSED FFBluetoothRadioOptions* yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr); yyjson_mut_obj_add_strbuf(doc, obj, "name", &item->name); yyjson_mut_obj_add_strbuf(doc, obj, "address", &item->address); - yyjson_mut_obj_add_uint(doc, obj, "lmpVersion", item->lmpVersion); - yyjson_mut_obj_add_uint(doc, obj, "lmpSubversion", item->lmpSubversion); - yyjson_mut_obj_add_uint(doc, obj, "hciVersion", item->hciVersion); - yyjson_mut_obj_add_uint(doc, obj, "hciRevision", item->hciRevision); + if (item->lmpVersion < 0) + yyjson_mut_obj_add_null(doc, obj, "lmpVersion"); + else + yyjson_mut_obj_add_int(doc, obj, "lmpVersion", item->lmpVersion); + if (item->lmpSubversion < 0) + yyjson_mut_obj_add_null(doc, obj, "lmpSubversion"); + else + yyjson_mut_obj_add_int(doc, obj, "lmpSubversion", item->lmpSubversion); yyjson_mut_obj_add_str(doc, obj, "vendor", item->vendor); + yyjson_mut_obj_add_bool(doc, obj, "enabled", item->enabled); + yyjson_mut_obj_add_bool(doc, obj, "discoverable", item->discoverable); + yyjson_mut_obj_add_bool(doc, obj, "connectable", item->connectable); } FF_LIST_FOR_EACH(FFBluetoothRadioResult, radio, results) @@ -167,9 +185,11 @@ void ffPrintBluetoothRadioHelpFormat(void) "Radio name for discovering - name", "Address - local radio address", "LMP version - lmp-version", - "HCI version - hci-version", + "LMP subversion - lmp-subversion", "Bluetooth version - version", "Vendor - vendor", + "Discoverable - discoverable", + "Connectable / Pairable - connectable", })); }