summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2013-08-19 12:46:48 +0200
committerPeter Wu <lekensteyn@gmail.com>2013-08-22 22:59:27 +0200
commit909c594d079410c766033b8eee20647b945155c2 (patch)
treed144f8893d0a3a732267df544018808d104a201c
parent180faa686fd4f1e507b22e1751afcaf563263bc3 (diff)
downloadupower-909c594d079410c766033b8eee20647b945155c2.tar.gz
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 <lekensteyn@gmail.com>
-rw-r--r--src/linux/hidpp-device.c37
-rw-r--r--src/linux/hidpp-device.h4
-rw-r--r--src/linux/up-device-unifying.c2
3 files changed, 42 insertions, 1 deletions
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 {
@@ -525,6 +526,16 @@ hidpp_device_get_kind (HidppDevice *device)
}
/**
+ * 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:
**/
gboolean
@@ -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,