1
0
forked from drath/libratbag

tools: ad a hidpp10-dump-page tool to dump a HID++1.0 device's memory

For protocol debugging, it's a lot easier to go have a simple helper than
having to go through the whole of libratbag.

And remove the page-dump helper from the main code.

Note that this tool needs a /dev/hidraw device directly, not an event node. It
is a debugging tool after all.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2015-10-15 11:41:04 +10:00
parent 2186dd90c6
commit 0cb1fe44ad
6 changed files with 136 additions and 28 deletions

1
.gitignore vendored
View File

@@ -47,3 +47,4 @@ test-context
test-device
test-*.log
ratbag-command
hidpp10-dump-page

View File

@@ -1,4 +1,5 @@
lib_LTLIBRARIES = libratbag.la
noinst_LTLIBRARIES = libhidpp10.la
include_HEADERS = \
libratbag.h
@@ -43,3 +44,11 @@ AM_CFLAGS = $(GCC_CFLAGS)
DISTCLEANFILES = libratbag-version.h
EXTRA_DIST = libratbag-version.h.in libratbag.sym
# The hidpp libraries are static libraries only for in-tree tools. No API
# stability is guaranteed here.
libhidpp10_la_SOURCES = \
hidpp-generic.h \
hidpp-generic.c \
hidpp10.h \
hidpp10.c

View File

@@ -193,9 +193,6 @@ out_err:
/* HID++ 1.0 commands 10 */
/* -------------------------------------------------------------------------- */
static inline void
hidpp10_dump_all_pages(struct hidpp10_device *dev);
/* -------------------------------------------------------------------------- */
/* 0x00: Enable HID++ Notifications */
/* -------------------------------------------------------------------------- */
@@ -1035,30 +1032,6 @@ hidpp10_read_memory(struct hidpp10_device *dev, uint8_t page, uint8_t offset,
return 0;
}
static inline void
hidpp10_dump_all_pages(struct hidpp10_device *dev)
{
uint16_t page, offset;
uint8_t bytes[16];
int res;
hidpp_log_info(&dev->base, "::::::: Dumping memory :::::\n");
for (page = 0; page < 512; page++) {
hidpp_log_info(&dev->base, ":: page %d\n", page);
for (offset = 0; offset < 256; offset += 16) {
res = hidpp10_read_memory(dev, page, offset, bytes);
if (res != 0)
goto out;
hidpp_log_buffer(&dev->base, HIDPP_LOG_PRIORITY_INFO, " ", bytes, ARRAY_LENGTH(bytes));
}
}
out:
hidpp_log_info(&dev->base, "::::::: Dumping memory complete :::::\n");
}
/* -------------------------------------------------------------------------- */
/* 0xB2: Device Connection and Disconnection (Pairing) */
/* -------------------------------------------------------------------------- */

View File

@@ -85,6 +85,10 @@ cleanup_free(void *p) {
free(*(void**)p);
}
static inline void
cleanup_close(int *p) {
close(*p);
}
static inline void
cleanup_udev_unref(struct udev **udev) {
if (*udev)
@@ -99,6 +103,7 @@ cleanup_udev_device_unref(struct udev_device **udev_device) {
#define _cleanup_(x) __attribute__((cleanup(x)))
#define _cleanup_free_ _cleanup_(cleanup_free)
#define _cleanup_close_ _cleanup_(cleanup_close)
#define _cleanup_udev_unref_ _cleanup_(cleanup_udev_unref)
#define _cleanup_udev_device_unref_ _cleanup_(cleanup_udev_device_unref)

View File

@@ -1,4 +1,4 @@
noinst_PROGRAMS =
noinst_PROGRAMS = hidpp10-dump-page
bin_PROGRAMS = ratbag-command
noinst_LTLIBRARIES = libshared.la
@@ -16,3 +16,8 @@ ratbag_command_SOURCES = ratbag-command.c
ratbag_command_LDADD = ../src/libratbag.la libshared.la $(LIBUDEV_LIBS) $(LIBEVDEV_LIBS)
ratbag_command_LDFLAGS = -no-install
ratbag_command_CFLAGS = $(LIBUDEV_CFLAGS) $(LIBEVDEV_CFLAGS)
hidpp10_dump_page_SOURCES = hidpp10-dump-page.c
hidpp10_dump_page_LDADD = ../src/libhidpp10.la
hidpp10_dump_page_LDFLAGS = -no-install
hidpp10_dump_page_CFLAGS = -I$(top_srcdir)/src

115
tools/hidpp10-dump-page.c Normal file
View File

@@ -0,0 +1,115 @@
/*
* Copyright © 2015 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <config.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <hidpp10.h>
#include <libratbag-util.h>
static inline int
dump_page(struct hidpp10_device *dev, size_t page, size_t offset)
{
int rc = 0;
uint8_t bytes[16];
while (offset < 256) {
hidpp_log_info(&dev->base, "page 0x%02zx off 0x%02zx: ", page, offset);
rc = hidpp10_read_memory(dev, page, offset, bytes);
if (rc != 0)
break;
hidpp_log_buffer(&dev->base, HIDPP_LOG_PRIORITY_INFO, " ", bytes, ARRAY_LENGTH(bytes));
offset += 16;
}
return rc;
}
static inline int
dump_all_pages(struct hidpp10_device *dev)
{
uint8_t page;
int rc = 0;
for (page = 0; page < 31; page++) {
rc = dump_page(dev, page, 0);
if (rc != 0)
break;
}
/* We dumped at least one page successfully and get EAGAIN, so we're
* on the last page. Overwrite the last line with a blank one so it
* doesn't look like an error */
if (page > 0 && rc == EAGAIN) {
hidpp_log_info(&dev->base, "\r \n");
rc = 0;
}
return rc;
}
void
usage(void)
{
printf("Usage: %s [page] [offset] /dev/hidraw0\n", program_invocation_short_name);
}
int
main(int argc, char **argv)
{
_cleanup_close_ int fd;
const char *path;
size_t page = 0, offset = 0;
struct hidpp10_device *dev = NULL;
struct hidpp_device base;
int rc;
if (argc < 2 || argc > 4) {
usage();
return 1;
}
path = argv[argc - 1];
fd = open(path, O_RDWR);
if (fd < 0)
error(1, errno, "Failed to open path %s", path);
hidpp_device_init(&base, fd);
dev = hidpp10_device_new_from_idx(&base, WIRED_DEVICE_IDX);
if (argc == 2)
rc = dump_all_pages(dev);
else {
page = atoi(argv[1]);
if (argc > 3)
offset = atoi(argv[2]);
rc = dump_page(dev, page, offset);
}
hidpp10_device_destroy(dev);
return rc;
}