mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-14 02:40:34 +00:00
unifying: Only call HID++2.0 features on version 2+ devices
Also, ignore HID++1.0 replies from HID++2.0 devices and use the correct function ID for getDfuStatus to avoid an error.
This commit is contained in:
parent
e97c5eb013
commit
2c1bd0236c
@ -110,58 +110,62 @@ lu_device_peripheral_fetch_firmware_info (LuDevice *device, GError **error)
|
||||
static gboolean
|
||||
lu_device_peripheral_fetch_battery_level (LuDevice *device, GError **error)
|
||||
{
|
||||
guint8 idx;
|
||||
g_autoptr(LuDeviceHidppMsg) msg = lu_device_hidpp_new ();
|
||||
|
||||
/* try using HID++2.0 */
|
||||
idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_BATTERY_LEVEL_STATUS);
|
||||
if (idx != 0x00) {
|
||||
msg->report_id = HIDPP_REPORT_ID_SHORT;
|
||||
msg->device_id = lu_device_get_hidpp_id (device);
|
||||
msg->sub_id = idx;
|
||||
msg->function_id = 0x00; /* GetBatteryLevelStatus */
|
||||
if (!lu_device_hidpp_transfer (device, msg, error)) {
|
||||
g_prefix_error (error, "failed to get battery info: ");
|
||||
return FALSE;
|
||||
if (lu_device_get_hidpp_version (device) >= 2) {
|
||||
guint8 idx;
|
||||
idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_BATTERY_LEVEL_STATUS);
|
||||
if (idx != 0x00) {
|
||||
g_autoptr(LuDeviceHidppMsg) msg = lu_device_hidpp_new ();
|
||||
msg->report_id = HIDPP_REPORT_ID_SHORT;
|
||||
msg->device_id = lu_device_get_hidpp_id (device);
|
||||
msg->sub_id = idx;
|
||||
msg->function_id = 0x00; /* GetBatteryLevelStatus */
|
||||
if (!lu_device_hidpp_transfer (device, msg, error)) {
|
||||
g_prefix_error (error, "failed to get battery info: ");
|
||||
return FALSE;
|
||||
}
|
||||
if (msg->data[0] != 0x00)
|
||||
lu_device_set_battery_level (device, msg->data[0]);
|
||||
return TRUE;
|
||||
}
|
||||
if (msg->data[0] != 0x00)
|
||||
lu_device_set_battery_level (device, msg->data[0]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* try HID++1.0 battery mileage */
|
||||
msg->report_id = HIDPP_REPORT_ID_SHORT;
|
||||
msg->device_id = lu_device_get_hidpp_id (device);
|
||||
msg->sub_id = HIDPP_SUBID_GET_REGISTER;
|
||||
msg->function_id = HIDPP_REGISTER_BATTERY_MILEAGE;
|
||||
if (lu_device_hidpp_transfer (device, msg, NULL)) {
|
||||
if (msg->data[0] != 0x00)
|
||||
lu_device_set_battery_level (device, msg->data[0]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* try HID++1.0 battery status instead */
|
||||
msg->function_id = HIDPP_REGISTER_BATTERY_STATUS;
|
||||
if (lu_device_hidpp_transfer (device, msg, NULL)) {
|
||||
switch (msg->data[0]) {
|
||||
case 1: /* 0 - 10 */
|
||||
lu_device_set_battery_level (device, 5);
|
||||
break;
|
||||
case 3: /* 11 - 30 */
|
||||
lu_device_set_battery_level (device, 20);
|
||||
break;
|
||||
case 5: /* 31 - 80 */
|
||||
lu_device_set_battery_level (device, 55);
|
||||
break;
|
||||
case 7: /* 81 - 100 */
|
||||
lu_device_set_battery_level (device, 90);
|
||||
break;
|
||||
default:
|
||||
g_warning ("unknown battery percentage: 0x%02x",
|
||||
msg->data[0]);
|
||||
break;
|
||||
if (lu_device_get_hidpp_version (device) == 1) {
|
||||
g_autoptr(LuDeviceHidppMsg) msg = lu_device_hidpp_new ();
|
||||
msg->report_id = HIDPP_REPORT_ID_SHORT;
|
||||
msg->device_id = lu_device_get_hidpp_id (device);
|
||||
msg->sub_id = HIDPP_SUBID_GET_REGISTER;
|
||||
msg->function_id = HIDPP_REGISTER_BATTERY_MILEAGE;
|
||||
if (lu_device_hidpp_transfer (device, msg, NULL)) {
|
||||
if (msg->data[0] != 0x00)
|
||||
lu_device_set_battery_level (device, msg->data[0]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* try HID++1.0 battery status instead */
|
||||
msg->function_id = HIDPP_REGISTER_BATTERY_STATUS;
|
||||
if (lu_device_hidpp_transfer (device, msg, NULL)) {
|
||||
switch (msg->data[0]) {
|
||||
case 1: /* 0 - 10 */
|
||||
lu_device_set_battery_level (device, 5);
|
||||
break;
|
||||
case 3: /* 11 - 30 */
|
||||
lu_device_set_battery_level (device, 20);
|
||||
break;
|
||||
case 5: /* 31 - 80 */
|
||||
lu_device_set_battery_level (device, 55);
|
||||
break;
|
||||
case 7: /* 81 - 100 */
|
||||
lu_device_set_battery_level (device, 90);
|
||||
break;
|
||||
default:
|
||||
g_warning ("unknown battery percentage: 0x%02x",
|
||||
msg->data[0]);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* not an error, the device just doesn't support any of the methods */
|
||||
@ -240,6 +244,12 @@ lu_device_peripheral_probe (LuDevice *device, GError **error)
|
||||
map_features[i],
|
||||
&error_local)) {
|
||||
g_debug ("%s", error_local->message);
|
||||
if (g_error_matches (error_local,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_TIMED_OUT)) {
|
||||
/* timed out, so not trying any more */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,7 +274,7 @@ lu_device_peripheral_probe (LuDevice *device, GError **error)
|
||||
msg->report_id = HIDPP_REPORT_ID_SHORT;
|
||||
msg->device_id = lu_device_get_hidpp_id (device);
|
||||
msg->sub_id = idx;
|
||||
msg->function_id = 0x01 << 4; /* getDfuStatus */
|
||||
msg->function_id = 0x00 << 4; /* getDfuStatus */
|
||||
if (!lu_device_hidpp_transfer (device, msg, error)) {
|
||||
g_prefix_error (error, "failed to get DFU status: ");
|
||||
return FALSE;
|
||||
|
@ -129,17 +129,85 @@ lu_device_hidpp_new (void)
|
||||
#define HIDPP_REPORT_04 0x04
|
||||
#define HIDPP_REPORT_20 0x20
|
||||
|
||||
static void
|
||||
hidpp_device_map_print (LuDevice *device)
|
||||
static gchar *
|
||||
lu_device_flags_to_string (LuDeviceFlags flags)
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
if (flags & LU_DEVICE_FLAG_REQUIRES_SIGNED_FIRMWARE)
|
||||
g_string_append (str, "signed-firmware,");
|
||||
if (flags & LU_DEVICE_FLAG_CAN_FLASH)
|
||||
g_string_append (str, "can-flash,");
|
||||
if (flags & LU_DEVICE_FLAG_REQUIRES_RESET)
|
||||
g_string_append (str, "requires-reset,");
|
||||
if (flags & LU_DEVICE_FLAG_ACTIVE)
|
||||
g_string_append (str, "active,");
|
||||
if (flags & LU_DEVICE_FLAG_IS_OPEN)
|
||||
g_string_append (str, "is-open,");
|
||||
if (flags & LU_DEVICE_FLAG_REQUIRES_ATTACH)
|
||||
g_string_append (str, "requires-attach,");
|
||||
if (flags & LU_DEVICE_FLAG_REQUIRES_DETACH)
|
||||
g_string_append (str, "requires-detach,");
|
||||
if (flags & LU_DEVICE_FLAG_DETACH_WILL_REPLUG)
|
||||
g_string_append (str, "detach-will-replug,");
|
||||
if (str->len == 0) {
|
||||
g_string_append (str, "none");
|
||||
} else {
|
||||
g_string_truncate (str, str->len - 1);
|
||||
}
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
gchar *
|
||||
lu_device_to_string (LuDevice *device)
|
||||
{
|
||||
LuDevicePrivate *priv = GET_PRIVATE (device);
|
||||
GString *str = g_string_new (NULL);
|
||||
g_autofree gchar *flags_str = NULL;
|
||||
|
||||
g_string_append_printf (str, "type:\t\t\t%s\n", lu_device_kind_to_string (priv->kind));
|
||||
flags_str = lu_device_flags_to_string (priv->flags);
|
||||
g_string_append_printf (str, "flags:\t\t\t%s\n", flags_str);
|
||||
g_string_append_printf (str, "hidpp-version:\t\t%u\n", priv->hidpp_version);
|
||||
if (priv->hidpp_id != HIDPP_DEVICE_ID_UNSET)
|
||||
g_string_append_printf (str, "hidpp-id:\t\t0x%02x\n", (guint) priv->hidpp_id);
|
||||
if (priv->udev_device_fd > 0)
|
||||
g_string_append_printf (str, "udev-device:\t\t%i\n", priv->udev_device_fd);
|
||||
if (priv->usb_device != NULL)
|
||||
g_string_append_printf (str, "usb-device:\t\t%p\n", priv->usb_device);
|
||||
if (priv->platform_id != NULL)
|
||||
g_string_append_printf (str, "platform-id:\t\t%s\n", priv->platform_id);
|
||||
if (priv->vendor != NULL)
|
||||
g_string_append_printf (str, "vendor:\t\t\t%s\n", priv->vendor);
|
||||
if (priv->product != NULL)
|
||||
g_string_append_printf (str, "product:\t\t%s\n", priv->product);
|
||||
if (priv->version_bl != NULL)
|
||||
g_string_append_printf (str, "version-bootloader:\t%s\n", priv->version_bl);
|
||||
if (priv->version_fw != NULL)
|
||||
g_string_append_printf (str, "version-firmware:\t%s\n", priv->version_fw);
|
||||
for (guint i = 0; i < priv->guids->len; i++) {
|
||||
const gchar *guid = g_ptr_array_index (priv->guids, i);
|
||||
g_string_append_printf (str, "guid:\t\t\t%s\n", guid);
|
||||
}
|
||||
if (priv->battery_level != 0)
|
||||
g_string_append_printf (str, "battery-level:\t\t%u\n", priv->battery_level);
|
||||
for (guint i = 0; i < priv->feature_index->len; i++) {
|
||||
LuDeviceHidppMap *map = g_ptr_array_index (priv->feature_index, i);
|
||||
g_debug ("%02x\t[%04x] %s",
|
||||
map->idx,
|
||||
map->feature,
|
||||
lu_hidpp_feature_to_string (map->feature));
|
||||
g_string_append_printf (str, "feature%02x:\t\t%s [0x%04x]\n",
|
||||
map->idx,
|
||||
lu_hidpp_feature_to_string (map->feature),
|
||||
map->feature);
|
||||
}
|
||||
|
||||
/* fixme: superclass? */
|
||||
if (LU_IS_DEVICE_BOOTLOADER (device)) {
|
||||
g_string_append_printf (str, "flash-addr-high:\t0x%04x\n",
|
||||
lu_device_bootloader_get_addr_hi (device));
|
||||
g_string_append_printf (str, "flash-addr-low:\t0x%04x\n",
|
||||
lu_device_bootloader_get_addr_lo (device));
|
||||
g_string_append_printf (str, "flash-block-size:\t0x%04x\n",
|
||||
lu_device_bootloader_get_blocksize (device));
|
||||
}
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
guint8
|
||||
@ -304,57 +372,47 @@ lu_device_hidpp_receive (LuDevice *device,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* this is likely an errata somewhere */
|
||||
if (lu_device_get_kind (device) == LU_DEVICE_KIND_PERIPHERAL) {
|
||||
const guint8 bytes[] = { 0x11, 0x02, 0xff, 0x11, 0x17 };
|
||||
if (memcmp (msg, bytes, 5) == 0) {
|
||||
guint8 *buf = (guint8 *) msg;
|
||||
g_debug ("FIXME: using 0xff errata");
|
||||
for (guint i = 2; i < read_size; i++)
|
||||
buf[i] = buf[i + 1];
|
||||
lu_device_hidpp_dump (device, "device->host", buf, read_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
lu_device_hidpp_transfer (LuDevice *device, LuDeviceHidppMsg *msg, GError **error)
|
||||
static gboolean
|
||||
lu_device_hidpp_msg_is_hidpp_10 (LuDeviceHidppMsg *msg)
|
||||
{
|
||||
LuDevicePrivate *priv = GET_PRIVATE (device);
|
||||
guint timeout = LU_DEVICE_TIMEOUT_MS;
|
||||
g_autoptr(LuDeviceHidppMsg) msg_tmp = lu_device_hidpp_new ();
|
||||
/* filter HID++1.0 messages */
|
||||
if (msg->sub_id == 0x40 ||
|
||||
msg->sub_id == 0x41 ||
|
||||
msg->sub_id == 0x49 ||
|
||||
msg->sub_id == 0x4b ||
|
||||
msg->sub_id == 0x8f) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* increase timeout for some operations */
|
||||
if (msg->flags & LU_DEVICE_HIDPP_MSG_FLAG_LONGER_TIMEOUT)
|
||||
timeout *= 5;
|
||||
|
||||
/* send */
|
||||
if (!lu_device_hidpp_send (device, msg, timeout, error))
|
||||
static gboolean
|
||||
lu_device_hidpp_msg_check_swid (LuDeviceHidppMsg *msg, LuDeviceHidppMsg *msg_tmp)
|
||||
{
|
||||
if ((msg_tmp->function_id & 0x0f) != FU_DEVICE_UNIFYING_SW_ID)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* keep trying to receive until we get a valid reply */
|
||||
while (1) {
|
||||
if (!lu_device_hidpp_receive (device, msg_tmp, timeout, error))
|
||||
return FALSE;
|
||||
|
||||
/* not us */
|
||||
if (lu_device_get_hidpp_version (device) >= 2 &&
|
||||
(msg->flags & LU_DEVICE_HIDPP_MSG_FLAG_IGNORE_SWID) == 0) {
|
||||
if ((msg_tmp->function_id & 0x0f) != FU_DEVICE_UNIFYING_SW_ID) {
|
||||
g_debug ("ignoring reply with SwId 0x%02i, expected 0x%02i",
|
||||
msg_tmp->function_id & 0x0f,
|
||||
FU_DEVICE_UNIFYING_SW_ID);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (msg_tmp->report_id == 0x10 || msg_tmp->report_id == 0x11)
|
||||
break;
|
||||
g_debug ("ignoring message with report 0x%02x", msg_tmp->report_id);
|
||||
};
|
||||
static gboolean
|
||||
lu_device_hidpp_msg_is_error (LuDevice *device,
|
||||
LuDeviceHidppMsg *msg,
|
||||
LuDeviceHidppMsg *msg_tmp,
|
||||
GError **error)
|
||||
{
|
||||
/* wrong device ID reported */
|
||||
if (msg->device_id != HIDPP_DEVICE_ID_UNSET &&
|
||||
msg->device_id != msg_tmp->device_id) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"invalid device_id response");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* kernel not doing it's thing */
|
||||
if (msg_tmp->device_id == HIDPP_DEVICE_ID_UNSET) {
|
||||
@ -365,12 +423,6 @@ lu_device_hidpp_transfer (LuDevice *device, LuDeviceHidppMsg *msg, GError **erro
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* if the HID++ ID is unset, grab it from the reply */
|
||||
if (priv->hidpp_id == HIDPP_DEVICE_ID_UNSET) {
|
||||
priv->hidpp_id = msg_tmp->device_id;
|
||||
g_debug ("HID++ ID now %02x", priv->hidpp_id);
|
||||
}
|
||||
|
||||
/* HID++ 1.0 error */
|
||||
if (msg_tmp->sub_id == HIDPP_SUBID_ERROR_MSG) {
|
||||
const gchar *tmp;
|
||||
@ -461,6 +513,63 @@ lu_device_hidpp_transfer (LuDevice *device, LuDeviceHidppMsg *msg, GError **erro
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* HID++ 2.0 error */
|
||||
if (msg_tmp->sub_id == HIDPP_SUBID_ERROR_MSG_20) {
|
||||
|
||||
switch (msg_tmp->data[1]) {
|
||||
case HIDPP_ERROR_CODE_INVALID_ARGUMENT:
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_ARGUMENT,
|
||||
"Invalid argument 0x%02x",
|
||||
msg_tmp->data[2]);
|
||||
break;
|
||||
case HIDPP_ERROR_CODE_OUT_OF_RANGE:
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_DATA,
|
||||
"out of range");
|
||||
break;
|
||||
case HIDPP_ERROR_CODE_HW_ERROR:
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_BROKEN_PIPE,
|
||||
"hardware error");
|
||||
break;
|
||||
case HIDPP_ERROR_CODE_INVALID_FEATURE_INDEX:
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_ARGUMENT,
|
||||
"invalid feature index");
|
||||
break;
|
||||
case HIDPP_ERROR_CODE_INVALID_FUNCTION_ID:
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_ARGUMENT,
|
||||
"invalid function ID");
|
||||
break;
|
||||
case HIDPP_ERROR_CODE_BUSY:
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_BUSY,
|
||||
"busy");
|
||||
break;
|
||||
case HIDPP_ERROR_CODE_UNSUPPORTED:
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"unsupported");
|
||||
break;
|
||||
default:
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"generic failure");
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check the response was valid */
|
||||
if (0&&msg->report_id != msg_tmp->report_id) {
|
||||
g_set_error_literal (error,
|
||||
@ -469,22 +578,78 @@ lu_device_hidpp_transfer (LuDevice *device, LuDeviceHidppMsg *msg, GError **erro
|
||||
"invalid report_id response");
|
||||
return FALSE;
|
||||
}
|
||||
if (msg->device_id != HIDPP_DEVICE_ID_UNSET &&
|
||||
msg->device_id != msg_tmp->device_id) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"invalid device_id response");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* copy over data */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
lu_device_hidpp_msg_copy (LuDeviceHidppMsg *msg, LuDeviceHidppMsg *msg_tmp)
|
||||
{
|
||||
memset (msg->data, 0x00, sizeof(msg->data));
|
||||
msg->device_id = msg_tmp->device_id;
|
||||
msg->sub_id = msg_tmp->sub_id;
|
||||
msg->function_id = msg_tmp->function_id;
|
||||
memcpy (msg->data, msg_tmp->data, sizeof(msg->data));
|
||||
}
|
||||
|
||||
gboolean
|
||||
lu_device_hidpp_transfer (LuDevice *device, LuDeviceHidppMsg *msg, GError **error)
|
||||
{
|
||||
LuDevicePrivate *priv = GET_PRIVATE (device);
|
||||
guint timeout = LU_DEVICE_TIMEOUT_MS;
|
||||
g_autoptr(LuDeviceHidppMsg) msg_tmp = lu_device_hidpp_new ();
|
||||
|
||||
/* increase timeout for some operations */
|
||||
if (msg->flags & LU_DEVICE_HIDPP_MSG_FLAG_LONGER_TIMEOUT)
|
||||
timeout *= 5;
|
||||
|
||||
/* send request */
|
||||
if (!lu_device_hidpp_send (device, msg, timeout, error))
|
||||
return FALSE;
|
||||
|
||||
/* keep trying to receive until we get a valid reply */
|
||||
while (1) {
|
||||
if (!lu_device_hidpp_receive (device, msg_tmp, timeout, error))
|
||||
return FALSE;
|
||||
|
||||
/* to ensure compatibility when an HID++ 2.0 device is
|
||||
* connected to an HID++ 1.0 receiver, any feature index
|
||||
* corresponding to an HID++ 1.0 sub-identifier which could be
|
||||
* sent by the receiver, must be assigned to a dummy feature */
|
||||
if (lu_device_get_hidpp_version (device) >= 2 &&
|
||||
lu_device_hidpp_msg_is_hidpp_10 (msg_tmp)) {
|
||||
g_debug ("ignoring HID++1.0 reply");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* is error */
|
||||
if (!lu_device_hidpp_msg_is_error (device, msg, msg_tmp, error))
|
||||
return FALSE;
|
||||
|
||||
/* not us */
|
||||
if (lu_device_get_hidpp_version (device) >= 2 &&
|
||||
(msg->flags & LU_DEVICE_HIDPP_MSG_FLAG_IGNORE_SWID) == 0) {
|
||||
if (!lu_device_hidpp_msg_check_swid (msg, msg_tmp)) {
|
||||
g_debug ("ignoring reply with SwId 0x%02i, expected 0x%02i",
|
||||
msg_tmp->function_id & 0x0f,
|
||||
FU_DEVICE_UNIFYING_SW_ID);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (msg_tmp->report_id == 0x10 || msg_tmp->report_id == 0x11)
|
||||
break;
|
||||
g_debug ("ignoring message with report 0x%02x", msg_tmp->report_id);
|
||||
};
|
||||
|
||||
/* if the HID++ ID is unset, grab it from the reply */
|
||||
if (priv->hidpp_id == HIDPP_DEVICE_ID_UNSET) {
|
||||
priv->hidpp_id = msg_tmp->device_id;
|
||||
g_debug ("HID++ ID now %02x", priv->hidpp_id);
|
||||
}
|
||||
|
||||
/* copy over data */
|
||||
lu_device_hidpp_msg_copy (msg, msg_tmp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -732,6 +897,7 @@ lu_device_open (LuDevice *device, GError **error)
|
||||
{
|
||||
LuDeviceClass *klass = LU_DEVICE_GET_CLASS (device);
|
||||
LuDevicePrivate *priv = GET_PRIVATE (device);
|
||||
g_autofree gchar *device_str = NULL;
|
||||
|
||||
g_return_val_if_fail (LU_IS_DEVICE (device), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
@ -797,8 +963,9 @@ lu_device_open (LuDevice *device, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* show the HID++2.0 features we found */
|
||||
hidpp_device_map_print (device);
|
||||
/* show the device */
|
||||
device_str = lu_device_to_string (device);
|
||||
g_debug ("%s", device_str);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
|
@ -119,6 +119,7 @@ LuDeviceHidppMsg *lu_device_hidpp_new (void);
|
||||
LuDeviceKind lu_device_kind_from_string (const gchar *kind);
|
||||
const gchar *lu_device_kind_to_string (LuDeviceKind kind);
|
||||
|
||||
gchar *lu_device_to_string (LuDevice *device);
|
||||
LuDeviceKind lu_device_get_kind (LuDevice *device);
|
||||
guint8 lu_device_get_hidpp_id (LuDevice *device);
|
||||
void lu_device_set_hidpp_id (LuDevice *device,
|
||||
|
@ -45,6 +45,7 @@ G_BEGIN_DECLS
|
||||
#define HIDPP_SUBID_SET_LONG_REGISTER 0x82
|
||||
#define HIDPP_SUBID_GET_LONG_REGISTER 0x83
|
||||
#define HIDPP_SUBID_ERROR_MSG 0x8F
|
||||
#define HIDPP_SUBID_ERROR_MSG_20 0xFF
|
||||
|
||||
#define HIDPP_ERR_SUCCESS 0x00
|
||||
#define HIDPP_ERR_INVALID_SUBID 0x01
|
||||
|
@ -198,86 +198,11 @@ lu_get_default_device (FuLuToolPrivate *priv, GError **error)
|
||||
return device;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
lu_device_flags_to_string (LuDeviceFlags flags)
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
if (flags & LU_DEVICE_FLAG_REQUIRES_SIGNED_FIRMWARE)
|
||||
g_string_append (str, "signed-firmware,");
|
||||
if (flags & LU_DEVICE_FLAG_CAN_FLASH)
|
||||
g_string_append (str, "can-flash,");
|
||||
if (flags & LU_DEVICE_FLAG_REQUIRES_RESET)
|
||||
g_string_append (str, "requires-reset,");
|
||||
if (flags & LU_DEVICE_FLAG_ACTIVE)
|
||||
g_string_append (str, "active,");
|
||||
if (flags & LU_DEVICE_FLAG_IS_OPEN)
|
||||
g_string_append (str, "is-open,");
|
||||
if (flags & LU_DEVICE_FLAG_REQUIRES_ATTACH)
|
||||
g_string_append (str, "requires-attach,");
|
||||
if (flags & LU_DEVICE_FLAG_REQUIRES_DETACH)
|
||||
g_string_append (str, "requires-detach,");
|
||||
if (flags & LU_DEVICE_FLAG_DETACH_WILL_REPLUG)
|
||||
g_string_append (str, "detach-will-replug,");
|
||||
if (str->len == 0) {
|
||||
g_string_append (str, "none");
|
||||
} else {
|
||||
g_string_truncate (str, str->len - 1);
|
||||
}
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
lu_tool_info_device (FuLuToolPrivate *priv, LuDevice *device, GError **error)
|
||||
lu_tool_info_device (LuDevice *device)
|
||||
{
|
||||
GPtrArray *guids;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
|
||||
/* show on console */
|
||||
g_print ("Type: %s\n",
|
||||
lu_device_kind_to_string (lu_device_get_kind (device)));
|
||||
g_print ("Flags: %s\n",
|
||||
lu_device_flags_to_string (lu_device_get_flags (device)));
|
||||
if (lu_device_get_hidpp_id (device) != HIDPP_DEVICE_ID_UNSET) {
|
||||
g_print ("Hid++ ID: 0x%02x\n",
|
||||
lu_device_get_hidpp_id (device));
|
||||
}
|
||||
if (lu_device_get_hidpp_version (device) != 0) {
|
||||
g_print ("Hid++ Version: 0x%02x\n",
|
||||
lu_device_get_hidpp_version (device));
|
||||
}
|
||||
g_print ("Platform ID: %s\n",
|
||||
lu_device_get_platform_id (device));
|
||||
g_print ("Vendor: %s\n",
|
||||
lu_device_get_vendor (device));
|
||||
g_print ("Product: %s\n",
|
||||
lu_device_get_product (device));
|
||||
if (lu_device_get_battery_level (device) != 0) {
|
||||
g_print ("Battery Level: %u%%\n",
|
||||
lu_device_get_battery_level (device));
|
||||
}
|
||||
if (lu_device_get_version_fw (device) != NULL) {
|
||||
g_print ("Firmware Ver: %s\n",
|
||||
lu_device_get_version_fw (device));
|
||||
}
|
||||
if (lu_device_get_version_bl (device) != NULL) {
|
||||
g_print ("Bootloader Ver: %s\n",
|
||||
lu_device_get_version_bl (device));
|
||||
}
|
||||
if (LU_IS_DEVICE_BOOTLOADER (device)) {
|
||||
g_print ("Flash Addr Hi: 0x%04x\n",
|
||||
lu_device_bootloader_get_addr_hi (device));
|
||||
g_print ("Flash Addr Lo: 0x%04x\n",
|
||||
lu_device_bootloader_get_addr_lo (device));
|
||||
g_print ("Flash Block Sz: 0x%04x\n",
|
||||
lu_device_bootloader_get_blocksize (device));
|
||||
}
|
||||
guids = lu_device_get_guids (device);
|
||||
for (guint i = 0; i < guids->len; i++) {
|
||||
const gchar *guid = g_ptr_array_index (guids, i);
|
||||
g_print ("GUID: %s\n", guid);
|
||||
}
|
||||
|
||||
/* do not need to close device */
|
||||
g_autofree gchar *str = lu_device_to_string (device);
|
||||
g_print ("%s", str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -291,8 +216,7 @@ lu_tool_info (FuLuToolPrivate *priv, gchar **values, GError **error)
|
||||
if (priv->emulation_kind != LU_DEVICE_KIND_UNKNOWN) {
|
||||
g_autoptr(LuDevice) device = NULL;
|
||||
device = lu_device_fake_new (priv->emulation_kind);
|
||||
if (!lu_tool_info_device (priv, device, error))
|
||||
return FALSE;
|
||||
lu_tool_info_device (device);
|
||||
}
|
||||
|
||||
/* get the devices */
|
||||
@ -304,8 +228,7 @@ lu_tool_info (FuLuToolPrivate *priv, gchar **values, GError **error)
|
||||
devices = lu_context_get_devices (ctx);
|
||||
for (guint i = 0; i < devices->len; i++) {
|
||||
LuDevice *device = g_ptr_array_index (devices, i);
|
||||
if (!lu_tool_info_device (priv, device, error))
|
||||
return FALSE;
|
||||
lu_tool_info_device (device);
|
||||
if (i != devices->len - 1)
|
||||
g_print ("\n");
|
||||
}
|
||||
@ -467,8 +390,7 @@ lu_tool_device_added_cb (LuContext* ctx, LuDevice *device, FuLuToolPrivate *priv
|
||||
g_print ("ADDED\tLogitech Unifying device %s {%p} [%s]\n",
|
||||
lu_device_kind_to_string (lu_device_get_kind (device)),
|
||||
device, lu_device_get_platform_id (device));
|
||||
if (!lu_tool_info_device (priv, device, &error))
|
||||
g_print ("Failed to open: %s\n", error->message);
|
||||
lu_tool_info_device (device);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user