linux: Parse kind from Class if Appearance is not available

Not all headsets have a GAP profile revealing their appearance, but they
do have a class.
This commit is contained in:
Marijn Suijten 2021-01-19 00:11:16 +01:00
parent e294444496
commit 98cf71fbcc

View file

@ -62,6 +62,94 @@ appearance_to_kind (guint16 appearance)
return UP_DEVICE_KIND_UNKNOWN;
}
/**
* class_to_kind:
* @class: a Bluetooth device class
*
* Returns value: the type of device corresponding to the given @class value.
**/
static UpDeviceKind
class_to_kind (guint32 class)
{
/*
* See Bluetooth Assigned Numbers for Baseband
* https://www.bluetooth.com/specifications/assigned-numbers/baseband/
*/
switch ((class & 0x1f00) >> 8) {
case 0x01:
return UP_DEVICE_KIND_COMPUTER;
case 0x02:
switch ((class & 0xfc) >> 2) {
case 0x01:
case 0x02:
case 0x03:
case 0x05:
return UP_DEVICE_KIND_PHONE;
case 0x04:
return UP_DEVICE_KIND_MODEM;
}
break;
case 0x03:
return UP_DEVICE_KIND_NETWORK;
case 0x04:
switch ((class & 0xfc) >> 2) {
case 0x01:
case 0x02:
return UP_DEVICE_KIND_HEADSET;
case 0x05:
return UP_DEVICE_KIND_SPEAKERS;
case 0x06:
return UP_DEVICE_KIND_HEADPHONES;
case 0x0b: /* VCR */
case 0x0c: /* Video Camera */
case 0x0d: /* Camcorder */
return UP_DEVICE_KIND_VIDEO;
default:
return UP_DEVICE_KIND_OTHER_AUDIO;
}
break;
case 0x05:
switch ((class & 0xc0) >> 6) {
case 0x00:
switch ((class & 0x1e) >> 2) {
case 0x01:
case 0x02:
return UP_DEVICE_KIND_GAMING_INPUT;
case 0x03:
return UP_DEVICE_KIND_REMOTE_CONTROL;
}
break;
case 0x01:
return UP_DEVICE_KIND_KEYBOARD;
case 0x02:
switch ((class & 0x1e) >> 2) {
case 0x05:
return UP_DEVICE_KIND_TABLET;
default:
return UP_DEVICE_KIND_MOUSE;
}
}
break;
case 0x06:
if (class & 0x80)
return UP_DEVICE_KIND_PRINTER;
if (class & 0x40)
return UP_DEVICE_KIND_SCANNER;
if (class & 0x20)
return UP_DEVICE_KIND_CAMERA;
if (class & 0x10)
return UP_DEVICE_KIND_MONITOR;
break;
case 0x07:
return UP_DEVICE_KIND_WEARABLE;
case 0x08:
return UP_DEVICE_KIND_TOY;
}
return UP_DEVICE_KIND_UNKNOWN;
}
/**
* up_device_bluez_coldplug:
*
@ -103,6 +191,12 @@ up_device_bluez_coldplug (UpDevice *device)
appearance = g_variant_get_uint16 (v);
kind = appearance_to_kind (appearance);
g_variant_unref (v);
} else if ((v = g_dbus_proxy_get_cached_property (proxy, "Class"))) {
guint32 class;
class = g_variant_get_uint32 (v);
kind = class_to_kind (class);
g_variant_unref (v);
} else {
kind = UP_DEVICE_KIND_UNKNOWN;
}