From bdba9990fb0ff74af06c41c1a2b496b6372442d1 Mon Sep 17 00:00:00 2001
From: Bastien Nocera <hadess@hadess.net>
Date: Wed, 19 Sep 2018 16:33:03 +0200
Subject: [PATCH] lib: Add libusb allocation helper

---
 doc/libfprint-docs.xml     |  1 +
 doc/libfprint-sections.txt |  6 +++
 libfprint/drivers_api.h    |  2 +-
 libfprint/fpi-usb.c        | 77 ++++++++++++++++++++++++++++++++++++++
 libfprint/fpi-usb.h        | 27 +++++++++++++
 libfprint/meson.build      |  2 +
 6 files changed, 114 insertions(+), 1 deletion(-)
 create mode 100644 libfprint/fpi-usb.c
 create mode 100644 libfprint/fpi-usb.h

diff --git a/doc/libfprint-docs.xml b/doc/libfprint-docs.xml
index 6d705e5..68543c6 100644
--- a/doc/libfprint-docs.xml
+++ b/doc/libfprint-docs.xml
@@ -42,6 +42,7 @@
     <xi:include href="xml/fpi-dev.xml"/>
     <xi:include href="xml/fpi-ssm.xml"/>
     <xi:include href="xml/fpi-poll.xml"/>
+    <xi:include href="xml/fpi-usb.xml"/>
   </part>
 
   <index id="api-index">
diff --git a/doc/libfprint-sections.txt b/doc/libfprint-sections.txt
index aeaef13..6b02bcd 100644
--- a/doc/libfprint-sections.txt
+++ b/doc/libfprint-sections.txt
@@ -193,3 +193,9 @@ FP_IMG_DEV
 fp_dev_set_instance_data
 FP_INSTANCE_DATA
 </SECTION>
+
+<SECTION>
+<INCLUDE>fpi-usb.h</INCLUDE>
+<FILE>fpi-usb</FILE>
+fpi_usb_alloc
+</SECTION>
diff --git a/libfprint/drivers_api.h b/libfprint/drivers_api.h
index 034c174..a567c3c 100644
--- a/libfprint/drivers_api.h
+++ b/libfprint/drivers_api.h
@@ -27,13 +27,13 @@
 #include <string.h>
 #include <stdlib.h>
 #include <glib.h>
-#include <libusb.h>
 
 #include "fprint.h"
 #include "fpi-log.h"
 #include "fpi-ssm.h"
 #include "fpi-poll.h"
 #include "fpi-dev.h"
+#include "fpi-usb.h"
 #include "assembling.h"
 #include "drivers/driver_ids.h"
 
diff --git a/libfprint/fpi-usb.c b/libfprint/fpi-usb.c
new file mode 100644
index 0000000..1b8a92e
--- /dev/null
+++ b/libfprint/fpi-usb.c
@@ -0,0 +1,77 @@
+/*
+ * Driver API definitions
+ * Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "fpi-usb.h"
+
+/**
+ * SECTION:fpi-usb
+ * @title: Helpers for libusb
+ *
+ * A collection of [libusb helpers](http://libusb.sourceforge.net/api-1.0/group__poll.html#details)
+ * to make driver development easier. Please refer to the libusb API documentation for more
+ * information about the original API.
+ */
+
+/* Helpers from glib */
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* special helpers to avoid gmessage.c dependency */
+static void mem_error (const char *format, ...) G_GNUC_PRINTF (1,2);
+#define mem_assert(cond)    do { if (G_LIKELY (cond)) ; else mem_error ("assertion failed: %s", #cond); } while (0)
+
+static void
+mem_error (const char *format,
+           ...)
+{
+  const char *pname;
+  va_list args;
+  /* at least, put out "MEMORY-ERROR", in case we segfault during the rest of the function */
+  fputs ("\n***MEMORY-ERROR***: ", stderr);
+  pname = g_get_prgname();
+  g_fprintf (stderr, "%s[%ld]: ", pname ? pname : "", (long)getpid());
+  va_start (args, format);
+  g_vfprintf (stderr, format, args);
+  va_end (args);
+  fputs ("\n", stderr);
+  abort();
+  _exit (1);
+}
+
+/**
+ * fpi_usb_alloc:
+ *
+ * Returns a struct libusb_transfer, similar to calling
+ * `libusb_alloc_transfer(0)`[[1](http://libusb.sourceforge.net/api-1.0/group__asyncio.html#ga13cc69ea40c702181c430c950121c000)]. As libfprint uses GLib internally,
+ * and [memory allocation failures will make applications fail](https://developer.gnome.org/glib/stable/glib-Memory-Allocation.html#glib-Memory-Allocation.description),
+ * this helper will assert when the libusb call fails.
+ */
+struct libusb_transfer *
+fpi_usb_alloc(void)
+{
+	struct libusb_transfer *transfer;
+
+	transfer = libusb_alloc_transfer(0);
+	mem_assert(transfer);
+
+	return transfer;
+}
diff --git a/libfprint/fpi-usb.h b/libfprint/fpi-usb.h
new file mode 100644
index 0000000..c966678
--- /dev/null
+++ b/libfprint/fpi-usb.h
@@ -0,0 +1,27 @@
+/*
+ * Driver API definitions
+ * Copyright (C) 2018 Bastien Nocera <hadess@hadess.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __FPI_USB_H__
+#define __FPI_USB_H__
+
+#include <libusb.h>
+
+struct libusb_transfer *fpi_usb_alloc(void) __attribute__((returns_nonnull));
+
+#endif
diff --git a/libfprint/meson.build b/libfprint/meson.build
index b0db454..c4c32e0 100644
--- a/libfprint/meson.build
+++ b/libfprint/meson.build
@@ -11,6 +11,8 @@ libfprint_sources = [
     'fpi-ssm.h',
     'fpi-poll.h',
     'fpi-poll.c',
+    'fpi-usb.h',
+    'fpi-usb.c',
     'img.c',
     'imgdev.c',
     'sync.c',