From fa8e34a344c22a8bbb40e099d4ab4a47ec22c493 Mon Sep 17 00:00:00 2001 From: Klaus Reimer Date: Thu, 28 Feb 2013 00:12:07 +0100 Subject: [PATCH] Started working on switch to libusbx 1.0 --- src/main/java/de/ailis/usb4java/jni/USB.java | 2 +- .../java/de/ailis/usb4java/libusbx/Error.java | 95 ++++ .../de/ailis/usb4java/libusbx/LibUSB.java | 87 +++ .../de/ailis/usb4java/libusbx/Loader.java | 325 ++++++++++++ .../usb4java/libusbx/LoaderException.java | 42 ++ .../de/ailis/usb4java/libusbx/LogLevel.java | 49 ++ .../java/de/ailis/usb4java/libusbx/Test.java | 25 + .../de/ailis/usb4java/libusbx/Version.java | 65 +++ src/main/native/AUTHORS | 1 + src/main/native/COPYING | 502 ++++++++++++++++++ src/main/native/ChangeLog | 0 src/main/native/Makefile.am | 2 + src/main/native/Makefile.scm | 37 ++ src/main/native/NEWS | 1 + src/main/native/README | 1 + src/main/native/acinclude.m4 | 11 + src/main/native/build/linux-arm.sh | 31 ++ src/main/native/build/linux-x86.sh | 38 ++ src/main/native/build/linux-x86_64.sh | 30 ++ src/main/native/build/macosx-universal.sh | 71 +++ src/main/native/build/mingw-windows-x86.sh | 48 ++ src/main/native/build/mingw-windows-x86_64.sh | 48 ++ src/main/native/configure.ac | 18 + src/main/native/src/Context.c | 27 + src/main/native/src/Context.h | 15 + src/main/native/src/Error.c | 16 + src/main/native/src/Error.h | 14 + src/main/native/src/LibUSB.c | 76 +++ src/main/native/src/Makefile.am | 10 + src/main/native/src/Version.c | 102 ++++ src/main/native/src/Version.h | 15 + src/main/native/src/usb4java.h | 12 + 32 files changed, 1815 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/ailis/usb4java/libusbx/Error.java create mode 100644 src/main/java/de/ailis/usb4java/libusbx/LibUSB.java create mode 100644 src/main/java/de/ailis/usb4java/libusbx/Loader.java create mode 100644 src/main/java/de/ailis/usb4java/libusbx/LoaderException.java create mode 100644 src/main/java/de/ailis/usb4java/libusbx/LogLevel.java create mode 100644 src/main/java/de/ailis/usb4java/libusbx/Test.java create mode 100644 src/main/java/de/ailis/usb4java/libusbx/Version.java create mode 100644 src/main/native/AUTHORS create mode 100644 src/main/native/COPYING create mode 100644 src/main/native/ChangeLog create mode 100644 src/main/native/Makefile.am create mode 100644 src/main/native/Makefile.scm create mode 100644 src/main/native/NEWS create mode 100644 src/main/native/README create mode 100644 src/main/native/acinclude.m4 create mode 100755 src/main/native/build/linux-arm.sh create mode 100755 src/main/native/build/linux-x86.sh create mode 100755 src/main/native/build/linux-x86_64.sh create mode 100755 src/main/native/build/macosx-universal.sh create mode 100755 src/main/native/build/mingw-windows-x86.sh create mode 100755 src/main/native/build/mingw-windows-x86_64.sh create mode 100644 src/main/native/configure.ac create mode 100644 src/main/native/src/Context.c create mode 100644 src/main/native/src/Context.h create mode 100644 src/main/native/src/Error.c create mode 100644 src/main/native/src/Error.h create mode 100644 src/main/native/src/LibUSB.c create mode 100644 src/main/native/src/Makefile.am create mode 100644 src/main/native/src/Version.c create mode 100644 src/main/native/src/Version.h create mode 100644 src/main/native/src/usb4java.h diff --git a/src/main/java/de/ailis/usb4java/jni/USB.java b/src/main/java/de/ailis/usb4java/jni/USB.java index ea22f8e..4c62a78 100644 --- a/src/main/java/de/ailis/usb4java/jni/USB.java +++ b/src/main/java/de/ailis/usb4java/jni/USB.java @@ -246,7 +246,7 @@ public final class USB * usb_find_busses will find all of the busses on the system. Returns the * number of changes since previous call to this function (total of new * busses and busses removed). - * + * * @return The number of changes since previous call. */ public static native int usb_find_busses(); diff --git a/src/main/java/de/ailis/usb4java/libusbx/Error.java b/src/main/java/de/ailis/usb4java/libusbx/Error.java new file mode 100644 index 0000000..d4da18a --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusbx/Error.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2013 Klaus Reimer + * See LICENSE.md for licensing information. + */ + +package de.ailis.usb4java.libusbx; + + +/** + * Most libusbx functions return 0 on success or one of these codes on failure. + * You can call libusb_error_name() to retrieve a string representation of an + * error code. + */ +public enum Error +{ + /** Success (no error). */ + SUCCESS(0), + + /** Input/output error. */ + ERROR_IO(-1), + + /** Invalid parameter. */ + ERROR_INVALID_PARAM(-2), + + /** Access denied (insufficient permissions). */ + ERROR_ACCESS(-3), + + /** No such device (it may have been disconnected). */ + ERROR_NO_DEVICE(-4), + + /** Entity not found. */ + ERROR_NOT_FOUND(-5), + + /** Resource busy. */ + ERROR_BUSY(-6), + + /** Operation timed out. */ + ERROR_TIMEOUT(-7), + + /** Overflow. */ + ERROR_OVERFLOW(-8), + + /** Pipe error. */ + ERROR_PIPE(-9), + + /** System call interrupted (perhaps due to signal) */ + ERROR_INTERRUPTED(-10), + + /** Insufficient memory. */ + ERROR_NO_MEM(-11), + + /** Operation not supported or unimplemented on this platform. */ + ERROR_NOT_SUPPORTED(-12), + + /** Other error. */ + ERROR_OTHER(-99); + + /** The internal error code. */ + private int code; + + /** + * Constructor. + * + * @param code + * The internal error code. + */ + private Error(final int code) + { + this.code = code; + } + + /** + * Returns the internal error code. + * + * @return The internal error code. + */ + public int getCode() + { + return this.code; + } + + /** + * Returns the error enum for the specified error code. + * + * @param code + * The internal error code. + * @return The error enum. + */ + public static Error valueOf(final int code) + { + for (Error error: values()) + if (error.getCode() == code) return error; + throw new IllegalArgumentException("Invalid error code: " + code); + } +} diff --git a/src/main/java/de/ailis/usb4java/libusbx/LibUSB.java b/src/main/java/de/ailis/usb4java/libusbx/LibUSB.java new file mode 100644 index 0000000..178a642 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusbx/LibUSB.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2013 Klaus Reimer + * See LICENSE.md for licensing information. + */ + +package de.ailis.usb4java.libusbx; + +/** + * + */ +public class LibUSB +{ + static + { + Loader.load(); + } + + /** + * Initialize libusb. + * + * This function must be called before calling any other libusbx function. + * + * If you do not provide an output location for a {@link Context}, a default + * context will be created. If there was already a default context, it will + * be reused (and nothing will be initialized/reinitialized). + * + * @param context + * Optional output location for context pointer. Null to use + * default context. Only valid on return code 0. + * @return 0 on success, or a {@link Error} code on failure + * + * @see Contexts + */ + public static native Error init(final Context context); + + /** + * Deinitialize libusb. + * + * Should be called after closing all open devices and before your + * application terminates. + * + * @param context + * The {@link Context} to deinitialize, or NULL for the default + * context + */ + public static native void exit(final Context context); + + /** + * Set log message verbosity. + * + * The default level is {@link LogLevel#NONE}, which means no messages are + * ever printed. If you choose to increase the message verbosity level, + * ensure that your application does not close the stdout/stderr file + * descriptors. + * + * You are advised to use level {@link LogLevel#WARNING}. libusbx is + * conservative with its message logging and most of the time, will only log + * messages that explain error conditions and other oddities. This will help + * you debug your software. + * + * If the {@link LogLevel#DEBUG} environment variable was set when libusbx + * was initialized, this function does nothing: the message verbosity is + * fixed to the value in the environment variable. + * + * If libusbx was compiled without any message logging, this function does + * nothing: you'll never get any messages. + * + * If libusbx was compiled with verbose debug message logging, this function + * does nothing: you'll always get messages from all levels. + * + * @param context + * The {@link Context} to operate on, or NULL for the default + * context. + * @param level + * The log level to set. + */ + public static native void setDebug(final Context context, final LogLevel level); + + /** + * Returns the version of the libusbx runtime. + * + * @return The version of the libusbx runtime. + */ + public static native Version getVersion(); + +} diff --git a/src/main/java/de/ailis/usb4java/libusbx/Loader.java b/src/main/java/de/ailis/usb4java/libusbx/Loader.java new file mode 100644 index 0000000..ccfb62c --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusbx/Loader.java @@ -0,0 +1,325 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.libusbx; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; + +/** + * Utility class to load native libraries from classpath. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class Loader +{ + /** Constant for Mac OS X operating system. */ + private static final String OS_MACOSX = "macosx"; + + /** Constant for Linux operating system. */ + private static final String OS_LINUX = "linux"; + + /** Constant for Windows operating system. */ + private static final String OS_WINDOWS = "windows"; + + /** Constant for FreeBSD operating system. */ + private static final String OS_FREEBSD = "freebsd"; + + /** Constant for SunOS operating system. */ + private static final String OS_SUNOS = "sunos"; + + /** Constant for i386 architecture. */ + private static final String ARCH_I386 = "i386"; + + /** Constant for x86 architecture. */ + private static final String ARCH_X86 = "x86"; + + /** Constant for x86_64 architecture. */ + private static final String ARCH_X86_64 = "x86_64"; + + /** Constant for amd64 architecture. */ + private static final String ARCH_AMD64 = "amd64"; + + /** Constant for universal architecture. */ + private static final String ARCH_UNIVERSAL = "universal"; + + /** Constant for so file extension. */ + private static final String EXT_SO = "so"; + + /** Constant for dll file extension. */ + private static final String EXT_DLL = "dll"; + + /** Constant for dylib file extension. */ + private static final String EXT_DYLIB = "dylib"; + + /** The temporary directory for native libraries. */ + private static File tmp; + + /** If library is already loaded. */ + private static boolean loaded = false; + + /** + * Private constructor to prevent instantiation. + */ + private Loader() + { + // Nothing to do here + } + + /** + * Returns the operating system name. This could be "linux", "windows" or + * "macosx" or (for any other non-supported platform) the value of the + * "os.name" property converted to lower case and with removed space + * characters. + * + * @return The operating system name. + */ + private static String getOS() + { + final String os = System.getProperty("os.name"); + if (os.toLowerCase().contains(OS_WINDOWS)) return OS_WINDOWS; + return os.toLowerCase().replace(" ", ""); + } + + /** + * Returns the CPU architecture. This will be "x86" or "x86_64" (Platform + * names i386 und amd64 are converted accordingly) or (when platform is + * unsupported) the value of os.arch converted to lower-case and with + * removed space characters. + * + * @return The CPU architecture + */ + private static String getArch() + { + final String os = getOS(); + if (os.equals(OS_MACOSX)) return ARCH_UNIVERSAL; + final String arch = System.getProperty("os.arch"); + if (arch.equals(ARCH_I386)) return ARCH_X86; + if (arch.equals(ARCH_AMD64)) return ARCH_X86_64; + return arch.toLowerCase().replace(" ", ""); + } + + /** + * Returns the shared library extension name. + * + * @return The shared library extension name. + */ + private static String getExt() + { + final String os = getOS(); + final String key = "usb4java.libext." + getOS(); + final String ext = System.getProperty(key); + if (ext != null) return ext; + if (os.equals(OS_LINUX) || os.equals(OS_FREEBSD) || os.equals(OS_SUNOS)) + return EXT_SO; + if (os.equals(OS_WINDOWS)) + return EXT_DLL; + if (os.equals(OS_MACOSX)) + return EXT_DYLIB; + throw new LoaderException("Unable to determine the shared library " + + "file extension for operating system '" + os + + "'. Please specify Java parameter -D" + key + "="); + } + + /** + * Creates the temporary directory used for unpacking the native libraries. + * This directory is marked for deletion on exit. + * + * @return The temporary directory for native libraries. + */ + private static File createTempDirectory() + { + // Return cached tmp directory when already created + if (tmp != null) return tmp; + + try + { + tmp = File.createTempFile("usb4java", null); + tmp.delete(); + tmp.mkdirs(); + tmp.deleteOnExit(); + return tmp; + } + catch (final IOException e) + { + throw new LoaderException("Unable to create temporary directory " + + "for usb4java natives: " + e, e); + } + } + + /** + * Returns the platform name. This could be for example "linux-x86" or + * "windows-x86_64". + * + * @return The architecture name. Never null. + */ + private static String getPlatform() + { + return getOS() + "-" + getArch(); + } + + /** + * Returns the name of the usb4java native library. This could be + * "libusb4java.dll" for example. + * + * @return The usb4java native library name. Never null. + */ + private static String getLibName() + { + return "libusb4java." + getExt(); + } + + /** + * Returns the name of the libusb native library. This could be + * "libusb0.dll" for example or null if this library is not needed on the + * current platform (Because it is provided by the operating system). + * + * @return The libusb native library name or null if not needed. + */ + private static String getExtraLibName() + { + final String os = getOS(); + if (os.equals(OS_WINDOWS)) return "libusb0." + EXT_DLL; + if (os.equals(OS_MACOSX)) return "libusb." + EXT_DYLIB; + return null; + } + + /** + * Copies the specified input stream to the specified output file. + * + * @param input + * The input stream. + * @param output + * The output file. + * @throws IOException + * If copying failed. + */ + private static void copy(final InputStream input, final File output) + throws IOException + { + final byte[] buffer = new byte[8192]; + final FileOutputStream stream = new FileOutputStream(output); + try + { + int read; + while ((read = input.read(buffer)) != -1) + { + stream.write(buffer, 0, read); + } + } + finally + { + stream.close(); + } + } + + /** + * Extracts a single library. + * + * @param platform + * The platform name (For example "linux-x86") + * @param lib + * The library name to extract (For example "libusb0.dll") + * @return The absolute path to the extracted library. + */ + private static String extractLibrary(final String platform, final String lib) + { + // Extract the usb4java library + final String source = '/' + + Loader.class.getPackage().getName().replace('.', '/') + + '/' + platform + "/" + lib; + + // Check if native library is present + final URL url = Loader.class.getResource(source); + if (url == null) throw new LoaderException( + "Native library not found in classpath: " + source); + + // If native library was found in an already extracted form then + // return this one without extracting it + if (url.getProtocol().equals("file")) + { + try + { + return new File(url.toURI()).getAbsolutePath(); + } + catch (final URISyntaxException e) + { + // Can't happen because we are not constructing the URI + // manually. But even when it happens then we fall back to + // extracting the library. + } + } + + // Extract the library and return the path to the extracted file. + final File dest = new File(createTempDirectory(), lib); + try + { + final InputStream stream = + Loader.class.getResourceAsStream(source); + if (stream == null) + throw new LoaderException("Unable to find " + source + + " in the classpath"); + try + { + copy(stream, dest); + } + finally + { + stream.close(); + } + } + catch (final IOException e) + { + throw new LoaderException( + "Unable to extract native library " + source + " to " + dest + + ": " + e, e); + } + + // Mark usb4java library for deletion + dest.deleteOnExit(); + + return dest.getAbsolutePath(); + } + + /** + * Extracts the usb4java library (and the libusb library if needed) and + * returns the absolute filename to be loaded by Java. The extracted + * libraries are marked for deletion on exit. + * + * @return The absolute path to the extracted usb4java library. + */ + private static String extract() + { + final String platform, lib, extraLib; + + platform = getPlatform(); + lib = getLibName(); + extraLib = getExtraLibName(); + if (extraLib != null) extractLibrary(platform, extraLib); + return extractLibrary(platform, lib); + } + + /** + * Loads the libusbx native wrapper library. Can be safely called + * multiple times. Duplicate calls are ignored. This method is automatically + * called when the {@link LibUSB} class is loaded. When you need to do it + * earlier (To catch exceptions for example) then simply call this method + * manually. + * + * @throws LoaderException + * When loading the native wrapper libraries failed. + */ + public static void load() throws LoaderException + { + if (loaded) return; + final String path = extract(); + System.load(path); + loaded = true; + } +} diff --git a/src/main/java/de/ailis/usb4java/libusbx/LoaderException.java b/src/main/java/de/ailis/usb4java/libusbx/LoaderException.java new file mode 100644 index 0000000..45210e5 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusbx/LoaderException.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.libusbx; + + +/** + * Thrown when JNI library could not be loaded. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class LoaderException extends RuntimeException +{ + /** Serial version UID. */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + * @param message + * The error message. + */ + public LoaderException(final String message) + { + super(message); + } + + /** + * Constructor. + * + * @param message + * The error message. + * @param cause + * The root cause. + */ + public LoaderException(final String message, final Throwable cause) + { + super(message, cause); + } +} diff --git a/src/main/java/de/ailis/usb4java/libusbx/LogLevel.java b/src/main/java/de/ailis/usb4java/libusbx/LogLevel.java new file mode 100644 index 0000000..1ce98f7 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusbx/LogLevel.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 Klaus Reimer + * See LICENSE.md for licensing information. + */ + +package de.ailis.usb4java.libusbx; + +/** + * Log message levels. + * + * @author Klaus Reimer (k@ailis.de) + */ +public enum LogLevel +{ + /** No messages ever printed by the library (default). */ + NONE(0), + + /** Error messages are printed to stderr. */ + ERROR(1), + + /** Warning and error messages are printed to stderr. */ + WARNING(2), + + /** + * Informational messages are printed to stdout, warning and error messages + * are printed to stderr. + */ + INFO(3), + + /** + * Debug and informational messages are printed to stdout, warnings and + * errors to stderr. + */ + DEBUG(4); + + /** The numeric log level. */ + int level; + + /** + * Constructor. + * + * @param level + * The numeric log level. + */ + private LogLevel(int level) + { + this.level = level; + } +} diff --git a/src/main/java/de/ailis/usb4java/libusbx/Test.java b/src/main/java/de/ailis/usb4java/libusbx/Test.java new file mode 100644 index 0000000..3f07ab5 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusbx/Test.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013 Klaus Reimer + * See LICENSE.md for licensing information. + */ +package de.ailis.usb4java.libusbx; + +/** + */ +public class Test +{ + /** + * @param args command line args + */ + public static void main(String[] args) + { + System.out.println(LibUSB.getVersion()); + Context context = new Context(); + System.out.println(context); + System.out.println(LibUSB.init(context)); + LibUSB.setDebug(context, LogLevel.DEBUG); + System.out.println(context); + LibUSB.exit(context); + System.out.println(context); + } +} diff --git a/src/main/java/de/ailis/usb4java/libusbx/Version.java b/src/main/java/de/ailis/usb4java/libusbx/Version.java new file mode 100644 index 0000000..048f66f --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusbx/Version.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.libusbx; + +import java.nio.ByteBuffer; + +/** + * Structure providing the version of the libusbx runtime. + */ +public final class Version +{ + /** The version data. */ + private final ByteBuffer data; + + /** + * Constructor. + * + * @param data + * The version data. + */ + private Version(final ByteBuffer data) + { + this.data = data; + } + + /** + * Returns the library major version. + * + * @return The library major version. + */ + public native int major(); + + /** + * Returns the library minor version. + * + * @return The library minor version. + */ + public native int minor(); + + /** + * Returns the library micro version. + * + * @return The library micro version. + */ + public native int micro(); + + /** + * Returns the release candidate suffix string, e.g. "-rc4". + * + * @return The release candidate suffix string. + */ + public native String rc(); + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return major() + "." + minor() + "." + micro() + rc(); + } +} diff --git a/src/main/native/AUTHORS b/src/main/native/AUTHORS new file mode 100644 index 0000000..1f18bbf --- /dev/null +++ b/src/main/native/AUTHORS @@ -0,0 +1 @@ +Klaus Reimer diff --git a/src/main/native/COPYING b/src/main/native/COPYING new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/src/main/native/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/src/main/native/ChangeLog b/src/main/native/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/src/main/native/Makefile.am b/src/main/native/Makefile.am new file mode 100644 index 0000000..87d3040 --- /dev/null +++ b/src/main/native/Makefile.am @@ -0,0 +1,2 @@ +ACLOCAL_AMFLAGS=-I m4 +SUBDIRS = src diff --git a/src/main/native/Makefile.scm b/src/main/native/Makefile.scm new file mode 100644 index 0000000..e76900c --- /dev/null +++ b/src/main/native/Makefile.scm @@ -0,0 +1,37 @@ +all: + mkdir -p m4 + autoreconf --install --force + +clean: + rm -rf \ + Debug \ + autom4te.cache \ + m4 \ + aclocal.m4 \ + config.guess \ + config.h \ + config.h.in \ + config.log \ + config.status \ + config.sub \ + configure \ + depcomp \ + install-sh \ + INSTALL \ + libtool \ + ltmain.sh \ + Makefile \ + Makefile.in \ + missing \ + stamp-h1 \ + src/Makefile.in \ + src/.deps \ + src/.libs \ + src/*.lo \ + src/*.la \ + src/*.o \ + src/Makefile \ + *.tar.gz \ + *.tar.bz2 \ + *~ + diff --git a/src/main/native/NEWS b/src/main/native/NEWS new file mode 100644 index 0000000..4a39bdf --- /dev/null +++ b/src/main/native/NEWS @@ -0,0 +1 @@ +Nothing new right now. \ No newline at end of file diff --git a/src/main/native/README b/src/main/native/README new file mode 100644 index 0000000..eba34e6 --- /dev/null +++ b/src/main/native/README @@ -0,0 +1 @@ +libusbx 1.0 Java wrapper diff --git a/src/main/native/acinclude.m4 b/src/main/native/acinclude.m4 new file mode 100644 index 0000000..2f7f46d --- /dev/null +++ b/src/main/native/acinclude.m4 @@ -0,0 +1,11 @@ +AC_DEFUN([AC_CHECK_JAVA],[ + AC_ARG_WITH( + java-home, + [ --with-java-home=DIR Set Java home directory ], + [ + JAVA_HOME=`echo $withval` + ] + ) + CPPFLAGS="$CPPFLAGS -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -I$JAVA_HOME/include/win32" + AC_CHECK_HEADERS(jni.h,,echo "ERROR: jni.h not found. JAVA_HOME is $JAVA_HOME. Use --with-java-home option to specify an other Java home directory."; exit 1;) +]) diff --git a/src/main/native/build/linux-arm.sh b/src/main/native/build/linux-arm.sh new file mode 100755 index 0000000..f14d4c4 --- /dev/null +++ b/src/main/native/build/linux-arm.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Builds libusb4java for 32 bit arm. libusb-dev must be installed. +# This script is meant to be run directly on a linux-arm machine +# (Like the Raspberry) + +set -e +cd $(dirname $0)/.. + +OS=linux +ARCH=arm +TMPDIR=$(pwd)/tmp +DISTDIR=$(pwd)/../resources/de/ailis/usb4java/jni/${OS}-${ARCH} + +# Clean up +rm -rf $TMPDIR +rm -rf $DISTDIR + +# Build autoconf stuff if needed +if [ ! -e configure ] +then + make -f Makefile.scm +fi + +# Build libusb4java +./configure --prefix=/ +make clean install-strip DESTDIR=$TMPDIR +mkdir -p $DISTDIR +cp -faL $TMPDIR/lib/libusb4java.so $DISTDIR/ +chmod -x $DISTDIR/libusb4java.so +rm -rf $TMPDIR diff --git a/src/main/native/build/linux-x86.sh b/src/main/native/build/linux-x86.sh new file mode 100755 index 0000000..fec977f --- /dev/null +++ b/src/main/native/build/linux-x86.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Builds libusb4java for 32 bit linux. +# +# If running on 32 bit linux you just need libusb-dev. +# +# If running on 64 bit linux you need ia32-libs-dev and libc6-dev-i386 +# or gcc-multilib and libusb-0.1-4:i386 or something like that an newer +# systems. Depending on your multilib installation it may be required to +# create a manual symlink libusb.so in /lib/i386-linux-gnu or otherwise +# compilation will fail because the compiler can't find the 32 bit +# library. + +set -e +cd $(dirname $0)/.. + +OS=linux +ARCH=x86 +TMPDIR=$(pwd)/tmp +DISTDIR=$(pwd)/../resources/de/ailis/usb4java/jni/${OS}-${ARCH} + +# Clean up +rm -rf $TMPDIR +rm -rf $DISTDIR + +# Build autoconf stuff if needed +if [ ! -e configure ] +then + make -f Makefile.scm +fi + +# Build libusb4java +./configure --prefix=/ CFLAGS="-m32" +make clean install-strip DESTDIR=$TMPDIR +mkdir -p $DISTDIR +cp -faL $TMPDIR/lib/libusb4java.so $DISTDIR/ +chmod -x $DISTDIR/libusb4java.so +rm -rf $TMPDIR diff --git a/src/main/native/build/linux-x86_64.sh b/src/main/native/build/linux-x86_64.sh new file mode 100755 index 0000000..0e14f39 --- /dev/null +++ b/src/main/native/build/linux-x86_64.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Builds libusb4java for 64 bit linux. +# Must be executed on 64 bit linux machine and must have libusb-dev installed. + +set -e +cd $(dirname $0)/.. + +OS=linux +ARCH=x86_64 +TMPDIR=$(pwd)/tmp +DISTDIR=$(pwd)/../resources/de/ailis/usb4java/libusbx/${OS}-${ARCH} + +# Clean up +rm -rf $TMPDIR +rm -rf $DISTDIR + +# Build autoconf stuff if needed +if [ ! -e configure ] +then + make -f Makefile.scm +fi + +# Build libusb4java +./configure --prefix=/ CFLAGS="-m64" +make clean install-strip DESTDIR=$TMPDIR +mkdir -p $DISTDIR +cp -faL $TMPDIR/lib/libusb4java.so $DISTDIR/ +chmod -x $DISTDIR/libusb4java.so +rm -rf $TMPDIR diff --git a/src/main/native/build/macosx-universal.sh b/src/main/native/build/macosx-universal.sh new file mode 100755 index 0000000..c25ea0c --- /dev/null +++ b/src/main/native/build/macosx-universal.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# +# Builds universal libusb4java for Mac OS X (x86_64, x86, ppc) +# This is meant to be run on a Mac (With XCode command line stuff +# installed), it doesn't cross compile on linux! + +set -e +cd $(dirname $0)/.. + +OS=macosx +ARCH=universal +TMPDIR=$(pwd)/tmp +DISTDIR=$(pwd)/../resources/de/ailis/usb4java/jni/${OS}-${ARCH} + +# Clean up +rm -rf $TMPDIR +rm -rf $DISTDIR + +# Download and unpack libusb +LIBUSB_VERSION=0.1.12 +URL="http://downloads.sourceforge.net/project/libusb/libusb-0.1%20%28LEGACY%29/$LIBUSB_VERSION/libusb-$LIBUSB_VERSION.tar.gz" +mkdir -p $TMPDIR +wget -O $TMPDIR/libusb.tar.gz "$URL" +cd $TMPDIR +tar xvfz libusb.tar.gz + +# Compile libusb +cd libusb-$LIBUSB_VERSION +cat << EOF | patch || exit 1 +--- ltmain.sh.orig 2009-10-10 17:26:28.000000000 +0200 ++++ ltmain.sh 2009-10-10 17:25:40.000000000 +0200 +@@ -917,7 +917,7 @@ + old_convenience= + deplibs= + old_deplibs= +- compiler_flags= ++ compiler_flags=\$CFLAGS + linker_flags= + dllsearchpath= + lib_search_path=`pwd` +EOF +export CFLAGS="-w -arch i386 -arch x86_64 -arch ppc" +./configure --prefix=/usr --disable-dependency-tracking --disable-build-docs +make install-strip DESTDIR=$TMPDIR SUBDIRS= +INCLUDES=$TMPDIR/usr/include +LIBS=$TMPDIR/usr/lib +cd ../.. + +# Create autoconf stuff if needed +if [ ! -e configure ] +then + make -f Makefile.scm +fi + +# Build libusb4java +./configure \ + --prefix=/usr \ + --with-libusb-includes=$INCLUDES \ + --with-libusb-libs=$LIBS \ + --disable-dependency-tracking \ + CFLAGS="-arch i386 -arch x86_64 -arch ppc" +make clean install-strip DESTDIR=$TMPDIR +mkdir -p $DISTDIR +cp -faL $TMPDIR/usr/lib/libusb4java.dylib $DISTDIR/ +cp -faL $LIBS/libusb.dylib $DISTDIR/ +rm -rf $TMPDIR + +# Remove paths from libraries +install_name_tool -id @executable_path/libusb.dylib $DISTDIR/libusb.dylib +install_name_tool -id @executable_path/libusb4java.dylib $DISTDIR/libusb4java.dylib +install_name_tool -change /usr/lib/libusb-0.1.4.dylib @loader_path/libusb.dylib $DISTDIR/libusb4java.dylib diff --git a/src/main/native/build/mingw-windows-x86.sh b/src/main/native/build/mingw-windows-x86.sh new file mode 100755 index 0000000..b46a35b --- /dev/null +++ b/src/main/native/build/mingw-windows-x86.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# Compile libusb4java for 32 bit windows with mingw on Windows +# or cross-compile it with mingw on Linux. +# +# For cross-compiling on Linux mingw-w64-dev must be installed. + +set -e +cd $(dirname $0)/.. + +OS=windows +ARCH=x86 +TMPDIR=$(pwd)/tmp +DISTDIR=$(pwd)/../resources/de/ailis/usb4java/jni/${OS}-${ARCH} + +# Clean up +rm -rf $TMPDIR +rm -rf $DISTDIR + +# Download and unpack libusb-win32 +LIBUSBWIN32_VERSION=1.2.2.0 +mkdir -p $TMPDIR +wget -O $TMPDIR/libusb-win32.zip "http://downloads.sourceforge.net/project/libusb-win32/libusb-win32-releases/$LIBUSBWIN32_VERSION/libusb-win32-bin-$LIBUSBWIN32_VERSION.zip" +cd $TMPDIR +unzip libusb-win32.zip +INCLUDES=$TMPDIR/libusb-win32-bin-$LIBUSBWIN32_VERSION/include +LIBS=$TMPDIR/libusb-win32-bin-$LIBUSBWIN32_VERSION/lib/gcc +BINS=$TMPDIR/libusb-win32-bin-$LIBUSBWIN32_VERSION/bin/x86 +cd .. + +# Create autoconf stuff if needed +if [ ! -e configure ] +then + make -f Makefile.scm +fi + +# Build libusb4java +CFLAGS=-m32 ./configure \ + --prefix=/ \ + --host=i686-w64-mingw32 \ + --with-libusb-includes=$INCLUDES \ + --with-libusb-libs=$LIBS,$BINS +make clean install-strip DESTDIR=$TMPDIR +mkdir -p $DISTDIR +cp -faL $TMPDIR/bin/libusb4java-0.dll $DISTDIR/libusb4java.dll +cp -faL $BINS/libusb0_x86.dll $DISTDIR/libusb0.dll +chmod -x $DISTDIR/libusb4java.dll +rm -rf $TMPDIR diff --git a/src/main/native/build/mingw-windows-x86_64.sh b/src/main/native/build/mingw-windows-x86_64.sh new file mode 100755 index 0000000..e17998d --- /dev/null +++ b/src/main/native/build/mingw-windows-x86_64.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# Compile libusb4java for 64 bit windows with mingw on Windows +# or cross-compile it with mingw on Linux. +# +# For cross-compiling on Linux mingw-w64-dev must be installed. + +set -e +cd $(dirname $0)/.. + +OS=windows +ARCH=x86_64 +TMPDIR=$(pwd)/tmp +DISTDIR=$(pwd)/../resources/de/ailis/usb4java/jni/${OS}-${ARCH} + +# Clean up +rm -rf $TMPDIR +rm -rf $DISTDIR + +# Download and unpack libusb-win32 +LIBUSBWIN32_VERSION=1.2.2.0 +mkdir -p $TMPDIR +wget -O $TMPDIR/libusb-win32.zip "http://downloads.sourceforge.net/project/libusb-win32/libusb-win32-releases/$LIBUSBWIN32_VERSION/libusb-win32-bin-$LIBUSBWIN32_VERSION.zip" +cd $TMPDIR +unzip libusb-win32.zip +INCLUDES=$TMPDIR/libusb-win32-bin-$LIBUSBWIN32_VERSION/include +LIBS=$TMPDIR/libusb-win32-bin-$LIBUSBWIN32_VERSION/lib/gcc +BINS=$TMPDIR/libusb-win32-bin-$LIBUSBWIN32_VERSION/bin/amd64 +cd .. + +# Create autoconf stuff if needed +if [ ! -e configure ] +then + make -f Makefile.scm +fi + +# Build libusb4java +CFLAGS=-m64 ./configure \ + --prefix=/ \ + --host=x86_64-w64-mingw32 \ + --with-libusb-includes=$INCLUDES \ + --with-libusb-libs=$LIBS,$BINS +make clean install-strip DESTDIR=$TMPDIR +mkdir -p $DISTDIR +cp -faL $TMPDIR/bin/libusb4java-0.dll $DISTDIR/libusb4java.dll +cp -faL $BINS/libusb0.dll $DISTDIR/libusb0.dll +chmod -x $DISTDIR/libusb4java.dll +rm -rf $TMPDIR diff --git a/src/main/native/configure.ac b/src/main/native/configure.ac new file mode 100644 index 0000000..585a817 --- /dev/null +++ b/src/main/native/configure.ac @@ -0,0 +1,18 @@ +AC_PREREQ([2.61]) +AC_INIT([libusb4java], [1.0.0], [k@ailis.de]) +AM_INIT_AUTOMAKE(foreign -Wall -Werror) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_SRCDIR([src/usb4java.h]) + +AC_LANG_C +AC_PROG_CC +AM_PROG_LIBTOOL +AC_CHECK_JAVA +PKG_CHECK_MODULES(LIBUSB, libusb-1.0) + +AC_CONFIG_FILES( + Makefile + src/Makefile +) +AC_OUTPUT diff --git a/src/main/native/src/Context.c b/src/main/native/src/Context.c new file mode 100644 index 0000000..63975ad --- /dev/null +++ b/src/main/native/src/Context.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +#include "usb4java.h" +#include "Context.h" + +void wrap_context(JNIEnv* env, libusb_context* data, jobject obj) +{ + jobject buffer = (*env)->NewDirectByteBuffer(env, data, 0); + jclass cls = (*env)->GetObjectClass(env, obj); + jfieldID field = (*env)->GetFieldID(env, cls, "data", + "Ljava/nio/ByteBuffer;"); + (*env)->SetObjectField(env, obj, field, buffer); +} + +libusb_context* unwrap_context(JNIEnv* env, jobject obj) +{ + if (!obj) return NULL; + jclass cls = (*env)->GetObjectClass(env, obj); + jfieldID field = (*env)->GetFieldID(env, cls, "data", + "Ljava/nio/ByteBuffer;"); + jobject buffer = (*env)->GetObjectField(env, obj, field); + return (libusb_context *) + (*env)->GetDirectBufferAddress(env, buffer); +} diff --git a/src/main/native/src/Context.h b/src/main/native/src/Context.h new file mode 100644 index 0000000..0fab2f8 --- /dev/null +++ b/src/main/native/src/Context.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +#ifndef USB4JAVA_CONTEXT_H +#define USB4JAVA_CONTEXT_H + +#include +#include + +void wrap_context(JNIEnv*, libusb_context*, jobject); +libusb_context* unwrap_context(JNIEnv*, jobject); + +#endif diff --git a/src/main/native/src/Error.c b/src/main/native/src/Error.c new file mode 100644 index 0000000..a4595da --- /dev/null +++ b/src/main/native/src/Error.c @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +#include "usb4java.h" +#include "Error.h" + +jobject wrap_error(JNIEnv* env, const int code) +{ + jclass cls = (*env)->FindClass(env, PACKAGE_DIR"/Error"); + jmethodID method = (*env)->GetStaticMethodID(env, cls, "valueOf", + "(I)L"PACKAGE_DIR"/Error;"); + if (!method) return NULL; + return (*env)->CallStaticObjectMethod(env, cls, method, code); +} diff --git a/src/main/native/src/Error.h b/src/main/native/src/Error.h new file mode 100644 index 0000000..91db133 --- /dev/null +++ b/src/main/native/src/Error.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +#ifndef USB4JAVA_ERROR_H +#define USB4JAVA_ERROR_H + +#include +#include + +jobject wrap_error(JNIEnv*, const int); + +#endif diff --git a/src/main/native/src/LibUSB.c b/src/main/native/src/LibUSB.c new file mode 100644 index 0000000..ed80691 --- /dev/null +++ b/src/main/native/src/LibUSB.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +/** + * @name LibUSB + * + * Native methods for the LibUSB class. + * + * @author Klaus Reimer + */ + +#include +#include +#include "usb4java.h" +#include "Version.h" +#include "Context.h" + +/** + * Version getVersion() + */ +JNIEXPORT jobject JNICALL METHOD_NAME(LibUSB, getVersion) +( + JNIEnv *env, jclass class +) +{ + return wrap_version(env, libusb_get_version()); +} + +/** + * int init() + */ +JNIEXPORT jint JNICALL METHOD_NAME(LibUSB, init) +( + JNIEnv *env, jclass class, jobject context +) +{ + if (!context) + { + return wrap_error(env, libusb_init(NULL)); + } + else + { + libusb_context *ctx; + int result = libusb_init(&ctx); + wrap_context(env, ctx, context); + return wrap_error(env, result); + } +} + +/** + * void exit() + */ +JNIEXPORT jobject JNICALL METHOD_NAME(LibUSB, exit) +( + JNIEnv *env, jclass class, jobject context +) +{ + libusb_exit(unwrap_context(env, context)); +} + +/** + * void setDebug(Context, LogLevel) + */ +JNIEXPORT void JNICALL METHOD_NAME(LibUSB, setDebug) +( + JNIEnv *env, jclass class, jobject context, jobject logLevel +) +{ + if (!logLevel) return; + jclass cls = (*env)->GetObjectClass(env, logLevel); + jfieldID field = (*env)->GetFieldID(env, cls, "level", "I"); + jint level = (*env)->GetObjectField(env, logLevel, field); + libusb_set_debug(unwrap_context(env, context), level); +} diff --git a/src/main/native/src/Makefile.am b/src/main/native/src/Makefile.am new file mode 100644 index 0000000..34d331c --- /dev/null +++ b/src/main/native/src/Makefile.am @@ -0,0 +1,10 @@ +lib_LTLIBRARIES = libusb4java.la +libusb4java_la_CFLAGS = $(LIBUSB_CFLAGS) +libusb4java_la_LIBADD = +libusb4java_la_LDFLAGS = -version-info 1:0:0 -no-undefined +EXTRA_DIST = *.h +libusb4java_la_SOURCES = \ + LibUSB.c \ + Version.c \ + Context.c \ + Error.c diff --git a/src/main/native/src/Version.c b/src/main/native/src/Version.c new file mode 100644 index 0000000..ec35d26 --- /dev/null +++ b/src/main/native/src/Version.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +/** + * @name Version + * + * Native methods for the Version class. + * + * @author Klaus Reimer + */ + +#include "usb4java.h" +#include "Version.h" + +/** + * Wraps the specified native data into a Java object and returns it. + * + * @param env + * The JNI environment. + * @param version + * The native data to wrap. + * @return The wrapper object. + */ +jobject wrap_version(JNIEnv* env, const struct libusb_version* data) +{ + if (!data) return NULL; + jclass cls = (*env)->FindClass(env, PACKAGE_DIR"/Version"); + if (cls == NULL) return NULL; + jmethodID constructor = (*env)->GetMethodID(env, cls, "", + "(Ljava/nio/ByteBuffer;)V"); + if (constructor == NULL) return NULL; + jobject buffer = (*env)->NewDirectByteBuffer(env, data, + sizeof(struct libusb_version)); + return (*env)->NewObject(env, cls, constructor, buffer); +} + +/** + * Returns the wrapped native data from the specified wrapper object. + * + * @param env + * The JNI environment. + * @param obj + * The wrapper object. + * @return The wrapped object. + */ +const struct libusb_version* unwrap_version(JNIEnv* env, jobject obj) +{ + jclass cls = (*env)->GetObjectClass(env, obj); + jfieldID field = (*env)->GetFieldID(env, cls, "data", + "Ljava/nio/ByteBuffer;"); + jobject buffer = (*env)->GetObjectField(env, obj, field); + return (struct libusb_version *) + (*env)->GetDirectBufferAddress(env, buffer); +} + +/** + * int major() + */ +JNIEXPORT jint JNICALL METHOD_NAME(Version, major) +( + JNIEnv *env, jobject this +) +{ + return unwrap_version(env, this)->major; +} + +/** + * int minor() + */ +JNIEXPORT jint JNICALL METHOD_NAME(Version, minor) +( + JNIEnv *env, jobject this +) +{ + return unwrap_version(env, this)->minor; +} + +/** + * int micro() + */ +JNIEXPORT jint JNICALL METHOD_NAME(Version, micro) +( + JNIEnv *env, jobject this +) +{ + return unwrap_version(env, this)->micro; +} + +/** + * string rc() + */ +JNIEXPORT jint JNICALL METHOD_NAME(Version, rc) +( + JNIEnv *env, jobject this +) +{ + return (*env)->NewStringUTF(env, unwrap_version(env, this)->rc); +} + + diff --git a/src/main/native/src/Version.h b/src/main/native/src/Version.h new file mode 100644 index 0000000..7118a0f --- /dev/null +++ b/src/main/native/src/Version.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +#ifndef USB4JAVA_VERSION_H +#define USB4JAVA_VERSION_H + +#include +#include + +jobject wrap_version(JNIEnv*, const struct libusb_version*); +const struct libusb_version* unwrap_version(JNIEnv*, jobject); + +#endif diff --git a/src/main/native/src/usb4java.h b/src/main/native/src/usb4java.h new file mode 100644 index 0000000..ab46e01 --- /dev/null +++ b/src/main/native/src/usb4java.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +#ifndef USB4JAVA_H +#define USB4JAVA_H + +#define PACKAGE_DIR "de/ailis/usb4java/libusbx" +#define METHOD_NAME(class, method) Java_de_ailis_usb4java_libusbx_##class##_##method + +#endif