diff --git a/.run/Run on Raspberry Pi.run.xml b/.run/Run on Raspberry Pi.run.xml new file mode 100644 index 00000000..2109d0bf --- /dev/null +++ b/.run/Run on Raspberry Pi.run.xml @@ -0,0 +1,49 @@ + + + + + + + + + \ No newline at end of file diff --git a/libraries/pi4j-library-gpiod/generate-headers.sh b/libraries/pi4j-library-gpiod/generate-headers.sh new file mode 100644 index 00000000..8c2e033e --- /dev/null +++ b/libraries/pi4j-library-gpiod/generate-headers.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +javac src/main/java/com/pi4j/library/gpiod/internal/GpioD.java -h src/main/native diff --git a/libraries/pi4j-library-gpiod/pom.xml b/libraries/pi4j-library-gpiod/pom.xml new file mode 100644 index 00000000..5d29a68b --- /dev/null +++ b/libraries/pi4j-library-gpiod/pom.xml @@ -0,0 +1,365 @@ + + + 4.0.0 + + com.pi4j + pi4j-library + 2.4.0-SNAPSHOT + ../pi4j-library/pom.xml + + + + pi4j-library-gpiod + Pi4J :: LIBRARY :: JNI Wrapper for GpioD Library + Pi4J wrapper for the GpioD library + jar + + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + + + + + + + + + + ${project.build.directory} + false + + LICENSE.txt + NOTICE.txt + README.md + lib/armhf/pi4j-gpiod/libpi4j-gpiod.so + lib/armhf/pi4j-gpiod/libgpiod.so + lib/aarch64/pi4j-gpiod/libpi4j-gpiod.so + lib/aarch64/pi4j-gpiod/libgpiod.so + + + + src/main/resources + false + + + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + + + enforce-native-jni-file--exist + + enforce + + prepare-package + + + + + + ${project.build.outputDirectory}/lib/armhf/pi4j-gpiod/libpi4j-gpiod.so + ${project.build.outputDirectory}/lib/armhf/pi4j-gpiod/libgpiod.so + + ${project.build.outputDirectory}/lib/aarch64/pi4j-gpiod/libpi4j-gpiod.so + ${project.build.outputDirectory}/lib/aarch64/pi4j-gpiod/libgpiod.so + + + + true + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + + + transfer-compiled-pi4j-jar + install + + run + + + + + + + + + + + + + + + + + + + + + + + pi4j-attach-native + package + + run + + + + + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + runtime + com.pi4j + ${project.build.directory}/dependencies + false + false + true + + + + + + + + + + + + + + + + + default + + true + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + download-jni-dependency + validate + + copy + + + + + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + armhf + so + true + ${project.build.directory}/lib/armhf/pi4j-gpiod + libpi4j-gpiod.so + + + ${project.groupId} + ${project.artifactId} + ${project.version} + armhf + so + true + ${project.build.directory}/lib/armhf/pi4j-gpiod + libgpiod.so + + + + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + so + aarch64 + true + ${project.build.directory}/lib/aarch64/pi4j-gpiod + libpi4j-gpiod.so + + + ${project.groupId} + ${project.artifactId} + ${project.version} + so + aarch64 + true + ${project.build.directory}/lib/aarch64/pi4j-gpiod + libgpiod.so + + + + + + + + + + + + + + + + + + native + + + release-build + + + + + + maven-antrun-plugin + + + + pi4j-prepare-native + generate-resources + + + + + + + + + + + + + + run + + + + + + + + pi4j-build-native + generate-resources + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/CWrapper.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/CWrapper.java new file mode 100644 index 00000000..31826926 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/CWrapper.java @@ -0,0 +1,28 @@ +package com.pi4j.library.gpiod.internal; + +import java.util.Objects; + +public class CWrapper { + private long cPointer; + + public CWrapper(long cPointer) { + this.cPointer = cPointer; + } + + long getCPointer() { + return cPointer; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CWrapper cWrapper = (CWrapper) o; + return cPointer == cWrapper.cPointer; + } + + @Override + public int hashCode() { + return Objects.hash(cPointer); + } +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioChip.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioChip.java new file mode 100644 index 00000000..60640fa7 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioChip.java @@ -0,0 +1,53 @@ +package com.pi4j.library.gpiod.internal; + +import java.io.Closeable; + +/** + *

GpioChip

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioChip extends CWrapper implements Closeable { + + public GpioChip(long cPointer) { + super(cPointer); + } + + public void close() { + GpioD.chipClose(this); + } + + public String getName() { + return GpioD.chipGetName(this); + } + + public String getLabel() { + return GpioD.chipGetLabel(this); + } + + public int getNumLines() { + return GpioD.chipGetNumLines(this); + } + + public GpioLine getLine(int offset) { + return GpioD.chipGetLine(this, offset); + } + + public GpioLineBulk getLines(int[] offsets) { + GpioLineBulk bulk = new GpioLineBulk(); + GpioD.chipGetLines(this, offsets, bulk); + return bulk; + } + + public GpioLineBulk getLines() { + GpioLineBulk bulk = new GpioLineBulk(); + GpioD.chipGetAllLines(this, bulk); + return bulk; + } + + public GpioLine getLine(String name) { + return GpioD.chipGetLine(this, name); + } + +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioChipIterator.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioChipIterator.java new file mode 100644 index 00000000..1be9c4c6 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioChipIterator.java @@ -0,0 +1,72 @@ +package com.pi4j.library.gpiod.internal; + +import java.util.Iterator; + +/** + *

GpioChipIterator

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioChipIterator extends CWrapper implements Iterator { + + private boolean noCloseCurrent; + private GpioChip next; + private GpioChip current; + + GpioChipIterator(long cPointer) { + super(cPointer); + } + + public GpioChipIterator() { + this(GpioD.chipIterNew()); + } + + + @Override + protected void finalize() { + if(next == null) { + if(noCloseCurrent) { + GpioD.chipIterFreeNoClose(this); + } else { + GpioD.chipIterFree(this); + } + } else { + if(!noCloseCurrent) { + GpioD.chipClose(current); + } + GpioD.chipIterFree(this); + } + } + + @Override + public boolean hasNext() { + if(next == null) { + next = GpioD.chipIterNextNoClose(this); + } + return next != null; + } + + @Override + public GpioChip next() { + if(next == null) { + if(noCloseCurrent) { + current = GpioD.chipIterNextNoClose(this); + } else { + current = GpioD.chipIterNext(this); + } + } else { + if(current != null && !noCloseCurrent) { + GpioD.chipClose(current); + } + current = next; + noCloseCurrent = false; + next = null; + } + return current; + } + + public void noCloseCurrent() { + this.noCloseCurrent = true; + } +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioD.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioD.java new file mode 100644 index 00000000..2e7a9764 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioD.java @@ -0,0 +1,817 @@ +package com.pi4j.library.gpiod.internal; + +import com.pi4j.library.gpiod.util.NativeLibraryLoader; + +import java.util.Arrays; + +/** + *

GpioD interface.

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioD { + // C library: https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/include/gpiod.h?h=v1.6.x + + private GpioD() { + // forbid object construction + } + + static { + // Load the platform library + NativeLibraryLoader.load("libgpiod.so", "pi4j-gpiod"); + NativeLibraryLoader.load("libpi4j-gpiod.so", "pi4j-gpiod"); + } + + static GpioChip chipOpen(String path) { + Long ptr = c_gpiod_chip_open(path); + if(ptr == null) { + throw new GpioDException("c_gpiod_chip_open failed!"); + } + return new GpioChip(ptr); + } + + private static native Long c_gpiod_chip_open(String path); + + static void chipClose(GpioChip chip) { + c_gpiod_chip_close(chip.getCPointer()); + } + + private static native void c_gpiod_chip_close(long chipPtr); + + static String chipGetName(GpioChip chip) { + return c_gpiod_chip_name(chip.getCPointer()); + } + + private static native String c_gpiod_chip_name(long chipPtr); + + static String chipGetLabel(GpioChip chip) { + return c_gpiod_chip_label(chip.getCPointer()); + } + + private static native String c_gpiod_chip_label(long chipPtr); + + static int chipGetNumLines(GpioChip chip) { + return c_gpiod_chip_num_lines(chip.getCPointer()); + } + + private static native int c_gpiod_chip_num_lines(long chipPtr); + + static GpioLine chipGetLine(GpioChip chip, int offset) { + Long linePtr = c_gpiod_chip_get_line(chip.getCPointer(), offset); + if (linePtr == null) { + throw new GpioDException("c_gpiod_chip_get_line failed!"); + } + return new GpioLine(linePtr); + } + private static native Long c_gpiod_chip_get_line(long chipPtr, int offset); + + static void chipGetLines(GpioChip chip, int[] offsets, GpioLineBulk lineBulk) { + if(c_gpiod_chip_get_lines(chip.getCPointer(), offsets, offsets.length, lineBulk.getCPointer()) < 0) { + throw new GpioDException("c_gpiod_chip_get_lines failed!"); + } + } + + private static native int c_gpiod_chip_get_lines(long chipPtr, int[] offsets, int numOffsets, long lineBulkPtr); + + static void chipGetAllLines(GpioChip chip, GpioLineBulk lineBulk) { + if(c_gpiod_chip_get_all_lines(chip.getCPointer(), lineBulk.getCPointer()) < 0) { + throw new GpioDException("c_gpiod_chip_get_all_lines failed!"); + } + } + + private static native int c_gpiod_chip_get_all_lines(long chipPtr, long lineBulkPtr); + + static GpioLine chipGetLine(GpioChip chip, String name) { + Long linePtr = c_gpiod_chip_find_line(chip.getCPointer(), name); + if (linePtr == null) { + throw new GpioDException("c_gpiod_chip_find_line failed!"); + } + return new GpioLine(linePtr); + } + + private static native Long c_gpiod_chip_find_line(long chipPtr, String name); + + static void lineBulkFree(GpioLineBulk lineBulk) { + c_gpiod_line_bulk_free(lineBulk.getCPointer()); + } + + private static native void c_gpiod_line_bulk_free(long lineBulkPtr); + + private static native void gpiod_line_bulk_init(long lineBulkPtr); + + static long lineBulkNew() { + Long ptr = c_gpiod_line_bulk_new(); + if(ptr == null) { + throw new GpioDException("c_gpiod_line_bulk_new failed!"); + } + gpiod_line_bulk_init(ptr); + return ptr; + } + + private static native Long c_gpiod_line_bulk_new(); + + static void lineBulkAdd(GpioLineBulk lineBulk, GpioLine line) { + c_gpiod_line_bulk_add(lineBulk.getCPointer(), line.getCPointer()); + } + + private static native void c_gpiod_line_bulk_add(long lineBulkPtr, long linePtr); + + static GpioLine lineBulkGetLine(GpioLineBulk lineBulk, int offset) { + return new GpioLine(c_gpiod_line_bulk_get_line(lineBulk.getCPointer(), offset)); + } + + private static native long c_gpiod_line_bulk_get_line(long lineBulkPtr, int offset); + + static int lineBulkGetNumLines(GpioLineBulk lineBulk) { + return c_gpiod_line_bulk_num_lines(lineBulk.getCPointer()); + } + + private static native int c_gpiod_line_bulk_num_lines(long lineBulkPtr); + + + public enum LINE_DIRECTION { + INPUT(1), OUTPUT(2); + final int val; + + public int getVal() { + return val; + } + + LINE_DIRECTION(int val) { + this.val = val; + } + + static LINE_DIRECTION fromInt(int val) { + for (LINE_DIRECTION dir : LINE_DIRECTION.values()) { + if (dir.val == val) { + return dir; + } + } + throw new IllegalStateException("Unexpected LINE_DIRECTION value: " + val); + } + } + + public enum LINE_ACTIVE_STATE { + HIGH(1), LOW(2); + final int val; + + public int getVal() { + return val; + } + + LINE_ACTIVE_STATE(int val) { + this.val = val; + } + + static LINE_ACTIVE_STATE fromInt(int val) { + for (LINE_ACTIVE_STATE dir : LINE_ACTIVE_STATE.values()) { + if (dir.val == val) { + return dir; + } + } + throw new IllegalStateException("Unexpected LINE_ACTIVE_STATE value: " + val); + } + } + + public enum LINE_BIAS { + AS_IS(1), DISABLE(2), PULL_UP(3), PULL_DOWN(4); + final int val; + + public int getVal() { + return val; + } + + LINE_BIAS(int val) { + this.val = val; + } + + static LINE_BIAS fromInt(int val) { + for (LINE_BIAS dir : LINE_BIAS.values()) { + if (dir.val == val) { + return dir; + } + } + throw new IllegalStateException("Unexpected LINE_BIAS value: " + val); + } + } + + static int lineGetOffset(GpioLine line) { + return c_gpiod_line_offset(line.getCPointer()); + } + + private static native int c_gpiod_line_offset(long linePtr); + + static String lineGetName(GpioLine line) { + return c_gpiod_line_name(line.getCPointer()); + } + + private static native String c_gpiod_line_name(long linePtr); + + static String lineGetConsumer(GpioLine line) { + return gpiod_line_consumer(line.getCPointer()); + } + + private static native String gpiod_line_consumer(long linePtr); + + static LINE_DIRECTION lineGetDirection(GpioLine line) { + return LINE_DIRECTION.fromInt(c_gpiod_line_direction(line.getCPointer())); + } + + private static native int c_gpiod_line_direction(long linePtr); + + static LINE_ACTIVE_STATE lineGetActiveState(GpioLine line) { + return LINE_ACTIVE_STATE.fromInt(c_gpiod_line_active_state(line.getCPointer())); + } + + private static native int c_gpiod_line_active_state(long linePtr); + + static LINE_BIAS lineGetBias(GpioLine line) { + return LINE_BIAS.fromInt(c_gpiod_line_bias(line.getCPointer())); + } + + private static native int c_gpiod_line_bias(long linePtr); + + static boolean lineIsUsed(GpioLine line) { + return c_gpiod_line_is_used(line.getCPointer()); + } + + private static native boolean c_gpiod_line_is_used(long linePtr); + + static boolean lineIsOpenDrain(GpioLine line) { + return c_gpiod_line_is_open_drain(line.getCPointer()); + } + + private static native boolean c_gpiod_line_is_open_drain(long linePtr); + + static boolean lineIsOpenSource(GpioLine line) { + return c_gpiod_line_is_open_source(line.getCPointer()); + } + + private static native boolean c_gpiod_line_is_open_source(long linePtr); + + static void lineUpdate(GpioLine line) { + if(c_gpiod_line_update(line.getCPointer()) < 0) { + throw new GpioDException("c_gpiod_line_update failed!"); + } + } + + private static native int c_gpiod_line_update(long linePtr); + + public enum LINE_REQUEST { + DIRECTION_AS_IS(1), DIRECTION_INPUT(2), DIRECTION_OUTPUT(3), EVENT_FALLING_EDGE(4), + EVENT_RISING_EDGE(5), EVENT_BOTH_EDGES(6); + final int val; + + public int getVal() { + return val; + } + + LINE_REQUEST(int val) { + this.val = val; + } + + static LINE_REQUEST fromInt(int val) { + for (LINE_REQUEST dir : LINE_REQUEST.values()) { + if (dir.val == val) { + return dir; + } + } + throw new IllegalStateException("Unexpected LINE_REQUEST value: " + val); + } + } + + public enum LINE_REQUEST_FLAG { + OPEN_DRAIN((byte) 1), OPEN_SOURCE((byte) (1 << 1)), ACTIVE_LOW((byte) (1 << 2)), BIAS_DISABLE((byte) (1 << 3)), + BIAS_PULL_DOWN((byte) (1 << 4)), BIAS_PULL_UP((byte) (1 << 5)); + final byte val; + + LINE_REQUEST_FLAG(byte val) { + this.val = val; + } + + public byte getVal() { + return val; + } + + static LINE_REQUEST_FLAG fromByte(byte val) { + for (LINE_REQUEST_FLAG dir : LINE_REQUEST_FLAG.values()) { + if (dir.val == val) { + return dir; + } + } + throw new IllegalStateException("Unexpected LINE_REQUEST_FLAG value: " + val); + } + } + + static void lineRequest(GpioLine line, GpioLineRequest request, int defaultVal) { + if(c_gpiod_line_request(line.getCPointer(), request.getCPointer(), defaultVal) < 0) { + throw new GpioDException("c_gpiod_line_request failed!"); + } + } + + private static native int c_gpiod_line_request(long linePtr, long lineRequestPtr, int default_val); + + static void lineRequestInput(GpioLine line, String consumer) { + if(c_gpiod_line_request_input(line.getCPointer(), consumer) < 0) { + throw new GpioDException("c_gpiod_line_request_input failed!"); + } + } + + private static native int c_gpiod_line_request_input(long linePtr, String consumer); + + static void lineRequestOutput(GpioLine line, String consumer, int defaultVal) { + if(c_gpiod_line_request_output(line.getCPointer(), consumer, defaultVal) < 0) { + throw new GpioDException("c_gpiod_line_request_output failed!"); + } + } + + private static native int c_gpiod_line_request_output(long linePtr, String consumer, int default_val); + + static void lineRequestRisingEdgeEvents(GpioLine line, String consumer) { + if(c_gpiod_line_request_rising_edge_events(line.getCPointer(), consumer) < 0) { + throw new GpioDException("c_gpiod_line_request_rising_edge_events failed!"); + } + } + + private static native int c_gpiod_line_request_rising_edge_events(long linePtr, String consumer); + + static void lineRequestFallingEdgeEvents(GpioLine line, String consumer) { + if(c_gpiod_line_request_falling_edge_events(line.getCPointer(), consumer) < 0) { + throw new GpioDException("c_gpiod_line_request_falling_edge_events failed!"); + } + } + + private static native int c_gpiod_line_request_falling_edge_events(long linePtr, String consumer); + + static void lineRequestBothEdgeEvents(GpioLine line, String consumer) { + if(c_gpiod_line_request_both_edges_events(line.getCPointer(), consumer) < 0) { + throw new GpioDException("c_gpiod_line_request_both_edges_events failed!"); + } + } + + private static native int c_gpiod_line_request_both_edges_events(long linePtr, String consumer); + + static void lineRequestInputFlags(GpioLine line, String consumer, int flags) { + if(c_gpiod_line_request_input_flags(line.getCPointer(), consumer, flags) < 0) { + throw new GpioDException("c_gpiod_line_request_input_flags failed!"); + } + } + + private static native int c_gpiod_line_request_input_flags(long linePtr, String consumer, int flags); + + static void lineRequestOutputFlags(GpioLine line, String consumer, int flags, int defaultVal) { + if(c_gpiod_line_request_output_flags(line.getCPointer(), consumer, flags, defaultVal) < 0) { + throw new GpioDException("c_gpiod_line_request_output_flags failed!"); + } + } + + private static native int c_gpiod_line_request_output_flags(long linePtr, String consumer, int flags, int default_val); + + static void lineRequestRisingEdgeEventsFlags(GpioLine line, String consumer, int flags) { + if(c_gpiod_line_request_rising_edge_events_flags(line.getCPointer(), consumer, flags) < 0) { + throw new GpioDException("c_gpiod_line_request_rising_edge_events_flags failed!"); + } + } + + private static native int c_gpiod_line_request_rising_edge_events_flags(long linePtr, String consumer, int flags); + + static void lineRequestFallingEdgeEventsFlags(GpioLine line, String consumer, int flags) { + if(c_gpiod_line_request_falling_edge_events_flags(line.getCPointer(), consumer, flags) < 0) { + throw new GpioDException("c_gpiod_line_request_falling_edge_events_flags failed!"); + } + } + + private static native int c_gpiod_line_request_falling_edge_events_flags(long linePtr, String consumer, int flags); + + static void lineRequestBothEdgeEventsFlags(GpioLine line, String consumer, int flags) { + if(c_gpiod_line_request_both_edges_events_flags(line.getCPointer(), consumer, flags) < 0) { + throw new GpioDException("c_gpiod_line_request_both_edges_events_flags failed!"); + } + } + + private static native int c_gpiod_line_request_both_edges_events_flags(long linePtr, String consumer, int flags); + + static void lineRequestBulk(GpioLineBulk lineBulk, GpioLineRequest lineRequest, int[] defaultVals) { + if(c_gpiod_line_request_bulk(lineBulk.getCPointer(), lineRequest.getCPointer(), defaultVals) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk failed!"); + } + } + + private static native int c_gpiod_line_request_bulk(long lineBulkPtr, long lineRequestPtr, int[] default_vals); + + static void lineRequestBulkInput(GpioLineBulk lineBulk, String consumer) { + if(c_gpiod_line_request_bulk_input(lineBulk.getCPointer(), consumer) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_input failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_input(long lineBulkPtr, String consumer); + + static void lineRequestBulkOutput(GpioLineBulk lineBulk, String consumer, int[] defaultVals) { + if(c_gpiod_line_request_bulk_output(lineBulk.getCPointer(), consumer, defaultVals) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_output failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_output(long lineBulkPtr, String consumer, int[] default_vals); + + static void lineRequestBulkRisingEdgeEvents(GpioLineBulk lineBulk, String consumer) { + if(c_gpiod_line_request_bulk_rising_edge_events(lineBulk.getCPointer(), consumer) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_rising_edge_events failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_rising_edge_events(long lineBulkPtr, String consumer); + + static void lineRequestBulkFallingEdgeEvents(GpioLineBulk lineBulk, String consumer) { + if(c_gpiod_line_request_bulk_falling_edge_events(lineBulk.getCPointer(), consumer) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_falling_edge_events failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_falling_edge_events(long lineBulkPtr, String consumer); + + static void lineRequestBulkBothEdgeEvents(GpioLineBulk lineBulk, String consumer) { + if(c_gpiod_line_request_bulk_both_edges_events(lineBulk.getCPointer(), consumer) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_both_edges_events failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_both_edges_events(long lineBulkPtr, String consumer); + + static void lineRequestBulkInputFlags(GpioLineBulk lineBulk, String consumer, int flags) { + if(c_gpiod_line_request_bulk_input_flags(lineBulk.getCPointer(), consumer, flags) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_input_flags failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_input_flags(long lineBulkPtr, String consumer, int flags); + + static void lineRequestBulkOutputFlags(GpioLineBulk lineBulk, String consumer, int flags, int[] defaultVals) { + if(c_gpiod_line_request_bulk_output_flags(lineBulk.getCPointer(), consumer, flags, defaultVals) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_output_flags failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_output_flags(long lineBulkPtr, String consumer, int flags, int[] default_vals); + + static void lineRequestBulkRisingEdgeEventFlags(GpioLineBulk lineBulk, String consumer, int flags) { + if(c_gpiod_line_request_bulk_rising_edge_events_flags(lineBulk.getCPointer(), consumer, flags) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_rising_edge_events_flags failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_rising_edge_events_flags(long lineBulkPtr, String consumer, int flags); + + static void lineRequestBulkFallingEdgeEventFlags(GpioLineBulk lineBulk, String consumer, int flags) { + if(c_gpiod_line_request_bulk_falling_edge_events_flags(lineBulk.getCPointer(), consumer, flags) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_falling_edge_events_flags failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_falling_edge_events_flags(long lineBulkPtr, String consumer, int flags); + + static void lineRequestBulkBothEdgeEventFlags(GpioLineBulk lineBulk, String consumer, int flags) { + if(c_gpiod_line_request_bulk_both_edges_events_flags(lineBulk.getCPointer(), consumer, flags) < 0) { + throw new GpioDException("c_gpiod_line_request_bulk_both_edges_events_flags failed!"); + } + } + + private static native int c_gpiod_line_request_bulk_both_edges_events_flags(long lineBulkPtr, String consumer, int flags); + + static void lineRelease(GpioLine line) { + c_gpiod_line_release(line.getCPointer()); + } + + private static native void c_gpiod_line_release(long linePtr); + + static void lineBulkRelease(GpioLineBulk lineBulk) { + c_gpiod_line_release_bulk(lineBulk.getCPointer()); + } + + private static native void c_gpiod_line_release_bulk(long lineBulkPtr); + + static boolean lineIsRequested(GpioLine line) { + return c_gpiod_line_is_requested(line.getCPointer()); + } + + private static native boolean c_gpiod_line_is_requested(long linePtr); + + static boolean lineIsFree(GpioLine line) { + return c_gpiod_line_is_free(line.getCPointer()); + } + + private static native boolean c_gpiod_line_is_free(long linePtr); + + static int lineGetValue(GpioLine line) { + int result = c_gpiod_line_get_value(line.getCPointer()); + if(result < 0) { + throw new GpioDException("c_gpiod_line_get_value failed!"); + } + return result; + } + + private static native int c_gpiod_line_get_value(long linePtr); + + static int[] lineBulkGetValues(GpioLineBulk lineBulk) { + int numVals = lineBulkGetNumLines(lineBulk); + int[] vals = new int[numVals]; + if(c_gpiod_line_get_value_bulk(lineBulk.getCPointer(), vals) < 0) { + throw new GpioDException("c_gpiod_line_get_value_bulk failed!"); + } + return vals; + } + + private static native int c_gpiod_line_get_value_bulk(long lineBulkPtr, int[] values); + + static void lineSetValue(GpioLine line, int value) { + if(c_gpiod_line_set_value(line.getCPointer(), value) < 0) { + throw new GpioDException("c_gpiod_line_set_value failed!"); + } + } + + private static native int c_gpiod_line_set_value(long linePtr, int value); + + static void lineBulkSetValue(GpioLineBulk lineBulk, int[] values) { + if(c_gpiod_line_set_value_bulk(lineBulk.getCPointer(), values) < 0) { + throw new GpioDException("c_gpiod_line_set_value_bulk failed!"); + } + } + + private static native int c_gpiod_line_set_value_bulk(long lineBulkPtr, int[] values); + + static void lineSetConfig(GpioLine line, LINE_REQUEST direction, int flags, int value) { + if(c_gpiod_line_set_config(line.getCPointer(), direction.val, flags, value) < 0) { + throw new GpioDException("c_gpiod_line_set_config failed!"); + } + } + + private static native int c_gpiod_line_set_config(long linePtr, int direction, int flags, int value); + + static void lineBulkSetConfig(GpioLineBulk lineBulk, LINE_REQUEST direction, int flags, int[] values) { + if(c_gpiod_line_set_config_bulk(lineBulk.getCPointer(), direction.val, flags, values) < 0) { + throw new GpioDException("c_gpiod_line_set_config_bulk failed!"); + } + } + + private static native int c_gpiod_line_set_config_bulk(long lineBulkPtr, int direction, int flags, int[] values); + + static void lineSetFlags(GpioLine line, int flags) { + if(c_gpiod_line_set_flags(line.getCPointer(), flags) < 0) { + throw new GpioDException("c_gpiod_line_set_flags failed!"); + } + } + + private static native int c_gpiod_line_set_flags(long linePtr, int flags); + + static void lineBulkSetFlags(GpioLineBulk lineBulk, int flags) { + if(c_gpiod_line_set_flags_bulk(lineBulk.getCPointer(), flags) < 0) { + throw new GpioDException("c_gpiod_line_set_flags_bulk failed!"); + } + } + + private static native int c_gpiod_line_set_flags_bulk(long lineBulkPtr, int flags); + + static void lineSetDirectionInput(GpioLine line) { + if(c_gpiod_line_set_direction_input(line.getCPointer()) < 0) { + throw new GpioDException("c_gpiod_line_set_direction_input failed!"); + } + } + + private static native int c_gpiod_line_set_direction_input(long linePtr); + + static void lineSetDirectionOutputBulk(GpioLineBulk lineBulk) { + if(c_gpiod_line_set_direction_input_bulk(lineBulk.getCPointer()) < 0) { + throw new GpioDException("c_gpiod_line_set_direction_input_bulk failed!"); + } + } + + private static native int c_gpiod_line_set_direction_input_bulk(long lineBulkPtr); + + static void lineSetDirectionOutput(GpioLine line, int value) { + if(c_gpiod_line_set_direction_output(line.getCPointer(), value) < 0) { + throw new GpioDException("c_gpiod_line_set_direction_output failed!"); + } + } + + private static native int c_gpiod_line_set_direction_output(long linePtr, int value); + + static void lineSetDirectionOutputBulk(GpioLineBulk lineBulk, int[] values) { + if(c_gpiod_line_set_direction_output_bulk(lineBulk.getCPointer(), values) < 0) { + throw new GpioDException("c_gpiod_line_set_direction_output_bulk failed!"); + } + } + + private static native int c_gpiod_line_set_direction_output_bulk(long lineBulkPtr, int[] values); + + public enum LINE_EVENT { + RISING_EDGE(1), FALLING_EDGE(2); + final int val; + + public int getVal() { + return val; + } + + LINE_EVENT(int val) { + this.val = val; + } + + static LINE_EVENT fromInt(int val) { + for (LINE_EVENT dir : LINE_EVENT.values()) { + if (dir.val == val) { + return dir; + } + } + throw new IllegalStateException("Unexpected LINE_EVENT value: " + val); + } + } + + static boolean lineEventWait(GpioLine line, long timeoutNs) { + int result = c_gpiod_line_event_wait(line.getCPointer(), timeoutNs); + if(result < 0) { + throw new GpioDException("c_gpiod_line_event_wait failed!"); + } + return result > 0; + } + + private static native int c_gpiod_line_event_wait(long linePtr, long timeoutNs); + + static boolean lineBulkEventWait(GpioLineBulk lineBulk, long timeoutNs, GpioLineBulk eventBulk) { + int result = c_gpiod_line_event_wait_bulk(lineBulk.getCPointer(), timeoutNs, eventBulk.getCPointer()); + if(result < 0) { + throw new GpioDException("c_gpiod_line_event_wait_bulk failed!"); + } + return result > 0; + } + + private static native int c_gpiod_line_event_wait_bulk(long lineBulkPtr, long timeoutNs, long eventBulkPtr); + + static boolean lineEventRead(GpioLine line, GpioLineEvent event) { + int result = c_gpiod_line_event_read(line.getCPointer(), event.getCPointer()); + if(result < 0) { + throw new GpioDException("c_gpiod_line_event_read failed!"); + } + return result > 0; + } + + private static native int c_gpiod_line_event_read(long linePtr, long eventPtr); + + static GpioLineEvent[] lineEventReadMultiple(GpioLine line, int maxRead) { + GpioLineEvent[] events = new GpioLineEvent[maxRead]; + for(int i = 0; i < events.length; i++) { + events[i] = new GpioLineEvent(); + } + + int numRead = c_gpiod_line_event_read_multiple(line.getCPointer(), + Arrays.stream(events).mapToLong(GpioLineEvent::getCPointer).toArray(), events.length); + if(numRead < 0) { + throw new GpioDException("c_gpiod_line_event_read_multiple failed!"); + } + + GpioLineEvent[] result = new GpioLineEvent[numRead]; + if(numRead == maxRead) { + result = events; + } else { + System.arraycopy(events, 0, result, 0, result.length); + } + return result; + } + + private static native int c_gpiod_line_event_read_multiple(long linePtr, long[] eventPtr, int num_events); + + static GpioLine lineGet(String device, int offset) { + Long ptr = c_gpiod_line_get(device, offset); + if(ptr == null) { + throw new GpioDException("c_gpiod_line_get failed!"); + } + return new GpioLine(ptr); + } + + private static native Long c_gpiod_line_get(String device, int offset); + + static GpioLine lineFind(String name) { + Long ptr = gpiod_line_find(name); + if(ptr == null) { + throw new GpioDException("gpiod_line_find failed!"); + } + return new GpioLine(ptr); + } + + private static native Long gpiod_line_find(String name); + + static void lineCloseChip(GpioLine line) { + c_gpiod_line_close_chip(line.getCPointer()); + } + + private static native void c_gpiod_line_close_chip(long linePtr); + + static GpioChip lineGetChip(GpioLine line) { + return new GpioChip(gpiod_line_get_chip(line.getCPointer())); + } + + private static native long gpiod_line_get_chip(long linePtr); + + static long chipIterNew() { + Long ptr = gpiod_chip_iter_new(); + if(ptr == null) { + throw new GpioDException("gpiod_chip_iter_new failed!"); + } + return ptr; + } + + private static native Long gpiod_chip_iter_new(); + + static void chipIterFree(GpioChipIterator iter) { + c_gpiod_chip_iter_free(iter.getCPointer()); + } + + private static native void c_gpiod_chip_iter_free(long chipIterPtr); + + static void chipIterFreeNoClose(GpioChipIterator iter) { + c_gpiod_chip_iter_free_noclose(iter.getCPointer()); + } + + private static native void c_gpiod_chip_iter_free_noclose(long chipIterPtr); + + static GpioChip chipIterNext(GpioChipIterator iter) { + Long ptr = c_gpiod_chip_iter_next(iter.getCPointer()); + if(ptr == null) { + return null; + } + return new GpioChip(ptr); + } + + private static native Long c_gpiod_chip_iter_next(long chipIterPtr); + + static GpioChip chipIterNextNoClose(GpioChipIterator iter) { + Long ptr = c_gpiod_chip_iter_next_noclose(iter.getCPointer()); + if(ptr == null) { + return null; + } + return new GpioChip(ptr); + } + + private static native Long c_gpiod_chip_iter_next_noclose(long chipIterPtr); + + static long lineIterNew(GpioChip chip) { + Long ptr = gpiod_line_iter_new(chip.getCPointer()); + if(ptr == null) { + throw new GpioDException("gpiod_line_iter_new failed!"); + } + return ptr; + } + + private static native Long gpiod_line_iter_new(long chipPtr); + + static void lineIterFree(GpioLineIterator iter) { + gpiod_line_iter_free(iter.getCPointer()); + } + + private static native void gpiod_line_iter_free(long lineIterPtr); + + static GpioLine lineIterNext(GpioLineIterator iter) { + Long ptr = gpiod_line_iter_next(iter.getCPointer()); + if(ptr == null) { + return null; + } + return new GpioLine(ptr); + } + + private static native Long gpiod_line_iter_next(long lineIterPtr); + + static long lineEventGetTimespec(GpioLineEvent event) { + return c_gpiod_line_event_get_timespec(event.getCPointer()); + } + + private static native long c_gpiod_line_event_get_timespec(long lineEventPtr); + + static LINE_EVENT lineEventGetType(GpioLineEvent event) { + return LINE_EVENT.fromInt(c_gpiod_line_event_get_type(event.getCPointer())); + } + + private static native int c_gpiod_line_event_get_type(long lineEventPtr); + + static long lineEventNew() { + Long ptr = c_gpiod_line_event_new(); + if(ptr == null) { + throw new GpioDException("c_gpiod_line_event_new failed!"); + } + return ptr; + } + + private static native Long c_gpiod_line_event_new(); + + static void lineEventFree(GpioLineEvent event) { + c_gpiod_line_event_free(event.getCPointer()); + } + + private static native void c_gpiod_line_event_free(long eventPtr); + + static String getVersion() { + return c_gpiod_version_string(); + } + + private static native String c_gpiod_version_string(); + +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioDException.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioDException.java new file mode 100644 index 00000000..849811b6 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioDException.java @@ -0,0 +1,17 @@ +package com.pi4j.library.gpiod.internal; + +/** + *

GpioDException

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioDException extends RuntimeException { + public GpioDException() { + super(); + } + + public GpioDException(String msg) { + super(msg); + } +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLine.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLine.java new file mode 100644 index 00000000..f50a6176 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLine.java @@ -0,0 +1,151 @@ +package com.pi4j.library.gpiod.internal; + +import java.util.Objects; + +/** + *

GpioLine

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioLine extends CWrapper { + + GpioLine(long cPointer) { + super(cPointer); + } + + public int getOffset() { + return GpioD.lineGetOffset(this); + } + + public String getName() { + return GpioD.lineGetName(this); + } + + public String getConsumer() { + return GpioD.lineGetConsumer(this); + } + + public GpioD.LINE_DIRECTION getDirection() { + return GpioD.lineGetDirection(this); + } + + public GpioD.LINE_ACTIVE_STATE getActiveState() { + return GpioD.lineGetActiveState(this); + } + + public GpioD.LINE_BIAS getBias() { + return GpioD.lineGetBias(this); + } + + public boolean isUsed() { + return GpioD.lineIsUsed(this); + } + + public boolean isOpenDrain() { + return GpioD.lineIsOpenDrain(this); + } + + public boolean isOpenSource() { + return GpioD.lineIsOpenSource(this); + } + + public void update() { + GpioD.lineUpdate(this); + } + + public void request(GpioLineRequest config, int defaultVal) { + GpioD.lineRequest(this, config, defaultVal); + } + + public void requestInput(String consumer) { + GpioD.lineRequestInput(this, consumer); + } + + public void requestOutput(String consumer, int defaultVal) { + GpioD.lineRequestOutput(this, consumer, defaultVal); + } + + public void requestRisingEdgeEvents(String consumer) { + GpioD.lineRequestRisingEdgeEvents(this, consumer); + } + + public void requestFallingEdgeEvents(String consumer) { + GpioD.lineRequestFallingEdgeEvents(this, consumer); + } + + public void requestBothEdgeEvents(String consumer) { + GpioD.lineRequestBothEdgeEvents(this, consumer); + } + + public void requestInputFlags(String consumer, int flags) { + GpioD.lineRequestInputFlags(this, consumer, flags); + } + + public void requestOutputFlags(String consumer, int flags, int defaultValue) { + GpioD.lineRequestOutputFlags(this, consumer, flags, defaultValue); + } + + public void requestRisingEdgeEventsFlags(String consumer, int flags) { + GpioD.lineRequestRisingEdgeEventsFlags(this, consumer, flags); + } + + public void requestFallingEdgeEventsFlags(String consumer, int flags) { + GpioD.lineRequestFallingEdgeEventsFlags(this, consumer, flags); + } + + public void requestBothEdgeEventsFlags(String consumer, int flags) { + GpioD.lineRequestBothEdgeEventsFlags(this, consumer, flags); + } + + public void release() { + GpioD.lineRelease(this); + } + + public boolean isRequested() { + return GpioD.lineIsRequested(this); + } + + public boolean isFree() { + return GpioD.lineIsFree(this); + } + + public int getValue() { + return GpioD.lineGetValue(this); + } + + public void setValue(int value) { + GpioD.lineSetValue(this, value); + } + + public void setConfig(GpioD.LINE_REQUEST direction, int flags, int value) { + GpioD.lineSetConfig(this, direction, flags, value); + } + + public void setFlags(int flags) { + GpioD.lineSetFlags(this, flags); + } + + public void setDirectionInput() { + GpioD.lineSetDirectionInput(this); + } + + public void setDirectionOutput(int value) { + GpioD.lineSetDirectionOutput(this, value); + } + + public boolean eventWait(long timeoutNs) { + return GpioD.lineEventWait(this, timeoutNs); + } + + public GpioLineEvent eventRead() { + GpioLineEvent event = new GpioLineEvent(); + GpioD.lineEventRead(this, event); + return event; + } + + public GpioLineEvent[] eventReadMultiple(int maxRead) { + return GpioD.lineEventReadMultiple(this, maxRead); + } + +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineBulk.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineBulk.java new file mode 100644 index 00000000..21cf0840 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineBulk.java @@ -0,0 +1,114 @@ +package com.pi4j.library.gpiod.internal; + +/** + *

GpioLineBulk

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioLineBulk extends CWrapper { + + GpioLineBulk(long cPointer) { + super(cPointer); + } + + public GpioLineBulk() { + this(GpioD.lineBulkNew()); + } + + @Override + protected void finalize() { + GpioD.lineBulkFree(this); + } + + public void add(GpioLine line) { + GpioD.lineBulkAdd(this, line); + } + + public GpioLine getLine(int index) { + return GpioD.lineBulkGetLine(this, index); + } + + public int getNumLines() { + return GpioD.lineBulkGetNumLines(this); + } + + public void request(GpioLineRequest config, int[] defaultVals) { + GpioD.lineRequestBulk(this, config, defaultVals); + } + + public void requestInput(String consumer) { + GpioD.lineRequestBulkInput(this, consumer); + } + + public void requestOutput(String consumer, int[] defaultVals) { + GpioD.lineRequestBulkOutput(this, consumer, defaultVals); + } + + public void requestRisingEdgeEvents(String consumer) { + GpioD.lineRequestBulkRisingEdgeEvents(this, consumer); + } + + public void requestFallingEdgeEvents(String consumer) { + GpioD.lineRequestBulkFallingEdgeEvents(this, consumer); + } + + public void requestBothEdgeEvents(String consumer) { + GpioD.lineRequestBulkBothEdgeEvents(this, consumer); + } + + public void requestInputFlags(String consumer, int flags) { + GpioD.lineRequestBulkInputFlags(this, consumer, flags); + } + + public void requestOutputFlags(String consumer, int flags, int[] defaultValue) { + GpioD.lineRequestBulkOutputFlags(this, consumer, flags, defaultValue); + } + + public void requestRisingEdgeEventsFlags(String consumer, int flags) { + GpioD.lineRequestBulkRisingEdgeEventFlags(this, consumer, flags); + } + + public void requestFallingEdgeEventsFlags(String consumer, int flags) { + GpioD.lineRequestBulkFallingEdgeEventFlags(this, consumer, flags); + } + + public void requestBothEdgeEventsFlags(String consumer, int flags) { + GpioD.lineRequestBulkBothEdgeEventFlags(this, consumer, flags); + } + + public void release() { + GpioD.lineBulkRelease(this); + } + + public int[] getValues() { + return GpioD.lineBulkGetValues(this); + } + + public void setValue(int[] values) { + GpioD.lineBulkSetValue(this, values); + } + + public void setConfig(GpioD.LINE_REQUEST direction, int flags, int[] values) { + GpioD.lineBulkSetConfig(this, direction, flags, values); + } + + public void setFlags(int flags) { + GpioD.lineBulkSetFlags(this, flags); + } + + public void setDirectionInput() { + GpioD.lineSetDirectionOutputBulk(this); + } + + public void setDirectionOutput(int[] values) { + GpioD.lineSetDirectionOutputBulk(this, values); + } + + public GpioLineBulk eventWait(long timeoutNs) { + GpioLineBulk bulk = new GpioLineBulk(); + GpioD.lineBulkEventWait(this, timeoutNs, bulk); + return bulk; + } + +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineEvent.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineEvent.java new file mode 100644 index 00000000..29a617e8 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineEvent.java @@ -0,0 +1,31 @@ +package com.pi4j.library.gpiod.internal; + +/** + *

GpioLineEvent

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioLineEvent extends CWrapper { + + GpioLineEvent(long cPointer) { + super(cPointer); + } + + public GpioLineEvent() { + this(GpioD.lineEventNew()); + } + + @Override + protected void finalize() { + GpioD.lineEventFree(this); + } + + public long getTimeNs() { + return GpioD.lineEventGetTimespec(this); + } + + public GpioD.LINE_EVENT getType() { + return GpioD.lineEventGetType(this); + } +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineIterator.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineIterator.java new file mode 100644 index 00000000..9b216bf2 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineIterator.java @@ -0,0 +1,41 @@ +package com.pi4j.library.gpiod.internal; + +import java.util.Iterator; + +/** + *

GpioLineIterator

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioLineIterator extends CWrapper implements Iterator { + + private GpioLine next; + + GpioLineIterator(long cPointer) { + super(cPointer); + } + + public GpioLineIterator(GpioChip chip) { + this(GpioD.lineIterNew(chip)); + } + + @Override + public boolean hasNext() { + if(next == null) { + next = GpioD.lineIterNext(this); + } + return next != null; + } + + @Override + public GpioLine next() { + GpioLine current; + if(next == null) { + next = GpioD.lineIterNext(this); + } + current = next; + next = null; + return current; + } +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineRequest.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineRequest.java new file mode 100644 index 00000000..52ba3a4e --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/internal/GpioLineRequest.java @@ -0,0 +1,15 @@ +package com.pi4j.library.gpiod.internal; + +/** + *

GpioLineRequest

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioLineRequest extends CWrapper { + + GpioLineRequest(long cPointer) { + super(cPointer); + } + +} diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/util/NativeLibraryLoader.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/util/NativeLibraryLoader.java new file mode 100644 index 00000000..24ac868e --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/util/NativeLibraryLoader.java @@ -0,0 +1,258 @@ +package com.pi4j.library.gpiod.util; +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: JNI Wrapper for LinuxFS Library + * FILENAME : NativeLibraryLoader.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.Set; +import java.util.TreeSet; + +public class NativeLibraryLoader { + + private static final Set loadedLibraries = new TreeSet<>(); + protected static final Logger logger = LoggerFactory.getLogger(NativeLibraryLoader.class); + private static boolean initialized; + + // private constructor + private NativeLibraryLoader() { + // forbid object construction + } + + public static synchronized void load(String fileName, String libName) { + // check for debug property; if found enable all logging levels + if (!initialized) { + initialized = true; + } + + // first, make sure that this library has not already been previously loaded + if (loadedLibraries.contains(fileName)) { + logger.warn("Library [" + fileName + "] has already been loaded; no need to load again."); + return; + } + + // cache loaded library + loadedLibraries.add(fileName); + + // determine if there is an overriding library path defined for native libraries + String libpath = System.getProperty("pi4j.library.path"); + if(StringUtil.isNotNullOrEmpty(libpath, true)) { + + // if the overriding library path is set to "system", then attempt to use the system resolved library paths + if (libpath.equalsIgnoreCase("system")) { + logger.debug("Attempting to load library using {pi4j.library.path} system resolved library name: [" + libName + "]"); + try { + // load library from JVM system library path; based on library name + System.loadLibrary(libName); + } + catch (Exception ex){ + //throw this error + throw new UnsatisfiedLinkError("Pi4J was unable load the native library [" + + libName + "] from the system defined library path. The system property 'pi4j.library.path' is defined as [" + + libpath + "]. You can alternatively define the 'pi4j.library.path' " + + "system property to override this behavior and specify an absolute library path." + + "; UNDERLYING EXCEPTION: [" + ex.getClass().getName() + "]=" + ex.getMessage()); + } + } + + // if the overriding library path is set to "local", then attempt to use the JAR local path to resolve library + else if (libpath.equalsIgnoreCase("local")) { + // get local directory path of JAR file + try { + libpath = NativeLibraryLoader.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); + } catch (URISyntaxException e) { + logger.error(e.getMessage(), e); + libpath = "."; + } + // build path based on lib directory and lib filename + String path = Paths.get(libpath, fileName).toString(); + logger.debug("Attempting to load library using {pi4j.library.path} defined path: [" + path + "]"); + try { + // load library from local path of this JAR file + System.load(path); + } + catch (Exception ex){ + //throw this error + throw new UnsatisfiedLinkError("Pi4J was unable load the native library [" + + libName + "] from the user defined library path. The system property 'pi4j.library.path' is defined as [" + + libpath + "]. Please make sure the defined the 'pi4j.library.path' " + + "system property contains the correct absolute library path." + + "; UNDERLYING EXCEPTION: [" + ex.getClass().getName() + "]=" + ex.getMessage()); + } + } + + // if the overriding library path is set to something else, then attempt to use the defined path to resolve library + else { + // build path based on lib directory and lib filename + String path = Paths.get(libpath, fileName).toString(); + logger.debug("Attempting to load library using {pi4j.library.path} defined path: [" + path + "]"); + try { + // load library from user defined absolute path provided via pi4j.library.path} + System.load(path); + } catch (UnsatisfiedLinkError ex) { + String exceptMessage; + // no guarantee the except pertains to ELF miss-match so check MSG content + if (ex.getMessage().contains("wrong ELF class")) { + exceptMessage = "Pi4J was unable to link the native library [" + + path + "] embedded inside this JAR [" + + NativeLibraryLoader.class.getProtectionDomain().getCodeSource().getLocation().getPath() + + "]. The exception indicates a mismatch of architecture. armhf/ELFCLASS32 aarch64/ELFCLASS64 \n" + + " UNDERLYING EXCEPTION: [" + ex.getClass().getName() + "]=" + ex.getMessage(); + } else { + exceptMessage = "Pi4J was unable to extract and load the native library [" + + path + "] from the embedded resources inside this JAR [" + + NativeLibraryLoader.class.getProtectionDomain().getCodeSource().getLocation().getPath() + + "]. to a temporary location on this system. You can alternatively define the 'pi4j.library.path' " + + "system property to override this behavior and specify the library path.\n" + + " UNDERLYING EXCEPTION: [" + ex.getClass().getName() + "]=" + ex.getMessage(); + } + throw new UnsatisfiedLinkError(exceptMessage); + } catch (Exception ex) { + throw new UnsatisfiedLinkError("Pi4J was unable to extract and load the native library [" + + path + "] from the embedded resources inside this JAR [" + + NativeLibraryLoader.class.getProtectionDomain().getCodeSource().getLocation().getPath() + + "]. to a temporary location on this system. You can alternatively define the 'pi4j.library.path' " + + "system property to override this behavior and specify the library path.\n" + + " UNDERLYING EXCEPTION: [" + ex.getClass().getName() + "]=" + ex.getMessage()); + } + } + } + + // if there is no overriding library path defined, then attempt to load native library from embedded resource + else { + // get CPU architecture from system properties + String osArch = System.getProperty("os.arch").toLowerCase(); + + // sanitize CPU architecture string + switch (osArch) { + case "arm": + osArch = "armhf"; + break; + case "arm64": + osArch = "aarch64"; + break; + case "aarch64": + break; + default: + throw new IllegalStateException("Pi4J has detected and UNKNOWN/UNSUPPORTED 'os.arch' : [" + + osArch + "]; only 'arm|armhf' and 'arm64|aarch64' are supported."); + } + + // include the CPU architecture in the embedded path + String path = "/lib/" + osArch + "/" + libName + "/" + fileName; + logger.debug("Attempting to load library [" + fileName + "] using path: [" + path + "]"); + try { + loadLibraryFromClasspath(path); + logger.debug("Library [" + fileName + "] loaded successfully using embedded resource file: [" + path + "]"); + } catch (UnsatisfiedLinkError e) { + logger.error("Unable to load [" + fileName + "] using path: [" + path + "]", e); + String exceptMessage; + // no guarantee the except pertains to ELF miss-match so check MSG content + if (e.getMessage().contains("wrong ELF class")) { + exceptMessage = "Pi4J was unable to link the native library [" + + path + "] embedded inside this JAR [" + + NativeLibraryLoader.class.getProtectionDomain().getCodeSource().getLocation().getPath() + + "]. The exception indicates a mismatch of architecture. armhf/ELFCLASS32 aarch64/ELFCLASS64 \n" + + " All native libraries must be of architecture " + osArch + " \n" + + " UNDERLYING EXCEPTION: [" + e.getClass().getName() + "]=" + e.getMessage(); + } else { + exceptMessage = "Pi4J was unable to extract and load the native library [" + + path + "] from the embedded resources inside this JAR [" + + NativeLibraryLoader.class.getProtectionDomain().getCodeSource().getLocation().getPath() + + "]. to a temporary location on this system. You can alternatively define the 'pi4j.library.path' " + + "system property to override this behavior and specify the library path.\n" + + " UNDERLYING EXCEPTION: [" + e.getClass().getName() + "]=" + e.getMessage(); + } + throw new UnsatisfiedLinkError(exceptMessage); + } catch (Exception e) { + logger.error("Unable to load [" + fileName + "] using path: [" + path + "]", e); + throw new UnsatisfiedLinkError("Pi4J was unable to extract and load the native library [" + + path + "] from the embedded resources inside this JAR [" + + NativeLibraryLoader.class.getProtectionDomain().getCodeSource().getLocation().getPath() + + "]. to a temporary location on this system. You can alternatively define the 'pi4j.library.path' " + + "system property to override this behavior and specify the library path.\n" + + " UNDERLYING EXCEPTION: [" + e.getClass().getName() + "]=" + e.getMessage()); + } + } + } + + /** + * Loads library from classpath + * + * The file from classpath is copied into system temporary directory and then loaded. The temporary file is + * deleted after exiting. Method uses String as filename because the pathname is + * "abstract", not system-dependent. + * + * @param path + * The file path in classpath as an absolute path, e.g. /package/File.ext (could be inside jar) + * @throws IOException + * If temporary file creation or read/write operation fails + * @throws IllegalArgumentException + * If source file (param path) does not exist + * @throws IllegalArgumentException + * If the path is not absolute or if the filename is shorter than three characters (restriction + * of {@see File#createTempFile(java.lang.String, java.lang.String)}). + */ + public static void loadLibraryFromClasspath(String path) throws IOException { + Path inputPath = Paths.get(path); + + if (!inputPath.isAbsolute()) { + throw new IllegalArgumentException("The path has to be absolute, but found: " + inputPath); + } + + String fileNameFull = inputPath.getFileName().toString(); + int dotIndex = fileNameFull.indexOf('.'); + if (dotIndex < 0 || dotIndex >= fileNameFull.length() - 1) { + throw new IllegalArgumentException("The path has to end with a file name and extension, but found: " + fileNameFull); + } + + String fileName = fileNameFull.substring(0, dotIndex); + String extension = fileNameFull.substring(dotIndex); + + Path target = Files.createTempFile(fileName, extension); + File targetFile = target.toFile(); + targetFile.deleteOnExit(); + + try (InputStream source = NativeLibraryLoader.class.getResourceAsStream(inputPath.toString())) { + if (source == null) { + throw new FileNotFoundException("File " + inputPath + " was not found in classpath."); + } + Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); + } + // Finally, load the library + System.load(target.toAbsolutePath().toString()); + } +} \ No newline at end of file diff --git a/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/util/StringUtil.java b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/util/StringUtil.java new file mode 100644 index 00000000..b4c14097 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/com/pi4j/library/gpiod/util/StringUtil.java @@ -0,0 +1,634 @@ +package com.pi4j.library.gpiod.util; +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: JNI Wrapper for LinuxFS Library + * FILENAME : StringUtil.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + + +import java.nio.ByteBuffer; +import java.util.Arrays; + +/** + *

StringUtil class.

+ * + * @author Robert Savage (http://www.savagehomeautomation.com) + * @version $Id: $Id + */ +public class StringUtil { + + /** Constant EMPTY="" */ + public static final String EMPTY = ""; + /** Constant DEFAULT_PAD_CHAR=' ' */ + public static final char DEFAULT_PAD_CHAR = ' '; + + /** + *

isNullOrEmpty.

+ * + * @param data a {@link String} object. + * @param trim a boolean. + * @return a boolean. + */ + public static boolean isNullOrEmpty(String data, boolean trim){ + if(data == null) + return true; + + // trim if requested + String test = data; + if(trim) + test = data.trim(); + + return (test.length() <= 0); + } + + /** + *

isNullOrEmpty.

+ * + * @param data a {@link String} object. + * @return a boolean. + */ + public static boolean isNullOrEmpty(String data){ + return isNullOrEmpty(data, false); + } + + /** + *

isNotNullOrEmpty.

+ * + * @param data a {@link String} object. + * @return a boolean. + */ + public static boolean isNotNullOrEmpty(String data){ + return isNotNullOrEmpty(data, false); + } + + /** + *

isNotNullOrEmpty.

+ * + * @param data a {@link String} object. + * @param trim a boolean. + * @return a boolean. + */ + public static boolean isNotNullOrEmpty(String data, boolean trim){ + return !(isNullOrEmpty(data, trim)); + } + + /** + *

setIfNullOrEmpty.

+ * + * @param data a {@link String} object. + * @param replacement a {@link String} object. + * @param trim a boolean. + * @return a {@link String} object. + */ + public static String setIfNullOrEmpty(String data, String replacement, boolean trim){ + if(isNullOrEmpty(data, trim)) { + return replacement; + } + return data; + } + + /** + *

setIfNullOrEmpty.

+ * + * @param data a {@link String} object. + * @param replacement a {@link String} object. + * @return a {@link String} object. + */ + public static String setIfNullOrEmpty(String data, String replacement){ + return setIfNullOrEmpty(data, replacement, false); + } + + /** + *

contains.

+ * + * @param source a {@link String} object. + * @param target a {@link String} object. + * @return a boolean. + */ + public static boolean contains(String source, String target) { + return (null != source && null != target && source.contains(target)); + } + + /** + *

contains.

+ * + * @param source a {@link String} object. + * @param targets an array of {@link String} objects. + * @return a boolean. + */ + public static boolean contains(String source, String[] targets) { + if (null != source && null != targets) { + for(var target : targets) { + if (source.contains(target)) { + return true; + } + } + } + return false; + } + + /** + *

contains.

+ * + * @param sources an array of {@link String} objects. + * @param target a {@link String} object. + * @return a boolean. + */ + public static boolean contains(String[] sources, String target) { + if (null != sources && null != target) { + for (var source : sources) { + if(contains(source, target)) + return true; + } + } + return false; + } + + /** + *

contains.

+ * + * @param sources an array of {@link String} objects. + * @param targets an array of {@link String} objects. + * @return a boolean. + */ + public static boolean contains(String[] sources, String[] targets) { + if (null != sources && null != targets) { + for (var source : sources) { + if(contains(source, targets)) + return true; + } + } + return false; + } + + /** + *

create.

+ * + * @param length a int. + * @return a {@link String} object. + */ + public static String create(int length) { + return create(DEFAULT_PAD_CHAR, length); + } + + /** + *

create.

+ * + * @param c a char. + * @param length a int. + * @return a {@link String} object. + */ + public static String create(char c, int length) { + StringBuilder sb = new StringBuilder(length); + for(var index = 0; index < length; index++) + sb.append(c); + return sb.toString(); + } + + /** + *

create.

+ * + * @param s a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String create(String s, int length) { + StringBuilder sb = new StringBuilder(length * s.length()); + for(var index = 0; index < length; index++) + sb.append(s); + return sb.toString(); + } + + /** + *

repeat.

+ * + * @param c a char. + * @param length a int. + * @return a {@link String} object. + */ + public static String repeat(char c, int length) { + return create(c, length); + } + + /** + *

repeat.

+ * + * @param s a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String repeat(String s, int length) { + return create(s, length); + } + + /** + *

padLeft.

+ * + * @param data a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String padLeft(String data, int length) { + return padLeft(data, DEFAULT_PAD_CHAR, length); + } + + /** + *

padLeft.

+ * + * @param data a {@link String} object. + * @param pad a char. + * @param length a int. + * @return a {@link String} object. + */ + public static String padLeft(String data, char pad, int length) { + var sb = new StringBuilder(data.length() + length); + for(var index = 0; index < length; index++) + sb.append(pad); + sb.append(data); + return sb.toString(); + } + + /** + *

padLeft.

+ * + * @param data a {@link String} object. + * @param pad a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String padLeft(String data, String pad, int length) { + var sb = new StringBuilder(data.length() + (length * pad.length())); + for(var index = 0; index < length; index++) + sb.append(pad); + sb.append(data); + return sb.toString(); + } + + /** + *

padRight.

+ * + * @param data a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String padRight(String data, int length) { + return padRight(data, DEFAULT_PAD_CHAR, length); + } + + /** + *

padRight.

+ * + * @param data a {@link String} object. + * @param pad a char. + * @param length a int. + * @return a {@link String} object. + */ + public static String padRight(String data, char pad, int length) { + var sb = new StringBuilder(data.length() + length); + sb.append(data); + for(var index = 0; index < length; index++) + sb.append(pad); + return sb.toString(); + } + + /** + *

padRight.

+ * + * @param data a {@link String} object. + * @param pad a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String padRight(String data, String pad, int length) { + var sb = new StringBuilder(data.length() + (length * pad.length())); + sb.append(data); + for(var index = 0; index < length; index++) + sb.append(pad); + return sb.toString(); + } + + /** + *

pad.

+ * + * @param data a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String pad(String data, int length) { + return pad(data, DEFAULT_PAD_CHAR, length); + } + + /** + *

pad.

+ * + * @param data a {@link String} object. + * @param pad a char. + * @param length a int. + * @return a {@link String} object. + */ + public static String pad(String data, char pad, int length) { + return create(pad, length) + data + create(pad, length); + } + + /** + *

pad.

+ * + * @param data a {@link String} object. + * @param pad a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String pad(String data, String pad, int length) { + return create(pad, length) + data + create(pad, length); + } + + /** + *

padCenter.

+ * + * @param data a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String padCenter(String data, int length) { + return padCenter(data, DEFAULT_PAD_CHAR, length); + } + + /** + *

padCenter.

+ * + * @param data a {@link String} object. + * @param pad a char. + * @param length a int. + * @return a {@link String} object. + */ + public static String padCenter(String data, char pad, int length) { + if(data.length() < length) { + int needed = length - data.length(); + int padNeeded = needed / 2; + StringBuilder result = new StringBuilder(); + result.append(create(pad, padNeeded)); + result.append(data); + result.append(create(pad, padNeeded)); + int remaining = length - result.length(); + result.append(create(pad, remaining)); + return result.toString(); + } + return data; + } + + /** + *

trimLeft.

+ * + * @param data a {@link String} object. + * @return a {@link String} object. + */ + public static String trimLeft(String data) { + return trimLeft(data, DEFAULT_PAD_CHAR); + } + + /** + *

trimLeft.

+ * + * @param data a {@link String} object. + * @param trim a char. + * @return a {@link String} object. + */ + public static String trimLeft(String data, char trim) { + for(var index = 0; index < data.length(); index++) + if(!(data.charAt(index) == trim)) + return data.substring(index); + return EMPTY; + } + + /** + *

trimRight.

+ * + * @param data a {@link String} object. + * @return a {@link String} object. + */ + public static String trimRight(String data) { + return trimRight(data, DEFAULT_PAD_CHAR); + } + + /** + *

trimRight.

+ * + * @param data a {@link String} object. + * @param trim a char. + * @return a {@link String} object. + */ + public static String trimRight(String data, char trim) { + int count = 0; + for(var index = data.length(); index > 0; index--) + if(data.charAt(index-1) == trim) + count++; + else + return data.substring(0, data.length() - count); + return EMPTY; + } + + /** + *

trim.

+ * + * @param data a {@link String} object. + * @return a {@link String} object. + */ + public static String trim(String data) { + return trim(data, DEFAULT_PAD_CHAR); + } + + /** + *

trim.

+ * + * @param data a {@link String} object. + * @param trim a char. + * @return a {@link String} object. + */ + public static String trim(String data, char trim) { + var result = trimLeft(data, trim); + return trimRight(result, trim); + } + + /** + *

center.

+ * + * @param text a {@link String} object. + * @param length a int. + * @return a {@link String} object. + */ + public static String center(String text, int length){ + var out = String.format("%"+length+"s%s%"+length+"s", "",text,""); + var mid = (out.length()/2); + var start = mid - (length/2); + var end = start + length; + return out.substring((int) start, (int) end); + } + + /** + *

concat.

+ * + * @param data a {@link String} object. + * @return a {@link String} object. + */ + public static String concat(String ... data) { + var sb = new StringBuilder(); + for(var d : data){ + sb.append(d); + } + return sb.toString(); + } + + /** + *

appendHexString.

+ * + * @param builder a {@link StringBuilder} object. + * @param byt a byte. + */ + public static void appendHexString(StringBuilder builder, byte byt){ + builder.append(String.format("%02X", byt)); + } + /** + *

toHexString.

+ * + * @param byt a byte. + * @return a {@link String} object. + */ + public static String toHexString(byte byt){ + return String.format("%02X", byt); + } + + /** + *

appendHexString.

+ * + * @param builder a {@link StringBuilder} object. + * @param byt a int. + */ + public static void appendHexString(StringBuilder builder, int byt){ + builder.append(String.format("%02X", (byte)byt)); + } + /** + *

toHexString.

+ * + * @param byt a int. + * @return a {@link String} object. + */ + public static String toHexString(int byt){ + return String.format("%02X", (byte)byt); + } + + /** + *

appendHexString.

+ * + * @param builder a {@link StringBuilder} object. + * @param bytes an array of {@link byte} objects. + */ + public static void appendHexString(StringBuilder builder, byte[] bytes){ + for (byte b : bytes) { + builder.append(String.format("%02X ", b)); + } + } + /** + *

toHexString.

+ * + * @param bytes an array of {@link byte} objects. + * @return a {@link String} object. + */ + public static String toHexString(byte[] bytes){ + StringBuilder sb = new StringBuilder(); + appendHexString(sb, bytes); + return sb.toString().trim(); + } + + /** + *

appendHexString.

+ * + * @param builder a {@link StringBuilder} object. + * @param buffer a {@link ByteBuffer} object. + */ + public static void appendHexString(StringBuilder builder, ByteBuffer buffer){ + appendHexString(builder, buffer.array()); + } + /** + *

toHexString.

+ * + * @param buffer a {@link ByteBuffer} object. + * @return a {@link String} object. + */ + public static String toHexString(ByteBuffer buffer){ + StringBuilder sb = new StringBuilder(); + appendHexString(sb, buffer); + return sb.toString().trim(); + } + + /** + *

appendHexString.

+ * + * @param builder a {@link StringBuilder} object. + * @param bytes an array of {@link byte} objects. + * @param offset a int. + * @param length a int. + */ + public static void appendHexString(StringBuilder builder, byte[] bytes, int offset, int length){ + appendHexString(builder, Arrays.copyOfRange(bytes, offset, length)); + } + /** + *

toHexString.

+ * + * @param bytes an array of {@link byte} objects. + * @param offset a int. + * @param length a int. + * @return a {@link String} object. + */ + public static String toHexString(byte[] bytes, int offset, int length){ + StringBuilder sb = new StringBuilder(); + appendHexString(sb, bytes, offset, length); + return sb.toString().trim(); + } + + /** + *

appendHexString.

+ * + * @param builder a {@link StringBuilder} object. + * @param buffer a {@link ByteBuffer} object. + * @param offset a int. + * @param length a int. + */ + public static void appendHexString(StringBuilder builder, ByteBuffer buffer, int offset, int length){ + appendHexString(builder, buffer.array(), offset, length); + } + /** + *

toHexString.

+ * + * @param buffer a {@link ByteBuffer} object. + * @param offset a int. + * @param length a int. + * @return a {@link String} object. + */ + public static String toHexString(ByteBuffer buffer, int offset, int length){ + StringBuilder sb = new StringBuilder(); + appendHexString(sb, buffer, offset, offset+length); + return sb.toString().trim(); + } + +} \ No newline at end of file diff --git a/libraries/pi4j-library-gpiod/src/main/java/module-info.java b/libraries/pi4j-library-gpiod/src/main/java/module-info.java new file mode 100644 index 00000000..8dde242c --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/java/module-info.java @@ -0,0 +1,38 @@ +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: LIBRARY :: JNI Wrapper for LinuxFS Library + * FILENAME : module-info.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ +module com.pi4j.library.gpiod { + + // SLF4J + requires org.slf4j; + + // PI4J + requires com.pi4j; + + + // EXPORTS + exports com.pi4j.library.gpiod.internal; +} diff --git a/libraries/pi4j-library-gpiod/src/main/native/Makefile b/libraries/pi4j-library-gpiod/src/main/native/Makefile new file mode 100644 index 00000000..537b8b67 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/native/Makefile @@ -0,0 +1,70 @@ +# +# Makefile: +# pi4j-gpiod - Pi4J Java (JNI) library wrapper for gpiod +# + +#DEBUG = -g -O0 +ARCH := armhf +DEBUG = -O3 +CC = $(CROSS_PREFIX)gcc +AR = $(CROSS_PREFIX)ar +RANLIB = $(CROSS_PREFIX)ranlib +SIZE = $(CROSS_PREFIX)size +STRIP = $(CROSS_PREFIX)strip +SHLIB = $(CC) -shared +STRIPLIB = $(STRIP) --strip-unneeded +INCLUDE = -I. \ + -I/$(JAVA_HOME)/include \ + -I/$(JAVA_HOME)/include/linux \ + -I/usr/lib/jvm/jdk-11-oracle/include \ + -I/usr/lib/jvm/jdk-11-oracle/include/linux \ + -I/usr/lib/jvm/jdk-11-oracle-arm32-vfp-hflt/include \ + -I/usr/lib/jvm/jdk-11-oracle-arm32-vfp-hflt/include/linux \ + -I/usr/lib/jvm/java-11-openjdk-amd64/include \ + -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux \ + -I/usr/lib/jvm/java-11-openjdk-armhf/include \ + -I/usr/lib/jvm/java-11-openjdk-armhf/include/linux \ + -I/usr/include -I./gpiod/install/include + +CFLAGS := $(DEBUG) -Wall $(INCLUDE) -Winline -pipe $(CARGS) -fPIC +LIBS = -L lib/$(ARCH)/pi4j-gpiod -L gpiod -lgpiod -lrt + +TARGET=libpi4j-gpiod.so + +# Should not alter anything below this line +############################################################################### + +SRC = com_pi4j_library_gpiod_internal_GpioD.c + +OBJ = $(SRC:.c=.o) + +all: $(OBJ) + @echo [LINK with DYNAMICALLY linked libraries] + @$(CC) $(OBJ) -shared -o $(TARGET) $(INCLUDE) $(LIBS) + +.c.o: + @echo [COMPILE] $< + @$(CC) -c $(CFLAGS) $< -o $@ + +clean: + rm -f $(OBJ) $(TARGET) *~ core tags Makefile.bak + +tags: $(SRC) + @echo [ctags] + @ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +install: $(TARGET) + @echo [install] + install -m 0755 -d /usr/local/lib + install -m 0755 -d /usr/local/include + install -m 0644 $(TARGET) /usr/local/lib + +uninstall: + @echo [uninstall] + rm -f /usr/local/lib/$(TARGET) + +# DO NOT DELETE +com_pi4j_library_gpiod_internal_GpioD.o: com_pi4j_library_gpiod_internal_GpioD.h diff --git a/libraries/pi4j-library-gpiod/src/main/native/build-docker.sh b/libraries/pi4j-library-gpiod/src/main/native/build-docker.sh new file mode 100755 index 00000000..6bd057fd --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/native/build-docker.sh @@ -0,0 +1,59 @@ +#!/bin/bash -e +### +# #%L +# ********************************************************************** +# ORGANIZATION : Pi4J +# PROJECT : Pi4J :: JNI Native Binding Library for GpioD +# FILENAME : build-docker.sh +# +# This file is part of the Pi4J project. More information about +# this project can be found here: https://pi4j.com/ +# ********************************************************************** +# %% +# Copyright (C) 2012 - 2019 Pi4J +# %% +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# #L% +### + +echo +echo "**********************************************************************" +echo "**********************************************************************" +echo "* *" +echo "* COMPILE Pi4J NATIVE LIBRARIES USING Pi4J DOCKER BUILDER IMAGE *" +echo "* *" +echo "**********************************************************************" +echo "**********************************************************************" +echo + +# validate compatible that "docker" exists +DOCKER=$(which docker) +if [[ ("$DOCKER" == "") ]]; then + echo "This native build is requires that 'docker' (https://www.docker.com/) is " + echo "installed and running on an Intel/AMD or ARM 64-bit platform." + echo "BUILD ABORTED; REASON: Missing 'docker' executable." + exit +fi + +# set executable permissions on build scripts +chmod +x build.sh + +# ------------------------------------------------------------- +# BUILD NATIVE LIBRARIES USING THE Pi4J DOCKER BUILDER IMAGE +# FOR ARMv6,ARMv7, ARMv8 32-BIT (ARMHF) +# FOR ARMv8 64-BIT (ARM64) +# ------------------------------------------------------------- +docker pull pi4j/pi4j-builder-native:2.0 +docker run --user "$(id -u):$(id -g)" --rm --volume $(pwd):/build pi4j/pi4j-builder-native:2.0 $@ diff --git a/libraries/pi4j-library-gpiod/src/main/native/build-libgpiod.sh b/libraries/pi4j-library-gpiod/src/main/native/build-libgpiod.sh new file mode 100755 index 00000000..050d57eb --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/native/build-libgpiod.sh @@ -0,0 +1,77 @@ +#!/bin/bash -e +### +# #%L +# ********************************************************************** +# ORGANIZATION : Pi4J +# PROJECT : Pi4J :: JNI Native Binding Library for GPIOD +# FILENAME : build-libpigpio.sh +# +# This file is part of the Pi4J project. More information about +# this project can be found here: https://pi4j.com/ +# ********************************************************************** +# %% +# Copyright (C) 2012 - 2021 Pi4J +# %% +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# #L% +### + +# -- RASPBERRY PI -- +# set default GPIOD repository URL if not already defined +if [ -z $GPIOD_REPO ]; then + GPIOD_REPO=https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git +fi +# set default GPIOD repository branch if not already defined +if [ -z $GPIOD_BRANCH ]; then + GPIOD_BRANCH=v1.6.x +fi +# set default GPIOD directory if not already defined +if [ -z $GPIOD_DIRECTORY ]; then + GPIOD_DIRECTORY=gpiod +fi + +echo "=====================================" +echo "BUILDING: ${ARCH}/libgpiod" +echo "=====================================" +echo "REPOSITORY : $GPIOD_REPO" +echo "BRANCH : $GPIOD_BRANCH" +echo "DIRECTORY : $GPIOD_DIRECTORY" +echo "HOST ARCHITECTURE: ${HOST}" + +# ---------------------------------- +# clone GPIOD from github +# ---------------------------------- +rm -rf $GPIOD_DIRECTORY +git clone $GPIOD_REPO -b $GPIOD_BRANCH $GPIOD_DIRECTORY --single-branch --depth 1 + +#rm -f pigpio.tar +#wget abyz.me.uk/rpi/pigpio/pigpio.tar +#tar xf pigpio.tar + +# ---------------------------------- +# build latest GPIOD +# ---------------------------------- +cd $GPIOD_DIRECTORY + +./autogen.sh --enable-tools=no --prefix=$(pwd)/install --host=${HOST} + +make clean all install \ + CROSS_PREFIX=${CROSS_PREFIX} \ + CC=$CC \ + ARCH=$ARCH + +#echo "Copying GPIOD library files to parent 'lib' folder" +mkdir -p ../lib/${ARCH}/pi4j-gpiod +cp install/lib/libgpiod.so ../lib/${ARCH}/pi4j-gpiod/libgpiod.so diff --git a/libraries/pi4j-library-gpiod/src/main/native/build-libpi4j.sh b/libraries/pi4j-library-gpiod/src/main/native/build-libpi4j.sh new file mode 100755 index 00000000..d2be09a0 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/native/build-libpi4j.sh @@ -0,0 +1,68 @@ +#!/bin/bash -e +### +# #%L +# ********************************************************************** +# ORGANIZATION : Pi4J +# PROJECT : Pi4J :: JNI Native Binding Library for PIGPIO +# FILENAME : build-libpi4j.sh +# +# This file is part of the Pi4J project. More information about +# this project can be found here: https://pi4j.com/ +# ********************************************************************** +# %% +# Copyright (C) 2012 - 2021 Pi4J +# %% +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# #L% +### + +# ---------------------------------------------- +# build latest Pi4J PiGPIO JNI Wrapper Library +# ---------------------------------------------- + +echo +echo "=============================================================================" +echo " STARTED BUILDING Pi4J-PIGPIO JNI NATIVE LIBRARY: ('${ARCH}/pi4j-gpiod/libpi4j-gpiod')" +echo "=============================================================================" +echo " - FOR ARCHITECTURE : ${ARCH}" +echo " - USING COMPILER : ${CC}" +echo " - USING CROSS PREFIX : ${CROSS_PREFIX}" +echo "-----------------------------------------------------------------------------" +echo + +./build-libgpiod.sh $@ + +# ------------------------------------------------------ +# BUILD LIBPI4J-GPIOD +# ------------------------------------------------------ +echo +echo "=====================================" +echo "BUILDING: ${ARCH}/pi4j-gpiod/libpi4j-gpiod" +echo "=====================================" + +# perform compile +mkdir -p lib/${ARCH}/pi4j-gpiod +make clean all \ + --always-make \ + CROSS_PREFIX=${CROSS_PREFIX} \ + CC=${CC} \ + ARCH=${ARCH} \ + TARGET=lib/${ARCH}/pi4j-gpiod/libpi4j-gpiod.so $@ + +echo +echo "-----------------------------------------------------------------------------" +echo " FINISHED BUILDING Pi4J-PIGPIO JNI NATIVE LIBRARY: ('${ARCH}/libpi4j-gpiod')" +echo "-----------------------------------------------------------------------------" +echo \ No newline at end of file diff --git a/libraries/pi4j-library-gpiod/src/main/native/build-prerequisites.sh b/libraries/pi4j-library-gpiod/src/main/native/build-prerequisites.sh new file mode 100755 index 00000000..6f104c88 --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/native/build-prerequisites.sh @@ -0,0 +1,139 @@ +#!/bin/bash +### +# #%L +# ********************************************************************** +# ORGANIZATION : Pi4J +# PROJECT : Pi4J :: JNI Native Binding Library for PIGPIO +# FILENAME : build-prerequisites.sh +# +# This file is part of the Pi4J project. More information about +# this project can be found here: https://pi4j.com/ +# ********************************************************************** +# %% +# Copyright (C) 2012 - 2021 Pi4J +# %% +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# #L% +### +# ---------------------------------- +# install prerequisites +# ---------------------------------- +if [ ! -z "`type apt-get 2>/dev/null;`" ]; then + + # GCC + GCC_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' gcc|grep "install ok installed") + if [[ "" == "$GCC_INSTALLED" ]]; then + sudo apt-get --force-yes --yes install gcc + else + echo " [PREREQUISITE] 'gcc' already installed."; + fi + + # GIT + GIT_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' git|grep "install ok installed") + if [[ "" == "$GIT_INSTALLED" ]]; then + sudo apt-get --force-yes --yes install git + else + echo " [PREREQUISITE] 'git' already installed."; + fi + + # TREE + TREE_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' tree|grep "install ok installed") + if [[ "" == "$TREE_INSTALLED" ]]; then + sudo apt-get --force-yes --yes install tree + else + echo " [PREREQUISITE] 'tree' already installed."; + fi + + # gcc-arm-linux-gnueabihf + GCC_ARMHF_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' gcc-arm-linux-gnueabihf) + if [[ "$?" == "1" ]] ; then + echo " [PREREQUISITE] installing 'gcc-arm-linux-gnueabihf'..."; + sudo apt-get --force-yes --yes install gcc-arm-linux-gnueabihf + else + echo " [PREREQUISITE] 'gcc-arm-linux-gnueabihf' already installed."; + fi + + # gcc-aarch64-linux-gnu + GCC_AARCH64_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' gcc-aarch64-linux-gnu) + if [[ "$?" == "1" ]] ; then + echo " [PREREQUISITE] installing 'gcc-aarch64-linux-gnu'..."; + sudo apt-get --force-yes --yes install gcc-aarch64-linux-gnu + else + echo " [PREREQUISITE] 'gcc-aarch64-linux-gnu' already installed."; + fi + + # libgpiod2 + LIBGPIOD_DEV_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' libgpiod-dev) + if [[ "$?" == "1" ]] ; then + echo " [PREREQUISITE] installing 'libgpiod-dev'..."; + sudo apt-get --force-yes --yes install libgpiod-dev + else + echo " [PREREQUISITE] 'libgpiod-dev' already installed."; + fi + + # libgpiod-dev + LIBGPIOD_2_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' libgpiod-dev) + if [[ "$?" == "1" ]] ; then + echo " [PREREQUISITE] installing 'libgpiod-dev'..."; + sudo apt-get --force-yes --yes install libgpiod-dev + else + echo " [PREREQUISITE] 'libgpiod-dev' already installed."; + fi + + # gpiod + GPIOD_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' gpiod) + if [[ "$?" == "1" ]] ; then + echo " [PREREQUISITE] installing 'gpiod'..."; + sudo apt-get --force-yes --yes install gpiod + else + echo " [PREREQUISITE] 'gpiod' already installed."; + fi + + # autoconf + LIBGPIOD_DEV_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' autoconf) + if [[ "$?" == "1" ]] ; then + echo " [PREREQUISITE] installing 'autoconf'..."; + sudo apt-get --force-yes --yes install autoconf + else + echo " [PREREQUISITE] 'autoconf' already installed."; + fi + + # pkg-config + PKG_CONFIG_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' pkg-config) + if [[ "$?" == "1" ]] ; then + echo " [PREREQUISITE] installing 'pkg-config'..."; + sudo apt-get --force-yes --yes install pkg-config + else + echo " [PREREQUISITE] 'pkg-config' already installed."; + fi + + # libtool + LIBTOOL_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' libtool) + if [[ "$?" == "1" ]] ; then + echo " [PREREQUISITE] installing 'libtool'..."; + sudo apt-get --force-yes --yes install libtool + else + echo " [PREREQUISITE] 'libtool' already installed."; + fi + + # autoconf + AUTOCONF_ARCHIVE_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' autoconf-archive) + if [[ "$?" == "1" ]] ; then + echo " [PREREQUISITE] installing 'autoconf-archive'..."; + sudo apt-get --force-yes --yes install autoconf-archive + else + echo " [PREREQUISITE] 'autoconf-archive' already installed."; + fi +fi diff --git a/libraries/pi4j-library-gpiod/src/main/native/build.sh b/libraries/pi4j-library-gpiod/src/main/native/build.sh new file mode 100755 index 00000000..64ee5b0a --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/native/build.sh @@ -0,0 +1,132 @@ +#!/bin/bash -e +### +# #%L +# ********************************************************************** +# ORGANIZATION : Pi4J +# PROJECT : Pi4J :: JNI Native Binding Library for GpioD +# FILENAME : build.sh +# +# This file is part of the Pi4J project. More information about +# this project can be found here: https://pi4j.com/ +# ********************************************************************** +# %% +# Copyright (C) 2012 - 2021 Pi4J +# %% +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# #L% +### + +echo +echo "**********************************************************************" +echo "* *" +echo "* Pi4J GPIOD LIBRARY NATIVE BUILD *" +echo "* *" +echo "**********************************************************************" +echo + +# ------------------------------------------------------ +# VALIDATE BUILD PLATFORM; PRECONDITIONS +# ------------------------------------------------------ + +# validate compatible OS/Kernel +KERNEL=$(uname -s) +if [[ ("$KERNEL" != "Linux") ]]; then + echo "This native build is only supported on Linux-based systems running on an Intel/AMD or ARM 64-bit platform." + echo "BUILD ABORTED; REASON: KERNEL='$KERNEL'; EXPECTED='Linux'" + echo "(NOTE: You can run this build using the Pi4J Docker Builder images from OSX, Windows, Linux.)" + exit 1 +fi + +# validate compatible CPU architecture +ARCHITECTURE=$(uname -m) +if [[ (("$ARCHITECTURE" != "aarch64") && ("$ARCHITECTURE" != "amd64") && ("$ARCHITECTURE" != "x86_64")) ]]; then + echo "This native build is only supported on Linux-based systems running on an Intel/AMD or ARM 64-bit platform." + echo "BUILD ABORTED; REASON: ARCHITECTURE='$ARCHITECTURE'; EXPECTED='aarch64|amd64|x86_64'" + exit 1 +fi + +# ------------------------------------------------------ +# ENSURE DEPENDENCY SCRIPTS ARE EXECUTABLE +# ------------------------------------------------------ +# set executable permissions on build scripts +chmod +x build-prerequisites.sh +chmod +x build-libpi4j.sh + +# ------------------------------------------------------ +# INSTALL BUILD PREREQUISITES +# ------------------------------------------------------ +echo +echo "=====================================" +echo " INSTALLING Pi4J BUILD PREREQUISITES " +echo "=====================================" +echo + +# if running inside a Pi4J Docker Builder image, then there is no need to install prerequisites +if [[ "${PI4J_BUILDER}" != "" ]]; then + echo "Running inside a Pi4J Docker Builder image; [version=${PI4J_BUILDER}; arch=${PI4J_BUILDER_ARCH}]" + echo "No need to check or install build environment prerequisites." +else + # if this is a Linux-based system and a 64-bit Intel/AMD or ARM platform, then we can install the prerequisites + # download and install development prerequisites + ./build-prerequisites.sh +fi + +# ------------------------------------------------------ +# JAVA_HOME ENVIRONMENT VARIABLE +# ------------------------------------------------------ +echo +echo "=========================================" +echo " CHECKING JAVA_HOME ENVIRONMENT VARIABLE " +echo "=========================================" +echo +if [[ -n "$JAVA_HOME" ]]; then + echo "'JAVA_HOME' already defined as: $JAVA_HOME"; +else + export JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:bin/javac::") + echo "'JAVA_HOME' was not defined; attempting to use: $JAVA_HOME"; +fi + +# ------------------------------------------------------ +# BUILD NATIVE LIBRARIES FOR ARMv6,ARMv7,ARMv8 32-BIT (ARMHF) +# USING THE LOCALLY INSTALLED ARM CROSS-COMPILER +# ------------------------------------------------------ +export CROSS_PREFIX=arm-linux-gnueabihf- +export CC=arm-linux-gnueabihf-gcc +export ARCH=armhf +export HOST=arm-linux-gnueabihf +./build-libpi4j.sh $@ + +# ------------------------------------------------------ +# BUILD NATIVE LIBRARIES FOR ARMv8 64-BIT (ARM64) +# USING THE LOCALLY INSTALLED ARM64 CROSS-COMPILER +# ------------------------------------------------------ +export CROSS_PREFIX=aarch64-linux-gnu- +export CC=aarch64-linux-gnu-gcc +export ARCH=aarch64 +export HOST=aarch64-linux-gnu +./build-libpi4j.sh $@ + +echo "======================================" +echo " Pi4J GPIOD LIBRARY NATIVE ARTIFACTS " +echo "======================================" +tree -R lib + +echo +echo "**********************************************************************" +echo "* *" +echo "* Pi4J GPIOD LIBRARY NATIVE BUILD *" +echo "* *" +echo "**********************************************************************" +echo \ No newline at end of file diff --git a/libraries/pi4j-library-gpiod/src/main/native/com_pi4j_library_gpiod_internal_GpioD.c b/libraries/pi4j-library-gpiod/src/main/native/com_pi4j_library_gpiod_internal_GpioD.c new file mode 100644 index 00000000..a57522cd --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/native/com_pi4j_library_gpiod_internal_GpioD.c @@ -0,0 +1,962 @@ + +#include +#include +#include "com_pi4j_library_gpiod_internal_GpioD.h" + +// Compile using: +// gcc -I /usr/lib/jvm/java-11-openjdk-amd64/include/ -I /usr/lib/jvm/java-11-openjdk-amd64/include/linux/ -lgpiod -I . -c com_pi4j_library_gpiod_internal_GpioD.c + +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1open + (JNIEnv* env, jclass javaClass, jstring path) { + struct gpiod_chip* chip; + const char* nativeString = (*env)->GetStringUTFChars(env, path, NULL); + chip = gpiod_chip_open(nativeString); + (*env)->ReleaseStringUTFChars(env, path, nativeString); + + if(chip == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) chip); +} + +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1close + (JNIEnv* env, jclass javaClass, jlong chipPtr) { + gpiod_chip_close((struct gpiod_chip*) (uintptr_t) chipPtr); + } + +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1name + (JNIEnv* env, jclass javaClass, jlong chipPtr) { + const char* name = gpiod_chip_name((struct gpiod_chip*) (uintptr_t) chipPtr); + jstring jStrName = (*env)->NewStringUTF(env, name); + return jStrName; + } + +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1label + (JNIEnv* env, jclass javaClass, jlong chipPtr) { + const char* label = gpiod_chip_label((struct gpiod_chip*) (uintptr_t) chipPtr); + jstring jStrName = (*env)->NewStringUTF(env, label); + return jStrName; +} + +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1num_1lines + (JNIEnv* env, jclass javaClass, jlong chipPtr) { + unsigned int num_lines = gpiod_chip_num_lines((struct gpiod_chip*) (uintptr_t) chipPtr); + return num_lines; +} + +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1get_1line + (JNIEnv* env, jclass javaClass, jlong chipPtr, jint offset) { + struct gpiod_line* line; + line = gpiod_chip_get_line((struct gpiod_chip*) (uintptr_t) chipPtr, offset); + if(line == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env,"java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "","(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) line); +} + +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1get_1lines + (JNIEnv* env, jclass javaClass, jlong chipPtr, jintArray offsets, jint num_offsets, jlong lineBulkPtr) { + jint* c_offsets = (*env)->GetIntArrayElements(env, offsets, 0); + int returnVal = gpiod_chip_get_lines((struct gpiod_chip*) (uintptr_t) chipPtr, (unsigned int*) c_offsets, num_offsets, (struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr); + (*env)->ReleaseIntArrayElements(env, offsets, c_offsets, 0); + return returnVal; +} + +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1get_1all_1lines + (JNIEnv* env, jclass javaClass, jlong chipPtr, jlong lineBulkPtr) { + return gpiod_chip_get_all_lines((struct gpiod_chip*) (uintptr_t) chipPtr, (struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr); +} + +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1find_1line + (JNIEnv* env, jclass javaClass, jlong chipPtr, jstring name) { + const char* c_name = (*env)->GetStringUTFChars(env, name, NULL); + struct gpiod_line* line = gpiod_chip_find_line((struct gpiod_chip*) (uintptr_t) chipPtr, c_name); + (*env)->ReleaseStringUTFChars(env, name, c_name); + + if(line == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "","(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) line); +} + +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1free + (JNIEnv* env, jclass javaClass, jlong bulkPtr) { + free((struct gpiod_line_bulk*) (uintptr_t) bulkPtr); +} + +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1bulk_1init + (JNIEnv* env, jclass javaClass, jlong bulkPtr) { + gpiod_line_bulk_init((struct gpiod_line_bulk*) (uintptr_t) bulkPtr); +} + +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1new + (JNIEnv* env, jclass javaClass) { + struct gpiod_line_bulk* bulkPtr = (struct gpiod_line_bulk*) malloc(sizeof(struct gpiod_line_bulk)); + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "","(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) bulkPtr); +} + +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1add + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr, jlong linePtr) { + gpiod_line_bulk_add((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr, (struct gpiod_line*) (uintptr_t) linePtr); +} + +JNIEXPORT jlong JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1get_1line + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr, jint offset) { + return (jlong) (uintptr_t) gpiod_line_bulk_get_line((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr, offset); +} + +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1num_1lines + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr) { + return gpiod_line_bulk_num_lines((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_offset + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1offset + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_offset((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_name + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1name + (JNIEnv* env, jclass javaClass, jlong linePtr) { + const char* c_name = gpiod_line_name((struct gpiod_line*) (uintptr_t) linePtr); + return (*env)->NewStringUTF(env, c_name); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_consumer + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1consumer + (JNIEnv* env, jclass javaClass, jlong linePtr) { + const char* c_name = gpiod_line_consumer((struct gpiod_line*) (uintptr_t) linePtr); + return (*env)->NewStringUTF(env, c_name); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_direction + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1direction + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_direction((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_active_state + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1active_1state + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_active_state((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_bias + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bias + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_bias((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_used + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1used + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_is_used((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_open_drain + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1open_1drain + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_is_open_drain((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_open_source + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1open_1source + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_is_open_source((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_update + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1update + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_update((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request + * Signature: (JJI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request + (JNIEnv* env, jclass javaClass, jlong linePtr, jlong requestConfigPtr, jint defaultVal) { + return gpiod_line_request((struct gpiod_line*) (uintptr_t) linePtr, (struct gpiod_line_request_config*) (uintptr_t) linePtr, defaultVal); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_input + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1input + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_input((struct gpiod_line*) (uintptr_t) linePtr, c_consumer); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_output + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1output + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer, jint defaultVal) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_output((struct gpiod_line*) (uintptr_t) linePtr, c_consumer, defaultVal); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_rising_edge_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1rising_1edge_1events + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_rising_edge_events((struct gpiod_line*) (uintptr_t) linePtr, c_consumer); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_falling_edge_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1falling_1edge_1events + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_falling_edge_events((struct gpiod_line*) (uintptr_t) linePtr, c_consumer); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_both_edges_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1both_1edges_1events + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_both_edges_events((struct gpiod_line*) (uintptr_t) linePtr, c_consumer); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_input_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1input_1flags + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer, jint flags) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_input_flags((struct gpiod_line*) (uintptr_t) linePtr, c_consumer, flags); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_output_flags + * Signature: (JLjava/lang/String;II)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1output_1flags + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer, jint flags, jint defaultVal) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_output_flags((struct gpiod_line*) (uintptr_t) linePtr, c_consumer, flags, defaultVal); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_rising_edge_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1rising_1edge_1events_1flags + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer, jint flags) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_rising_edge_events_flags((struct gpiod_line*) (uintptr_t) linePtr, c_consumer, flags); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_falling_edge_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1falling_1edge_1events_1flags + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer, jint flags) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_falling_edge_events_flags((struct gpiod_line*) (uintptr_t) linePtr, c_consumer, flags); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_both_edges_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1both_1edges_1events_1flags + (JNIEnv* env, jclass javaClass, jlong linePtr, jstring consumer, jint flags) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_both_edges_events_flags((struct gpiod_line*) (uintptr_t) linePtr, c_consumer, flags); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk + * Signature: (JJ[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr, jlong requestConfigPtr, jintArray defaultVals) { + jint* c_defaultVals = (*env)->GetIntArrayElements(env, defaultVals, 0); + int result = gpiod_line_request_bulk((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr, (struct gpiod_line_request_config*) (uintptr_t) requestConfigPtr, c_defaultVals); + (*env)->ReleaseIntArrayElements(env, defaultVals, c_defaultVals, 0); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_input + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1input + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_input((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_output + * Signature: (JLjava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1output + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer, jintArray defaultVals) { + jint* c_defaultVals = (*env)->GetIntArrayElements(env, defaultVals, 0); + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_output((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer, c_defaultVals); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + (*env)->ReleaseIntArrayElements(env, defaultVals, c_defaultVals, 0); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_rising_edge_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1rising_1edge_1events + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_rising_edge_events((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_falling_edge_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1falling_1edge_1events + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_falling_edge_events((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_both_edges_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1both_1edges_1events + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_both_edges_events((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_input_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1input_1flags + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer, jint flags) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_input_flags((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer, flags); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_output_flags + * Signature: (JLjava/lang/String;I[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1output_1flags + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer, jint flags, jintArray defaultVals) { + jint* c_defaultVals = (*env)->GetIntArrayElements(env, defaultVals, 0); + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_output_flags((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer, flags, c_defaultVals); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + (*env)->ReleaseIntArrayElements(env, defaultVals, c_defaultVals, 0); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_rising_edge_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1rising_1edge_1events_1flags + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer, jint flags) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_rising_edge_events_flags((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer, flags); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_falling_edge_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1falling_1edge_1events_1flags + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer, jint flags) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_falling_edge_events_flags((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer, flags); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_both_edges_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1both_1edges_1events_1flags + (JNIEnv* env, jclass javaClass, jlong bulkPtr, jstring consumer, jint flags) { + const char* c_consumer = (*env)->GetStringUTFChars(env, consumer, NULL); + int result = gpiod_line_request_bulk_both_edges_events_flags((struct gpiod_line_bulk*) (uintptr_t) bulkPtr, c_consumer, flags); + (*env)->ReleaseStringUTFChars(env, consumer, c_consumer); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_release + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1release + (JNIEnv* env, jclass javaClass, jlong linePtr) { + gpiod_line_release((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_release_bulk + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1release_1bulk + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr) { + gpiod_line_release_bulk((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_requested + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1requested + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_is_requested((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_free + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1free + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_is_free((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_get_value + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1get_1value + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_get_value((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_get_value_bulk + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1get_1value_1bulk + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr, jintArray values) { + jint* c_values = (*env)->GetIntArrayElements(env, values, 0); + int result = gpiod_line_get_value_bulk((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr, c_values); + (*env)->ReleaseIntArrayElements(env, values, c_values, 0); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_value + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1value + (JNIEnv* env, jclass javaClass, jlong linePtr, jint value) { + return gpiod_line_set_value((struct gpiod_line*) (uintptr_t) linePtr, value); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_value_bulk + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1value_1bulk + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr, jintArray values) { + jint* c_values = (*env)->GetIntArrayElements(env, values, 0); + int result = gpiod_line_set_value_bulk((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr, c_values); + (*env)->ReleaseIntArrayElements(env, values, c_values, 0); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_config + * Signature: (JIII)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1config + (JNIEnv* env, jclass javaClass, jlong linePtr, jint direction, jint flags, jint value) { + return gpiod_line_set_config((struct gpiod_line*) (uintptr_t) linePtr, direction, flags, value); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_config_bulk + * Signature: (JII[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1config_1bulk + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr, jint direction, jint flags, jintArray values) { + jint* c_values = (*env)->GetIntArrayElements(env, values, 0); + int result = gpiod_line_set_config_bulk((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr, direction, flags, c_values); + (*env)->ReleaseIntArrayElements(env, values, c_values, 0); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_flags + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1flags + (JNIEnv* env, jclass javaClass, jlong linePtr, jint flags) { + return gpiod_line_set_flags((struct gpiod_line*) (uintptr_t) linePtr, flags); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_flags_bulk + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1flags_1bulk + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr, jint flags) { + return gpiod_line_set_flags_bulk((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr, flags); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_direction_input + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1direction_1input + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return gpiod_line_set_direction_input((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_direction_input_bulk + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1direction_1input_1bulk + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr) { + return gpiod_line_set_direction_input_bulk((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_direction_output + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1direction_1output + (JNIEnv* env, jclass javaClass, jlong linePtr, jint value) { + return gpiod_line_set_direction_output((struct gpiod_line*) (uintptr_t) linePtr, value); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_direction_output_bulk + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1direction_1output_1bulk + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr, jintArray values) { + jint* c_values = (*env)->GetIntArrayElements(env, values, 0); + int result = gpiod_line_set_direction_output_bulk((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr, c_values); + (*env)->ReleaseIntArrayElements(env, values, c_values, 0); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_wait + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1wait + (JNIEnv* env, jclass javaClass, jlong linePtr, jlong timeoutNs) { + struct timespec timeout; + timeout.tv_sec = timeoutNs / 1000000000; + timeout.tv_nsec = timeoutNs % 1000000000; + return gpiod_line_event_wait((struct gpiod_line*) (uintptr_t) linePtr, &timeout); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_wait_bulk + * Signature: (JJJ)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1wait_1bulk + (JNIEnv* env, jclass javaClass, jlong lineBulkPtr, jlong timeoutNs, jlong eventBulkPtr) { + struct timespec timeout; + timeout.tv_sec = timeoutNs / 1000000000; + timeout.tv_nsec = timeoutNs % 1000000000; + int result = gpiod_line_event_wait_bulk((struct gpiod_line_bulk*) (uintptr_t) lineBulkPtr, &timeout, (struct gpiod_line_bulk*) (uintptr_t) eventBulkPtr); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_read + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1read + (JNIEnv* env, jclass javaClass, jlong linePtr, jlong eventPtr) { + return gpiod_line_event_read((struct gpiod_line*) (uintptr_t) linePtr, (struct gpiod_line_event*) (uintptr_t) eventPtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_read_multiple + * Signature: (J[JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1read_1multiple + (JNIEnv* env, jclass javaClass, jlong linePtr, jlongArray events, jint numEvents) { + jlong* c_events = (*env)->GetLongArrayElements(env, events, 0); + int result = gpiod_line_event_read_multiple((struct gpiod_line*) (uintptr_t) linePtr, (struct gpiod_line_event*) (uintptr_t) c_events, numEvents); + (*env)->ReleaseLongArrayElements(env, events, c_events, 0); + return result; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_get + * Signature: (Ljava/lang/String;I)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1get + (JNIEnv* env, jclass javaClass, jstring device, jint offset) { + const char* c_device = (*env)->GetStringUTFChars(env, device, NULL); + struct gpiod_line* found = gpiod_line_get(c_device, offset); + (*env)->ReleaseStringUTFChars(env, device, c_device); + + if(found == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) found); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_find + * Signature: (Ljava/lang/String;)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1find + (JNIEnv* env, jclass javaClass, jstring name) { + const char* c_name = (*env)->GetStringUTFChars(env, name, NULL); + struct gpiod_line* found = gpiod_line_find(c_name); + (*env)->ReleaseStringUTFChars(env, name, c_name); + + if(found == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) found); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_close_chip + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1close_1chip + (JNIEnv* env, jclass javaClass, jlong linePtr) { + gpiod_line_close_chip((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_get_chip + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1get_1chip + (JNIEnv* env, jclass javaClass, jlong linePtr) { + return (jlong) (uintptr_t) gpiod_line_get_chip((struct gpiod_line*) (uintptr_t) linePtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_chip_iter_new + * Signature: ()Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1chip_1iter_1new + (JNIEnv* env, jclass javaClass) { + struct gpiod_chip_iter* iter = gpiod_chip_iter_new(); + + if(iter == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) iter); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_iter_free + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1iter_1free + (JNIEnv* env, jclass javaClass, jlong chipIterPtr) { + gpiod_chip_iter_free((struct gpiod_chip_iter*) (uintptr_t) chipIterPtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_iter_free_noclose + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1iter_1free_1noclose + (JNIEnv* env, jclass javaClass, jlong chipIterPtr) { + gpiod_chip_iter_free_noclose((struct gpiod_chip_iter*) (uintptr_t) chipIterPtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_iter_next + * Signature: (J)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1iter_1next + (JNIEnv* env, jclass javaClass, jlong chipIterPtr) { + struct gpiod_chip* chip = gpiod_chip_iter_next((struct gpiod_chip_iter*) (uintptr_t) chipIterPtr); + + if(chip == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) chip); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_iter_next_noclose + * Signature: (J)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1iter_1next_1noclose + (JNIEnv* env, jclass javaClass, jlong chipIterPtr) { + struct gpiod_chip* chip = gpiod_chip_iter_next_noclose((struct gpiod_chip_iter*) (uintptr_t) chipIterPtr); + + if(chip == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) chip); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_iter_new + * Signature: (J)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1iter_1new + (JNIEnv* env, jclass javaClass, jlong lineIterPtr) { + struct gpiod_line_iter* iter = gpiod_line_iter_new((struct gpiod_chip*) (uintptr_t) lineIterPtr); + + if(iter == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) iter); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_iter_free + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1iter_1free + (JNIEnv* env, jclass javaClass, jlong lineIterPtr) { + gpiod_line_iter_free((struct gpiod_line_iter*) (uintptr_t) lineIterPtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_iter_next + * Signature: (J)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1iter_1next + (JNIEnv* env, jclass javaClass, jlong lineIterPtr) { + struct gpiod_line* line = gpiod_line_iter_next((struct gpiod_line_iter*) (uintptr_t) lineIterPtr); + + if(line == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) line); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_get_timespec + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1get_1timespec + (JNIEnv* env, jclass javaClass, jlong eventPtr) { + struct timespec ts = ((struct gpiod_line_event*) (uintptr_t) eventPtr)->ts; + jlong tsNs = ts.tv_nsec; + tsNs += ts.tv_sec * 1000000000; + return tsNs; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_get_type + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1get_1type + (JNIEnv* env, jclass javaClass, jlong eventPtr) { + return ((struct gpiod_line_event*) (uintptr_t) eventPtr)->event_type; +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_new + * Signature: ()Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1new + (JNIEnv* env, jclass javaClass) { + struct gpiod_line_event* eventPtr = (struct gpiod_line_event*) malloc(sizeof(struct gpiod_line_event)); + if(eventPtr == NULL) { + return NULL; + } + jclass cls = (*env)->FindClass(env, "java/lang/Long"); + jmethodID longConstructor = (*env)->GetMethodID(env, cls, "","(J)V"); + return (*env)->NewObject(env, cls, longConstructor, (jlong) (uintptr_t) eventPtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_free + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1free + (JNIEnv* env, jclass javaClass, jlong eventPtr) { + free((struct gpiod_line_event*) (uintptr_t) eventPtr); +} + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_version_string + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1version_1string + (JNIEnv* env, jclass javaClass) { + return (*env)->NewStringUTF(env, gpiod_version_string()); +} \ No newline at end of file diff --git a/libraries/pi4j-library-gpiod/src/main/native/com_pi4j_library_gpiod_internal_GpioD.h b/libraries/pi4j-library-gpiod/src/main/native/com_pi4j_library_gpiod_internal_GpioD.h new file mode 100644 index 00000000..a8deb9fe --- /dev/null +++ b/libraries/pi4j-library-gpiod/src/main/native/com_pi4j_library_gpiod_internal_GpioD.h @@ -0,0 +1,685 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_pi4j_library_gpiod_internal_GpioD */ + +#ifndef _Included_com_pi4j_library_gpiod_internal_GpioD +#define _Included_com_pi4j_library_gpiod_internal_GpioD +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_open + * Signature: (Ljava/lang/String;)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1open + (JNIEnv *, jclass, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_close + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1close + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_name + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1name + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_label + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1label + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_num_lines + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1num_1lines + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_get_line + * Signature: (JI)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1get_1line + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_get_lines + * Signature: (J[IIJ)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1get_1lines + (JNIEnv *, jclass, jlong, jintArray, jint, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_get_all_lines + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1get_1all_1lines + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_find_line + * Signature: (JLjava/lang/String;)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1find_1line + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_bulk_free + * Signature: (J)Ljava/lang/Long; + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1free + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_bulk_init + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1bulk_1init + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_bulk_new + * Signature: ()Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1new + (JNIEnv *, jclass); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_bulk_add + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1add + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_bulk_get_line + * Signature: (JI)J + */ +JNIEXPORT jlong JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1get_1line + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_bulk_num_lines + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bulk_1num_1lines + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_offset + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1offset + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_name + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1name + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_consumer + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1consumer + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_direction + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1direction + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_active_state + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1active_1state + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_bias + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1bias + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_used + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1used + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_open_drain + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1open_1drain + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_open_source + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1open_1source + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_update + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1update + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request + * Signature: (JJI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request + (JNIEnv *, jclass, jlong, jlong, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_input + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1input + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_output + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1output + (JNIEnv *, jclass, jlong, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_rising_edge_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1rising_1edge_1events + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_falling_edge_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1falling_1edge_1events + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_both_edges_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1both_1edges_1events + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_input_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1input_1flags + (JNIEnv *, jclass, jlong, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_output_flags + * Signature: (JLjava/lang/String;II)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1output_1flags + (JNIEnv *, jclass, jlong, jstring, jint, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_rising_edge_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1rising_1edge_1events_1flags + (JNIEnv *, jclass, jlong, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_falling_edge_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1falling_1edge_1events_1flags + (JNIEnv *, jclass, jlong, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_both_edges_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1both_1edges_1events_1flags + (JNIEnv *, jclass, jlong, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk + * Signature: (JJ[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk + (JNIEnv *, jclass, jlong, jlong, jintArray); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_input + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1input + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_output + * Signature: (JLjava/lang/String;[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1output + (JNIEnv *, jclass, jlong, jstring, jintArray); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_rising_edge_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1rising_1edge_1events + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_falling_edge_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1falling_1edge_1events + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_both_edges_events + * Signature: (JLjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1both_1edges_1events + (JNIEnv *, jclass, jlong, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_input_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1input_1flags + (JNIEnv *, jclass, jlong, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_output_flags + * Signature: (JLjava/lang/String;I[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1output_1flags + (JNIEnv *, jclass, jlong, jstring, jint, jintArray); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_rising_edge_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1rising_1edge_1events_1flags + (JNIEnv *, jclass, jlong, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_falling_edge_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1falling_1edge_1events_1flags + (JNIEnv *, jclass, jlong, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_request_bulk_both_edges_events_flags + * Signature: (JLjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1request_1bulk_1both_1edges_1events_1flags + (JNIEnv *, jclass, jlong, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_release + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1release + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_release_bulk + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1release_1bulk + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_requested + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1requested + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_is_free + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1is_1free + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_get_value + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1get_1value + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_get_value_bulk + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1get_1value_1bulk + (JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_value + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1value + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_value_bulk + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1value_1bulk + (JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_config + * Signature: (JIII)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1config + (JNIEnv *, jclass, jlong, jint, jint, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_config_bulk + * Signature: (JII[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1config_1bulk + (JNIEnv *, jclass, jlong, jint, jint, jintArray); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_flags + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1flags + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_flags_bulk + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1flags_1bulk + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_direction_input + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1direction_1input + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_direction_input_bulk + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1direction_1input_1bulk + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_direction_output + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1direction_1output + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_set_direction_output_bulk + * Signature: (J[I)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1set_1direction_1output_1bulk + (JNIEnv *, jclass, jlong, jintArray); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_wait + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1wait + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_wait_bulk + * Signature: (JJJ)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1wait_1bulk + (JNIEnv *, jclass, jlong, jlong, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_read + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1read + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_read_multiple + * Signature: (J[JI)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1read_1multiple + (JNIEnv *, jclass, jlong, jlongArray, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_get + * Signature: (Ljava/lang/String;I)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1get + (JNIEnv *, jclass, jstring, jint); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_find + * Signature: (Ljava/lang/String;)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1find + (JNIEnv *, jclass, jstring); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_close_chip + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1close_1chip + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_get_chip + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1get_1chip + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_chip_iter_new + * Signature: ()Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1chip_1iter_1new + (JNIEnv *, jclass); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_iter_free + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1iter_1free + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_iter_free_noclose + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1iter_1free_1noclose + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_iter_next + * Signature: (J)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1iter_1next + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_chip_iter_next_noclose + * Signature: (J)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1chip_1iter_1next_1noclose + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_iter_new + * Signature: (J)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1iter_1new + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_iter_free + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1iter_1free + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: gpiod_line_iter_next + * Signature: (J)Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_gpiod_1line_1iter_1next + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_get_timespec + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1get_1timespec + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_get_type + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1get_1type + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_new + * Signature: ()Ljava/lang/Long; + */ +JNIEXPORT jobject JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1new + (JNIEnv *, jclass); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_line_event_free + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1line_1event_1free + (JNIEnv *, jclass, jlong); + +/* + * Class: com_pi4j_library_gpiod_internal_GpioD + * Method: c_gpiod_version_string + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_pi4j_library_gpiod_internal_GpioD_c_1gpiod_1version_1string + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libraries/pi4j-library/pom.xml b/libraries/pi4j-library/pom.xml index bcea620f..ce8a507a 100644 --- a/libraries/pi4j-library/pom.xml +++ b/libraries/pi4j-library/pom.xml @@ -29,6 +29,7 @@ ../pi4j-library-pigpio ../pi4j-library-linuxfs + ../pi4j-library-gpiod diff --git a/pi4j-distribution/pom.xml b/pi4j-distribution/pom.xml index f4f7b216..e1bfaad8 100644 --- a/pi4j-distribution/pom.xml +++ b/pi4j-distribution/pom.xml @@ -52,6 +52,11 @@ pi4j-plugin-linuxfs ${project.version} + + com.pi4j + pi4j-plugin-gpiod + ${project.version} + @@ -64,6 +69,11 @@ pi4j-library-linuxfs ${project.version} + + com.pi4j + pi4j-library-gpiod + ${project.version} + + + com.pi4j + pi4j-library-gpiod + ${project.version} + armhf + so + + + com.pi4j + pi4j-library-gpiod + ${project.version} + aarch64 + so + + diff --git a/pi4j-test/pom.xml b/pi4j-test/pom.xml index a61b14bf..8a5899bd 100644 --- a/pi4j-test/pom.xml +++ b/pi4j-test/pom.xml @@ -31,6 +31,85 @@ pi4j-plugin-mock ${project.version} + + + + com.pi4j + pi4j-library-pigpio + ${project.version} + + + com.pi4j + pi4j-library-linuxfs + ${project.version} + + + com.pi4j + pi4j-library-gpiod + ${project.version} + + + + + + com.pi4j + pi4j-library-pigpio + ${project.version} + armhf + so + + + com.pi4j + pi4j-library-pigpio + ${project.version} + aarch64 + so + + + + + com.pi4j + pi4j-library-linuxfs + ${project.version} + armhf + so + + + com.pi4j + pi4j-library-linuxfs + ${project.version} + aarch64 + so + + + + + com.pi4j + pi4j-library-gpiod + ${project.version} + armhf + so + + + com.pi4j + pi4j-library-gpiod + ${project.version} + aarch64 + so + + + com.pi4j + pi4j-plugin-gpiod + ${project.version} + + + com.pi4j + pi4j-plugin-linuxfs + ${project.version} + + @@ -107,47 +186,98 @@ + + - - - org.apache.maven.plugins - maven-antrun-plugin - + + + + remote-run + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + process-sources + + copy-dependencies + + + ${project.build.directory}/distribution + runtime + false + false + true + true + + + + - - - transfer-compiled-pi4j-jar - install - - run - + + + org.apache.maven.plugins + maven-jar-plugin - - - - - - - - - - - - - - + ${project.build.directory}/distribution - - - + - - + + org.apache.maven.plugins + maven-antrun-plugin + + + transfer + install + + run + + + + + + + + + + + + + + + + + + + + + + org.apache.ant + ant-jsch + ${ant-jsch.version} + + + + + + + diff --git a/pi4j-test/src/main/java/com/pi4j/test/GpiodTest.java b/pi4j-test/src/main/java/com/pi4j/test/GpiodTest.java new file mode 100644 index 00000000..f0ec4eaa --- /dev/null +++ b/pi4j-test/src/main/java/com/pi4j/test/GpiodTest.java @@ -0,0 +1,31 @@ +package com.pi4j.test; + +import com.pi4j.Pi4J; +import com.pi4j.context.Context; +import com.pi4j.plugin.gpiod.provider.gpio.digital.GpioDDigitalInputProvider; +import com.pi4j.plugin.gpiod.provider.gpio.digital.GpioDDigitalOutputProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GpiodTest { + + private static final Logger logger = LoggerFactory.getLogger(Main.class); + + public static void main(String[] args) throws InterruptedException { + System.out.println("Attach remote now!"); + Thread.sleep(1000 * 10); + Context pi4j = Pi4J.newContextBuilder() + .add(GpioDDigitalOutputProvider.newInstance(), GpioDDigitalInputProvider.newInstance()) + .build(); + //Context pi4j = Pi4J.newAutoContext(); + + logger.info("\r\n\r\n-----------------------------------\r\n" + + "Pi4J GPIOD - Runtime Information\r\n" + + "-----------------------------------"); + pi4j.describe().print(System.out); + + + // shutdown Pi4J + pi4j.shutdown(); + } +} diff --git a/pi4j-test/src/main/java/module-info.java b/pi4j-test/src/main/java/module-info.java index 92627143..0377ef17 100644 --- a/pi4j-test/src/main/java/module-info.java +++ b/pi4j-test/src/main/java/module-info.java @@ -36,6 +36,19 @@ // Pi4J Mock Platform and Providers requires com.pi4j.plugin.mock; + + // TEST + requires com.pi4j.plugin.gpiod; + uses com.pi4j.plugin.gpiod.GpioDPlugin; + uses com.pi4j.plugin.gpiod.provider.gpio.digital.GpioDDigitalOutput; + uses com.pi4j.plugin.gpiod.provider.gpio.digital.GpioDDigitalOutputProvider; + + requires com.pi4j.plugin.linuxfs; + uses com.pi4j.plugin.linuxfs.LinuxFsPlugin; + uses com.pi4j.plugin.linuxfs.provider.gpio.digital.LinuxFsDigitalOutput; + uses com.pi4j.plugin.linuxfs.provider.gpio.digital.LinuxFsDigitalOutputProvider; + // TEST END + uses com.pi4j.plugin.mock.platform.MockPlatform; uses com.pi4j.plugin.mock.provider.gpio.analog.MockAnalogInput; uses com.pi4j.plugin.mock.provider.gpio.analog.MockAnalogInputProvider; diff --git a/plugins/pi4j-plugin-gpiod/.gitignore b/plugins/pi4j-plugin-gpiod/.gitignore new file mode 100644 index 00000000..5ff6309b --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/plugins/pi4j-plugin-gpiod/pom.xml b/plugins/pi4j-plugin-gpiod/pom.xml new file mode 100644 index 00000000..466827b7 --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/pom.xml @@ -0,0 +1,113 @@ + + + + com.pi4j + pi4j-plugin + 2.4.0-SNAPSHOT + ../pi4j-plugin/pom.xml + + 4.0.0 + + + pi4j-plugin-gpiod + Pi4J :: PLUGIN :: GPIOD I/O Providers + Pi4J Library Plugin for GPIOD I/O Providers + jar + + + com.jcraft + jsch + ${jsch.version} + + + com.pi4j + pi4j-library-gpiod + ${project.version} + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + process-sources + + copy-dependencies + + + runtime + com.pi4j + ${project.build.directory}/dependencies + false + false + true + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + + + transfer-compiled-pi4j-jar + install + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/GpioDPlugin.java b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/GpioDPlugin.java new file mode 100644 index 00000000..62fb9d66 --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/GpioDPlugin.java @@ -0,0 +1,60 @@ +package com.pi4j.plugin.gpiod; + +import com.pi4j.extension.Plugin; +import com.pi4j.extension.PluginService; +import com.pi4j.plugin.gpiod.provider.gpio.digital.GpioDDigitalOutputProvider; +import com.pi4j.provider.Provider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

GpioDPlugin class.

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioDPlugin implements Plugin { + + /** + * Constant NAME="GpioD" + */ + public static final String NAME = "GpioD"; + /** + * Constant ID="gpiod" + */ + public static final String ID = "gpiod"; + + // Digital Output (GPIO) Provider name and unique ID + /** + * Constant DIGITAL_OUTPUT_PROVIDER_NAME="NAME + Digital Output (GPIO) Provider" + */ + public static final String DIGITAL_OUTPUT_PROVIDER_NAME = NAME + " Digital Output (GPIO) Provider"; + /** + * Constant DIGITAL_OUTPUT_PROVIDER_ID="ID + -digital-output" + */ + public static final String DIGITAL_OUTPUT_PROVIDER_ID = ID + "-digital-output"; + + /** + * Constant DIGITAL_INPUT_PROVIDER_NAME="NAME + Digital Input (GPIO) Provider" + */ + public static final String DIGITAL_INPUT_PROVIDER_NAME = NAME + " Digital Input (GPIO) Provider"; + /** + * Constant DIGITAL_INPUT_PROVIDER_ID="ID + -digital-input" + */ + public static final String DIGITAL_INPUT_PROVIDER_ID = ID + "-digital-input"; + + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * {@inheritDoc} + */ + @Override + public void initialize(PluginService service) { + Provider[] providers = { + GpioDDigitalOutputProvider.newInstance() + }; + + service.register(providers); + } +} diff --git a/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/ActiveGpioChip.java b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/ActiveGpioChip.java new file mode 100644 index 00000000..501960e4 --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/ActiveGpioChip.java @@ -0,0 +1,46 @@ +package com.pi4j.plugin.gpiod.provider.gpio.digital; + +import com.pi4j.library.gpiod.internal.GpioChip; +import com.pi4j.library.gpiod.internal.GpioChipIterator; + +import java.io.Closeable; + +public class ActiveGpioChip implements Closeable { + private static GpioChip gpioChip; + private static int claimsOpen = 0; + + public ActiveGpioChip() { + if(gpioChip == null) { + GpioChipIterator iterator = new GpioChipIterator(); + GpioChip found = null; + while (iterator.hasNext()) { + GpioChip current = iterator.next(); + if(current.getLabel().contains("pinctrl")) { + found = current; + iterator.noCloseCurrent(); + break; + } + } + if(found == null) { + throw new IllegalStateException("Couldn't identify gpiochip!"); + } + ActiveGpioChip.gpioChip = found; + } + ActiveGpioChip.claimsOpen += 1; + } + + public GpioChip getGpioChip() { + return ActiveGpioChip.gpioChip; + } + + public void close() { + ActiveGpioChip.claimsOpen -= 1; + if(ActiveGpioChip.claimsOpen == 0) { + ActiveGpioChip.gpioChip.close(); + ActiveGpioChip.gpioChip = null; + } else if (ActiveGpioChip.claimsOpen < 0) { + ActiveGpioChip.claimsOpen = 0; + throw new IllegalStateException("ActiveGpioChip.chipsOpen < 0"); + } + } +} diff --git a/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalInput.java b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalInput.java new file mode 100644 index 00000000..f4c2d5a6 --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalInput.java @@ -0,0 +1,122 @@ +package com.pi4j.plugin.gpiod.provider.gpio.digital; + +import com.pi4j.context.Context; +import com.pi4j.exception.InitializeException; +import com.pi4j.exception.ShutdownException; +import com.pi4j.io.gpio.digital.*; +import com.pi4j.library.gpiod.internal.GpioD; +import com.pi4j.library.gpiod.internal.GpioDException; +import com.pi4j.library.gpiod.internal.GpioLine; +import com.pi4j.library.gpiod.internal.GpioLineEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + *

PiGpioDigitalOutput class.

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioDDigitalInput extends DigitalInputBase implements DigitalInput { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + private final long inputMaxWaitNs = 500 * 1000 * 1000; // 0,5 seconds + protected ExecutorService executor = Executors.newSingleThreadExecutor(r -> new Thread(r, "Pi4J.GPIO.Monitor")); + private final GpioLine line; + private final long debounceNs; + + /** + *

Constructor for GpioDDigitalInput.

+ * + * @param line a {@link com.pi4j.library.gpiod.internal.GpioLine} object. + * @param provider a {@link DigitalInputProvider} object. + * @param config a {@link DigitalInputConfig} object. + */ + public GpioDDigitalInput(GpioLine line, DigitalInputProvider provider, DigitalInputConfig config) { + super(provider, config); + this.line = line; + if(config.getDebounce() == 0) { + debounceNs = 0; + } else { + // Convert microseconds to nanoseconds + debounceNs = 1000 * config.getDebounce(); + } + } + + @Override + public DigitalInput initialize(Context context) throws InitializeException { + try { + switch (config.getPull()) { + case PULL_UP: + this.line.requestBothEdgeEventsFlags(config.getId(), GpioD.LINE_REQUEST_FLAG.BIAS_PULL_UP.getVal()); + break; + case PULL_DOWN: + this.line.requestBothEdgeEventsFlags(config.getId(), GpioD.LINE_REQUEST_FLAG.BIAS_PULL_DOWN.getVal()); + break; + case OFF: + this.line.requestBothEdgeEventsFlags(config.getId(), GpioD.LINE_REQUEST_FLAG.BIAS_DISABLE.getVal()); + break; + } + } catch (GpioDException e) { + logger.error(e.getMessage(), e); + throw new InitializeException(e); + } + super.initialize(context); + + Runnable monitorThread = new Runnable() { + @Override + public void run() { + DigitalState lastState = null; + while (true) { + long debounceNs = GpioDDigitalInput.this.debounceNs; + // We have to use this function before calling eventRead() directly, since native methods can't be interrupted. + // eventRead() is blocking and prevents thread interrupt while running + while (!GpioDDigitalInput.this.line.eventWait(inputMaxWaitNs)) { + continue; + } + GpioLineEvent lastEvent = GpioDDigitalInput.this.line.eventRead(); + long currentTime = System.nanoTime(); + + // Perform debouncing + // If the event is too new to be sure that it is debounced then ... + while (lastEvent.getTimeNs() + debounceNs >= currentTime) { + // ... wait for remaining debounce time and watch out for new event(s) + if(GpioDDigitalInput.this.line.eventWait(Math.min(inputMaxWaitNs, lastEvent.getTimeNs() + debounceNs - currentTime))) { + // Repeat if a second event occurred withing debounce interval + lastEvent = GpioDDigitalInput.this.line.eventRead(); + } + + currentTime = System.nanoTime(); + } + + // Apply event only if the new state is not the same as the last state. + DigitalState newState = DigitalState.getState(lastEvent.getType() == GpioD.LINE_EVENT.RISING_EDGE); + if(lastState != newState) { + lastState = newState; + GpioDDigitalInput.this.dispatch(new DigitalStateChangeEvent(GpioDDigitalInput.this, newState)); + } + + } + } + }; + + executor.submit(monitorThread); + return this; + } + + @Override + public DigitalInput shutdown(Context context) throws ShutdownException { + super.shutdown(context); + executor.shutdown(); + this.line.release(); + return this; + } + + @Override + public DigitalState state() { + return DigitalState.getState(this.line.getValue()); + } + +} diff --git a/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalInputProvider.java b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalInputProvider.java new file mode 100644 index 00000000..4adff7ec --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalInputProvider.java @@ -0,0 +1,26 @@ +package com.pi4j.plugin.gpiod.provider.gpio.digital; + +import com.pi4j.io.gpio.digital.DigitalInputProvider; +import com.pi4j.plugin.gpiod.GpioDPlugin; + +/** + *

GpioDDigitalInputProvider interface.

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public interface GpioDDigitalInputProvider extends DigitalInputProvider { + /** Constant NAME="GpioDPlugin.DIGITAL_INPUT_PROVIDER_NAME" */ + String NAME = GpioDPlugin.DIGITAL_INPUT_PROVIDER_NAME; + /** Constant ID="GpioDPlugin.DIGITAL_INPUT_PROVIDER_ID" */ + String ID = GpioDPlugin.DIGITAL_INPUT_PROVIDER_ID; + + /** + *

newInstance.

+ * + * @return a {@link com.pi4j.plugin.gpiod.provider.gpio.digital.GpioDDigitalInputProvider} object. + */ + static GpioDDigitalInputProvider newInstance() { + return new GpioDDigitalInputProviderImpl(); + } +} diff --git a/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalInputProviderImpl.java b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalInputProviderImpl.java new file mode 100644 index 00000000..5e4c69b0 --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalInputProviderImpl.java @@ -0,0 +1,49 @@ +package com.pi4j.plugin.gpiod.provider.gpio.digital; + +import com.pi4j.context.Context; +import com.pi4j.exception.InitializeException; +import com.pi4j.exception.ShutdownException; +import com.pi4j.io.gpio.digital.*; +import com.pi4j.library.gpiod.internal.GpioLine; + +public class GpioDDigitalInputProviderImpl extends DigitalInputProviderBase implements GpioDDigitalInputProvider { + private ActiveGpioChip chipClaim; + + /** + *

Constructor for GpioDDigitalInputProviderImpl.

+ */ + public GpioDDigitalInputProviderImpl(){ + this.id = ID; + this.name = NAME; + } + + /** {@inheritDoc} */ + @Override + public DigitalInput create(DigitalInputConfig config) { + // create new I/O instance based on I/O config + GpioLine line = this.chipClaim.getGpioChip().getLine(config.address()); + return new GpioDDigitalInput(line, this, config); + } + + @Override + public int getPriority() { + // GpioD should be used if available + return 150; + } + + /** {@inheritDoc} */ + @Override + public DigitalInputProvider initialize(Context context) throws InitializeException { + DigitalInputProvider provider = super.initialize(context); + this.chipClaim = new ActiveGpioChip(); + return provider; + } + + @Override + public DigitalInputProvider shutdown(Context context) throws ShutdownException { + if(chipClaim.getGpioChip() != null) { + this.chipClaim.close(); + } + return super.shutdown(context); + } +} diff --git a/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalOutput.java b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalOutput.java new file mode 100644 index 00000000..884c7e85 --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalOutput.java @@ -0,0 +1,94 @@ +package com.pi4j.plugin.gpiod.provider.gpio.digital; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: PIGPIO I/O Providers + * FILENAME : PiGpioDigitalOutput.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + + +import com.pi4j.context.Context; +import com.pi4j.exception.InitializeException; +import com.pi4j.exception.ShutdownException; +import com.pi4j.io.exception.IOException; +import com.pi4j.io.gpio.digital.*; +import com.pi4j.library.gpiod.internal.GpioDException; +import com.pi4j.library.gpiod.internal.GpioLine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

PiGpioDigitalOutput class.

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioDDigitalOutput extends DigitalOutputBase implements DigitalOutput { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + private final GpioLine line; + + /** + *

Constructor for GpioDDigitalOutput.

+ * + * @param line a {@link com.pi4j.library.gpiod.internal.GpioLine} object. + * @param provider a {@link DigitalOutputProvider} object. + * @param config a {@link DigitalOutputConfig} object. + */ + public GpioDDigitalOutput(GpioLine line, DigitalOutputProvider provider, DigitalOutputConfig config) { + super(provider, config); + this.line = line; + } + + /** {@inheritDoc} */ + @Override + public DigitalOutput initialize(Context context) throws InitializeException { + try { + this.line.requestOutput(config.getId(), config.initialState().value().intValue()); + } catch (GpioDException e) { + logger.error(e.getMessage(), e); + throw new InitializeException(e); + } + super.initialize(context); + return this; + } + + @Override + public DigitalOutput shutdown(Context context) throws ShutdownException { + DigitalOutput returnMe = super.shutdown(context); + this.line.release(); + return returnMe; + } + + /** {@inheritDoc} */ + @Override + public DigitalOutput state(DigitalState state) throws IOException { + try { + this.line.setValue(state.value().intValue()); + } catch (GpioDException e) { + logger.error(e.getMessage(), e); + throw new IOException(e.getMessage(), e); + } + return super.state(state); + } +} diff --git a/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalOutputProvider.java b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalOutputProvider.java new file mode 100644 index 00000000..1e4a681d --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalOutputProvider.java @@ -0,0 +1,53 @@ +package com.pi4j.plugin.gpiod.provider.gpio.digital; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: PIGPIO I/O Providers + * FILENAME : PiGpioDigitalOutputProvider.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.pi4j.io.gpio.digital.DigitalOutputProvider; +import com.pi4j.plugin.gpiod.GpioDPlugin; + +/** + *

PiGpioDigitalOutputProvider interface.

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public interface GpioDDigitalOutputProvider extends DigitalOutputProvider { + /** Constant NAME="GpioDPlugin.DIGITAL_OUTPUT_PROVIDER_NA"{trunked} */ + String NAME = GpioDPlugin.DIGITAL_OUTPUT_PROVIDER_NAME; + /** Constant ID="GpioDPlugin.DIGITAL_OUTPUT_PROVIDER_ID" */ + String ID = GpioDPlugin.DIGITAL_OUTPUT_PROVIDER_ID; + + /** + *

newInstance.

+ * + * @return a {@link GpioDDigitalOutputProvider} object. + */ + static GpioDDigitalOutputProvider newInstance() { + return new GpioDDigitalOutputProviderImpl(); + } +} diff --git a/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalOutputProviderImpl.java b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalOutputProviderImpl.java new file mode 100644 index 00000000..5e36c034 --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/java/com/pi4j/plugin/gpiod/provider/gpio/digital/GpioDDigitalOutputProviderImpl.java @@ -0,0 +1,89 @@ +package com.pi4j.plugin.gpiod.provider.gpio.digital; + +/* + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: PIGPIO I/O Providers + * FILENAME : PiGpioDigitalOutputProviderImpl.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + +import com.pi4j.context.Context; +import com.pi4j.exception.InitializeException; +import com.pi4j.exception.ShutdownException; +import com.pi4j.io.gpio.digital.DigitalOutput; +import com.pi4j.io.gpio.digital.DigitalOutputConfig; +import com.pi4j.io.gpio.digital.DigitalOutputProvider; +import com.pi4j.io.gpio.digital.DigitalOutputProviderBase; +import com.pi4j.library.gpiod.internal.GpioChip; +import com.pi4j.library.gpiod.internal.GpioChipIterator; +import com.pi4j.library.gpiod.internal.GpioLine; + + +/** + *

PiGpioDigitalOutputProviderImpl class.

+ * + * @author Alexander Liggesmeyer (https://alexander.liggesmeyer.net/) + * @version $Id: $Id + */ +public class GpioDDigitalOutputProviderImpl extends DigitalOutputProviderBase implements GpioDDigitalOutputProvider { + private ActiveGpioChip chipClaim; + + + /** + *

Constructor for PiGpioDigitalOutputProviderImpl.

+ * + */ + public GpioDDigitalOutputProviderImpl(){ + this.id = ID; + this.name = NAME; + } + + /** {@inheritDoc} */ + @Override + public DigitalOutput create(DigitalOutputConfig config) { + // create new I/O instance based on I/O config + GpioLine line = this.chipClaim.getGpioChip().getLine(config.address()); + return new GpioDDigitalOutput(line, this, config); + } + + @Override + public int getPriority() { + // GpioD should be used if available + return 150; + } + + @Override + public DigitalOutputProvider initialize(Context context) throws InitializeException { + DigitalOutputProvider provider = super.initialize(context); + this.chipClaim = new ActiveGpioChip(); + return provider; + } + + @Override + public DigitalOutputProvider shutdown(Context context) throws ShutdownException { + if(chipClaim.getGpioChip() != null) { + this.chipClaim.close(); + } + return super.shutdown(context); + } +} diff --git a/plugins/pi4j-plugin-gpiod/src/main/java/module-info.java b/plugins/pi4j-plugin-gpiod/src/main/java/module-info.java new file mode 100644 index 00000000..841408cc --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/java/module-info.java @@ -0,0 +1,43 @@ +import com.pi4j.plugin.gpiod.GpioDPlugin; + +/*- + * #%L + * ********************************************************************** + * ORGANIZATION : Pi4J + * PROJECT : Pi4J :: PLUGIN :: LinuxFS I/O Providers + * FILENAME : module-info.java + * + * This file is part of the Pi4J project. More information about + * this project can be found here: https://pi4j.com/ + * ********************************************************************** + * + * This program 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 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ +module com.pi4j.plugin.gpiod { + + // depends on SLF4J + requires org.slf4j; + + requires com.pi4j; + requires com.pi4j.library.gpiod; + requires jsch; + + exports com.pi4j.plugin.gpiod; + exports com.pi4j.plugin.gpiod.provider.gpio.digital; + + provides com.pi4j.extension.Plugin + with GpioDPlugin; +} diff --git a/plugins/pi4j-plugin-gpiod/src/main/resources/services/com.pi4j.extension.Plugin b/plugins/pi4j-plugin-gpiod/src/main/resources/services/com.pi4j.extension.Plugin new file mode 100644 index 00000000..e42965da --- /dev/null +++ b/plugins/pi4j-plugin-gpiod/src/main/resources/services/com.pi4j.extension.Plugin @@ -0,0 +1 @@ +com.pi4j.plugin.gpiod.GpioDPlugin \ No newline at end of file diff --git a/plugins/pi4j-plugin/pom.xml b/plugins/pi4j-plugin/pom.xml index 51b66a3c..6e41d6ea 100644 --- a/plugins/pi4j-plugin/pom.xml +++ b/plugins/pi4j-plugin/pom.xml @@ -31,6 +31,7 @@ ../pi4j-plugin-pigpio ../pi4j-plugin-raspberrypi ../pi4j-plugin-linuxfs + ../pi4j-plugin-gpiod diff --git a/pom.xml b/pom.xml index 8d209a86..f8aa888c 100644 --- a/pom.xml +++ b/pom.xml @@ -291,6 +291,20 @@ ${pi4j.gpg.key} + + + com.pi4j.test/com.pi4j.test.GpiodTest + + + + + cocktailpi.local + 22 + pi + raspberry + /home/pi/deploy + +