From 909c594d079410c766033b8eee20647b945155c2 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Mon, 19 Aug 2013 12:46:48 +0200 Subject: hidpp: retrieve serial number for devices (v2) Before this, history files were saved as history-rate-M525.dat. Since multiple devices of the same model might be connected, this name is not unique enough. The serial number gives a more reliable path for the history files and allows clients to distinguish their devices (an object path like /org/freedesktop/UPower/devices/mouse_0003o046DoC52Bx0018 does not stay the same). Note: if a serial number cannot be read, instead of reverting this patch, consider splitting the serial refresh from the version, kind and model refresh. - v2: Fix invalid return value when an invalid parameter is passed to hidpp_device_get_serial. Signed-off-by: Peter Wu --- src/linux/hidpp-device.c | 37 +++++++++++++++++++++++++++++++++++++ src/linux/hidpp-device.h | 4 +++- src/linux/up-device-unifying.c | 2 ++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c index 91f99aa..c0a8dc8 100644 --- a/src/linux/hidpp-device.c +++ b/src/linux/hidpp-device.c @@ -153,6 +153,7 @@ struct HidppDevicePrivate HidppDeviceKind kind; int fd; gboolean is_present; + gchar *serial; }; typedef struct { @@ -524,6 +525,16 @@ hidpp_device_get_kind (HidppDevice *device) return device->priv->kind; } +/** + * hidpp_device_get_serial: + **/ +const gchar * +hidpp_device_get_serial (HidppDevice *device) +{ + g_return_val_if_fail (HIDPP_IS_DEVICE (device), NULL); + return device->priv->serial; +} + /** * hidpp_device_is_reachable: **/ @@ -746,6 +757,30 @@ hidpp_device_refresh (HidppDevice *device, } } + /* get serial number, this can be queried from the receiver */ + if ((refresh_flags & HIDPP_REFRESH_FLAGS_SERIAL) > 0) { + guint32 *serialp; + + msg.type = HIDPP_MSG_TYPE_SHORT; + msg.device_idx = HIDPP_RECEIVER_ADDRESS; + msg.feature_idx = HIDPP_READ_LONG_REGISTER; + msg.function_idx = 0xb5; + msg.s.params[0] = 0x30 | (priv->device_idx - 1); + msg.s.params[1] = 0x00; + msg.s.params[2] = 0x00; + + ret = hidpp_device_cmd (device, + &msg, &msg, + error); + if (!ret) + goto out; + + name = g_string_new (""); + serialp = (guint32 *) &msg.l.params[1]; + g_string_printf (name, "%08X", g_ntohl(*serialp)); + priv->serial = g_strdup (name->str); + } + /* get battery status */ if ((refresh_flags & HIDPP_REFRESH_FLAGS_BATTERY) > 0) { if (priv->version == 1) { @@ -918,6 +953,7 @@ hidpp_device_init (HidppDevice *device) device->priv->batt_status = HIDPP_DEVICE_BATT_STATUS_UNKNOWN; device->priv->batt_is_approx = FALSE; device->priv->kind = HIDPP_DEVICE_KIND_UNKNOWN; + device->priv->serial = NULL; /* add known root */ map = g_new0 (HidppDeviceMap, 1); @@ -952,6 +988,7 @@ hidpp_device_finalize (GObject *object) g_free (device->priv->hidraw_device); g_free (device->priv->model); + g_free (device->priv->serial); G_OBJECT_CLASS (hidpp_device_parent_class)->finalize (object); } diff --git a/src/linux/hidpp-device.h b/src/linux/hidpp-device.h index 2934606..fa334f8 100644 --- a/src/linux/hidpp-device.h +++ b/src/linux/hidpp-device.h @@ -69,7 +69,8 @@ typedef enum { HIDPP_REFRESH_FLAGS_KIND = 2, HIDPP_REFRESH_FLAGS_BATTERY = 4, HIDPP_REFRESH_FLAGS_MODEL = 8, - HIDPP_REFRESH_FLAGS_FEATURES = 16 + HIDPP_REFRESH_FLAGS_FEATURES = 16, + HIDPP_REFRESH_FLAGS_SERIAL = 32 } HidppRefreshFlags; GType hidpp_device_get_type (void); @@ -78,6 +79,7 @@ guint hidpp_device_get_batt_percentage (HidppDevice *device); guint hidpp_device_get_version (HidppDevice *device); HidppDeviceBattStatus hidpp_device_get_batt_status (HidppDevice *device); HidppDeviceKind hidpp_device_get_kind (HidppDevice *device); +const gchar *hidpp_device_get_serial (HidppDevice *device); void hidpp_device_set_hidraw_device (HidppDevice *device, const gchar *hidraw_device); void hidpp_device_set_index (HidppDevice *device, diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c index 989ac48..8ebf946 100644 --- a/src/linux/up-device-unifying.c +++ b/src/linux/up-device-unifying.c @@ -246,6 +246,7 @@ up_device_unifying_coldplug (UpDevice *device) ret = hidpp_device_refresh (unifying->priv->hidpp_device, HIDPP_REFRESH_FLAGS_VERSION | HIDPP_REFRESH_FLAGS_KIND | + HIDPP_REFRESH_FLAGS_SERIAL | HIDPP_REFRESH_FLAGS_MODEL, &error); if (!ret) { @@ -264,6 +265,7 @@ up_device_unifying_coldplug (UpDevice *device) "vendor", vendor, "type", up_device_unifying_get_device_kind (unifying), "model", hidpp_device_get_model (unifying->priv->hidpp_device), + "serial", hidpp_device_get_serial (unifying->priv->hidpp_device), "has-history", TRUE, "is-rechargeable", TRUE, "power-supply", FALSE, -- cgit v1.2.1