Signed-off-by: Hoang Le <[email protected]>
---
.gitignore | 16 +
Makefile.am | 12 +-
configure.ac | 19 +-
demos/Makefile.am | 4 +
demos/tipcj/Makefile.am | 3 +
demos/tipcj/connection/Common.java | 9 +
demos/tipcj/connection/Makefile.am | 34 ++
demos/tipcj/connection/Manifest_client.txt | 3 +
demos/tipcj/connection/Manifest_server.txt | 3 +
demos/tipcj/connection/Tipc_Java_Api_Client.java | 227 ++++++++
demos/tipcj/connection/Tipc_Java_Api_Server.java | 170 ++++++
demos/tipcj/hello_world/Hello_Java_Api_Client.java | 70 +++
demos/tipcj/hello_world/Hello_Java_Api_Server.java | 59 ++
demos/tipcj/hello_world/Makefile.am | 29 +
demos/tipcj/hello_world/Manifest_client.txt | 3 +
demos/tipcj/hello_world/Manifest_server.txt | 3 +
tipcj/Makefile.am | 33 ++
tipcj/Manifest.txt | 2 +
tipcj/com/tipcj/Poll.java | 47 ++
tipcj/com/tipcj/ServiceType.java | 23 +
tipcj/com/tipcj/SocketType.java | 24 +
tipcj/com/tipcj/TipcAddr.java | 65 +++
tipcj/com/tipcj/TipcBaseApi.java | 166 ++++++
tipcj/com/tipcj/TipcConfig.java | 49 ++
tipcj/com/tipcj/TipcConn.java | 320 +++++++++++
tipcj/com/tipcj/TipcHelper.java | 53 ++
tipcj/com/tipcj/TipcServiceRange.java | 65 +++
tipcj/com/tipcj/TipcSrvConn.java | 108 ++++
tipcj/include/tipcjni.h | 221 ++++++++
tipcj/libtipcj.c | 594 +++++++++++++++++++++
30 files changed, 2431 insertions(+), 3 deletions(-)
create mode 100644 demos/tipcj/Makefile.am
create mode 100644 demos/tipcj/connection/Common.java
create mode 100644 demos/tipcj/connection/Makefile.am
create mode 100644 demos/tipcj/connection/Manifest_client.txt
create mode 100644 demos/tipcj/connection/Manifest_server.txt
create mode 100644 demos/tipcj/connection/Tipc_Java_Api_Client.java
create mode 100644 demos/tipcj/connection/Tipc_Java_Api_Server.java
create mode 100644 demos/tipcj/hello_world/Hello_Java_Api_Client.java
create mode 100644 demos/tipcj/hello_world/Hello_Java_Api_Server.java
create mode 100644 demos/tipcj/hello_world/Makefile.am
create mode 100644 demos/tipcj/hello_world/Manifest_client.txt
create mode 100644 demos/tipcj/hello_world/Manifest_server.txt
create mode 100644 tipcj/Makefile.am
create mode 100644 tipcj/Manifest.txt
create mode 100644 tipcj/com/tipcj/Poll.java
create mode 100644 tipcj/com/tipcj/ServiceType.java
create mode 100644 tipcj/com/tipcj/SocketType.java
create mode 100644 tipcj/com/tipcj/TipcAddr.java
create mode 100644 tipcj/com/tipcj/TipcBaseApi.java
create mode 100644 tipcj/com/tipcj/TipcConfig.java
create mode 100644 tipcj/com/tipcj/TipcConn.java
create mode 100644 tipcj/com/tipcj/TipcHelper.java
create mode 100644 tipcj/com/tipcj/TipcServiceRange.java
create mode 100644 tipcj/com/tipcj/TipcSrvConn.java
create mode 100644 tipcj/include/tipcjni.h
create mode 100644 tipcj/libtipcj.c
diff --git a/.gitignore b/.gitignore
index 39d06a7af575..29f32b08d354 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,3 +58,19 @@ demos/golang/hello_world/hello_go_api_server
libtipc/libtipc.a
test/overlapping_ranges/overlap_client
test/overlapping_ranges/overlap_server
+
+# Standard shared library
+*.so
+
+# All java .class
+*.class
+*.jar
+
+# All java packages
+tipcj/.libs
+demos/tipcj/hello_world/Hello_Java_Api_Client.tar.gz
+demos/tipcj/hello_world/Hello_Java_Api_Server.tar.gz
+demos/tipcj/hello_world/.libs
+demos/tipcj/connection/Tipc_Java_Api_Client.tar.gz
+demos/tipcj/connection/Tipc_Java_Api_Server.tar.gz
+demos/tipcj/connection/.libs
diff --git a/Makefile.am b/Makefile.am
index 37d0385b9171..bac4bb3d3e4a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1 +1,11 @@
-SUBDIRS=man scripts libtipc demos test utils
+SUBDIRS=man scripts libtipc
+
+if TIPC_GOAPI_EXAMPLE
+SUBDIRS+=golang
+endif
+
+if TIPC_JAVA
+SUBDIRS+=tipcj
+endif
+
+SUBDIRS+=demos test utils
diff --git a/configure.ac b/configure.ac
index c5fa53165526..6ffd6d2552c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,7 +24,7 @@ AC_CHECK_TYPE(struct tipc_sioc_ln_req, [tipc_lss=yes],[],
[[#include <linux/tipc
AM_CONDITIONAL(TIPC_LINK_STATE_SUBSCRITION, test "x$tipc_lss" = "xyes")
# Checks for TIPC GO API
-AC_ARG_WITH(goapi,[ --with-goapi Compile TIPC GO APIs
examples],[goapi=true],[])
+AC_ARG_WITH(goapi,[ --with-goapi Compile TIPC GO APIs
examples],[goapi=true],[])
if test "x$goapi" == "xtrue"; then
AC_CHECK_PROG([gotool],[go],[true],[])
if test "x$gotool" != "xtrue"; then
@@ -33,6 +33,17 @@ if test "x$goapi" == "xtrue"; then
fi
AM_CONDITIONAL(TIPC_GOAPI_EXAMPLE, test "x$goapi" == "xtrue" -a "x$gotool" ==
"xtrue")
+# Checks for TIPC JAVA API
+AC_ARG_WITH(tipcj,[ --with-tipcj Compile TIPC JAVA API and a couple of
examples],[with_tipcj=true],[])
+if test "x$with_tipcj" == "xtrue"; then
+ AM_PROG_GCJ
+ AC_CHECK_PROG([javac],[javac],[true],[])
+ if test "x$javac" != "xtrue"; then
+ AC_MSG_NOTICE([javac are not available - ignore java
compiling])
+ fi
+fi
+AM_CONDITIONAL(TIPC_JAVA, test "x$with_tipcj" == "xtrue" -a "x$javac" ==
"xtrue")
+
AC_CONFIG_FILES([
Makefile
libtipc/Makefile
@@ -60,8 +71,12 @@ AC_CONFIG_FILES([
demos/golang/Makefile
demos/golang/hello_world/Makefile
demos/golang/connection/Makefile
- man/Makefile
+ man/Makefile
scripts/Makefile
+ tipcj/Makefile
+ demos/tipcj/Makefile
+ demos/tipcj/hello_world/Makefile
+ demos/tipcj/connection/Makefile
])
AM_CONDITIONAL(WITH_SCRIPTS, false)
AC_ARG_ENABLE(scripts,
diff --git a/demos/Makefile.am b/demos/Makefile.am
index 1d1a9fe17707..475c7044a362 100644
--- a/demos/Makefile.am
+++ b/demos/Makefile.am
@@ -8,3 +8,7 @@ endif
if TIPC_GOAPI_EXAMPLE
SUBDIRS+= golang
endif
+
+if TIPC_JAVA
+SUBDIRS+= tipcj
+endif
diff --git a/demos/tipcj/Makefile.am b/demos/tipcj/Makefile.am
new file mode 100644
index 000000000000..a5b28ac5205e
--- /dev/null
+++ b/demos/tipcj/Makefile.am
@@ -0,0 +1,3 @@
+if TIPC_JAVA
+SUBDIRS = hello_world connection
+endif
diff --git a/demos/tipcj/connection/Common.java
b/demos/tipcj/connection/Common.java
new file mode 100644
index 000000000000..d1d5f2a3fac6
--- /dev/null
+++ b/demos/tipcj/connection/Common.java
@@ -0,0 +1,9 @@
+package com.tipcj.demos;
+
+public interface Common {
+ public static final int RDM_SRV_TYPE = 18888;
+ public static final int STREAM_SRV_TYPE = 17777;
+ public static final int SEQPKT_SRV_TYPE = 16666;
+ public static final int SRV_INST = 17;
+ public static final int BUF_SIZE = 40;
+}
diff --git a/demos/tipcj/connection/Makefile.am
b/demos/tipcj/connection/Makefile.am
new file mode 100644
index 000000000000..ec07b5ed4427
--- /dev/null
+++ b/demos/tipcj/connection/Makefile.am
@@ -0,0 +1,34 @@
+bin_PROGRAMS=Tipc_Java_Api_Client Tipc_Java_Api_Server
+
+Tipc_Java_Api_Client_SOURCES=
+Tipc_Java_Api_Server_SOURCES=
+
+CLIENT_OBJECTS=com/tipcj/demos/Common.class \
+ com/tipcj/demos/Tipc_Java_Api_Client.class
+
+
+SERVER_OBJECTS=com/tipcj/demos/Common.class \
+ com/tipcj/demos/Tipc_Java_Api_Server.class
+
+CLEANFILES=$(CLIENT_OBJECTS) $(SERVER_OBJECTS)
+
+Tipc_Java_Api_Client$(EXEEXT): $(CLIENT_OBJECTS)
+ $(shell $(MKDIR_P) .libs)
+ $(shell cd .libs && jar cfm ../[email protected] ../Manifest_client.txt
$(CLIENT_OBJECTS))
+ tar cvfz [email protected] [email protected] -C ../../../tipcj .libs/libtipcj.jar
.libs/libtipcj.so
+ cp ../../../tipcj/.libs/libtipcj.jar ../../../tipcj/.libs/libtipcj.so
.libs
+
+com/tipcj/demos/%.class: %.java
+ @echo "Compiling $<"
+ $(shell $(MKDIR_P) .libs)
+ $(shell javac -cp ../../../tipcj/.libs:.libs -d .libs $< )
+
+Tipc_Java_Api_Server$(EXEEXT): $(SERVER_OBJECTS)
+ $(shell $(MKDIR_P) .libs)
+ $(shell cd .libs && jar cfm ../[email protected] ../Manifest_server.txt
$(SERVER_OBJECTS))
+ tar cvfz [email protected] [email protected] -C ../../../tipcj .libs/libtipcj.jar
.libs/libtipcj.so
+ cp ../../../tipcj/.libs/libtipcj.jar ../../../tipcj/.libs/libtipcj.so
.libs
+
+clean-generic:
+ rm -rf Tipc_Java_Api_Client$(EXEEXT).jar
Tipc_Java_Api_Server$(EXEEXT).jar Tipc_Java_Api_Client$(EXEEXT).tar.gz
Tipc_Java_Api_Server$(EXEEXT).tar.gz
+
diff --git a/demos/tipcj/connection/Manifest_client.txt
b/demos/tipcj/connection/Manifest_client.txt
new file mode 100644
index 000000000000..19a9015fd403
--- /dev/null
+++ b/demos/tipcj/connection/Manifest_client.txt
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: com.tipcj.demos.Tipc_Java_Api_Client
+Class-Path: .libs/libtipcj.jar .libs/libtipcj.so
diff --git a/demos/tipcj/connection/Manifest_server.txt
b/demos/tipcj/connection/Manifest_server.txt
new file mode 100644
index 000000000000..ad93f6a304ac
--- /dev/null
+++ b/demos/tipcj/connection/Manifest_server.txt
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: com.tipcj.demos.Tipc_Java_Api_Server
+Class-Path: .libs/libtipcj.jar .libs/libtipcj.so
diff --git a/demos/tipcj/connection/Tipc_Java_Api_Client.java
b/demos/tipcj/connection/Tipc_Java_Api_Client.java
new file mode 100644
index 000000000000..42564910475b
--- /dev/null
+++ b/demos/tipcj/connection/Tipc_Java_Api_Client.java
@@ -0,0 +1,227 @@
+package com.tipcj.demos;
+
+import java.nio.ByteBuffer;
+
+import com.tipcj.*;
+
+public class Tipc_Java_Api_Client {
+ public int[] pfds;
+ public short[] events;
+ public Integer[] revents;
+ public TipcSrvConn topSrv;
+ public Integer up;
+ public TipcAddr srvAddr;
+ public TipcConn rdmConn;
+ public TipcConn streamConn;
+ public TipcConn seqpacketConn;
+
+ public long rdm_service_demo() {
+ byte[] inbuf = new byte[Common.BUF_SIZE];
+ ByteBuffer bytebuffer =
ByteBuffer.allocateDirect(Common.BUF_SIZE);
+ byte[] msg = new String("Hello World!!!").getBytes();
+ int ret;
+ Integer err = new Integer(0);
+
+ if (up == 0) {
+ System.out.println("Service on SOCK_RDM went down");
+ return 0;
+ }
+ System.out.println("-------------------------------------");
+ System.out.println("Service on SOCK_RDM came up");
+ System.out.println("Sending msg: " + new String(msg) + " on
SOCK_RDM --> " + srvAddr);
+
+ if (rdmConn.Sock_Rejectable() < 0) {
+ System.err.println("Set rejectable failed");
+ return 0;
+ }
+
+ if (rdmConn.Sendto(msg, srvAddr) != msg.length) {
+ System.err.println("sendto() failed");
+ return 0;
+ }
+
+ ret = rdmConn.Recvfrom(bytebuffer, bytebuffer.limit(), srvAddr,
null, err);
+ if ((ret < 0) || (err != 0)) {
+ System.err.println("Unexpected response");
+ return 0;
+ }
+
+ bytebuffer.get(inbuf, 0, ret);
+ System.out.println("Received response: " + new String(inbuf) +
" <--" + srvAddr);
+ return srvAddr.Node;
+ }
+
+ public void rdm_reject_demo(long srv_node) {
+ TipcAddr invalid = new TipcAddr(42, 1, srv_node);
+ byte[] msg = new String("Hello World").getBytes();
+ byte[] inbuf = new byte[Common.BUF_SIZE];
+ ByteBuffer bytebuffer =
ByteBuffer.allocateDirect(Common.BUF_SIZE);
+ Integer err = new Integer(0);
+ int ret;
+
+ if (up == 0) {
+ return;
+ }
+
+ System.out.println("Sending msg: " + new String(msg) + " on
SOCK_RDM --> " + invalid + " (non-existing)");
+ if (rdmConn.Sendto(msg, invalid) != msg.length) {
+ System.out.println("Client sendto() failed: No route to
host");
+ return;
+ }
+
+ ret = rdmConn.Recvfrom(bytebuffer, bytebuffer.limit(), srvAddr,
null, err);
+ if ((ret < 0) || (err == 0)) {
+ System.err.println(String.format("Unexpected response
err:%d", err));
+ }
+ bytebuffer.get(inbuf, 0, ret);
+ System.out.println("Received rejected msg: '" + new
String(inbuf) + "' <-- " + srvAddr + " err:" + err);
+ System.out.println("-------------------------------------");
+ }
+
+ public void stream_service_demo() {
+ TipcAddr srv = new TipcAddr(Common.STREAM_SRV_TYPE,
Common.SRV_INST, 0);
+ byte[] msg = new String("Hello World").getBytes();
+ byte[] inbuf = new byte[Common.BUF_SIZE];
+ int ret = 0;
+
+ if (up == 0) {
+ System.out.println("Service on SOCK_STREAM went down");
+ return;
+ }
+ System.out.println("-------------------------------------");
+ System.out.println("Service on SOCK_STREAM came up");
+ System.out.println("Performing implicit two-way connect with
message '" + new String(msg) + "' --> " + srv);
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ex) {}
+
+ ret = streamConn.Sendto(msg, srv);
+ if (ret != msg.length) {
+ System.err.println("send() failed");
+ }
+
+ System.err.println("Receiving ...");
+ ret = streamConn.Recv(inbuf, false);
+ if (ret <= 0) {
+ System.err.println("Unexpected response");
+ return;
+ }
+
+ System.out.println("Received response: " + new String(inbuf) +
" on SOCK_STREAM connection");
+ System.out.println("SOCK_STREAM connection established --> " +
srvAddr);
+ System.out.println("-------------------------------------");
+ }
+
+ public void seqpacket_service_demo() {
+ TipcAddr srv = new TipcAddr(Common.SEQPKT_SRV_TYPE,
Common.SRV_INST, 0);
+ byte[] msg = new String("Hello World").getBytes();
+ byte[] inbuf = new byte[Common.BUF_SIZE];
+ int ret = 0;
+
+ if (up == 0) {
+ System.out.println("Service on SOCK_SEQPACKET went
down");
+ return;
+ }
+
+ System.out.println("-------------------------------------");
+ System.out.println("Service on SOCK_SEQPACKET came up");
+
+ System.out.println("Connecting to: -->" + srvAddr);
+
+ ret = seqpacketConn.Connect(srvAddr);
+ if (ret < 0) {
+ System.err.println("connect() failed");
+ return;
+ }
+
+ System.out.println(String.format("Sending msg: %s on
connection", new String(msg)));
+ ret = seqpacketConn.Send(msg);
+ if (ret != msg.length) {
+ System.err.println("send() failed");
+ return;
+ }
+
+ ret = seqpacketConn.Recv(inbuf, true);
+ if (ret <= 0) {
+ System.err.println("Unexpected response");
+ return;
+ }
+
+ System.out.println("Received response: " + new String(inbuf) +
" on SOCK_SEQPACKET connection");
+ System.out.println("-------------------------------------");
+ }
+
+ public Tipc_Java_Api_Client() {
+ /* Create traffic sockets */
+ rdmConn = new TipcConn(SocketType.SOCK_RDM);
+ streamConn = new TipcConn(SocketType.SOCK_STREAM);
+ seqpacketConn = new TipcConn(SocketType.SOCK_SEQPACKET);
+
+ /* Subscribe for service events */
+ topSrv = new TipcSrvConn(0);
+
+ pfds = new int[] {rdmConn.GetFd(), streamConn.GetFd(),
seqpacketConn.GetFd(), topSrv.getFd()};
+ events = new short[] {Poll.EPOLLIN, Poll.EPOLLIN |
Poll.EPOLLHUP, Poll.EPOLLIN | Poll.EPOLLHUP, Poll.EPOLLIN | Poll.EPOLLHUP};
+ revents = new Integer[pfds.length];
+
+ srvAddr = new TipcAddr(Common.RDM_SRV_TYPE, Common.SRV_INST, 0);
+ up = new Integer(0);
+
+ System.out.println("Waiting for Service " + srvAddr);
+ TipcSrvConn.SrvWait(srvAddr, -1);
+
+ if (topSrv.SrvScr(Common.RDM_SRV_TYPE, 0, ~0, false, -1) != 0) {
+ System.err.println("subscribe for RDM server failed");
+ }
+
+ if (topSrv.SrvScr(Common.STREAM_SRV_TYPE, 0, ~0, false, -1) !=
0) {
+ System.err.println("subscribe for STREAM server
failed");
+ }
+
+ if (topSrv.SrvScr(Common.SEQPKT_SRV_TYPE, 0, ~0, false, -1) !=
0) {
+ System.err.println("subscribe for SEQPACKET server
failed");
+ }
+
+ while (Poll.pollset(pfds, events, revents, 3000000) >=0) {
+ if ((revents[1] & Poll.EPOLLHUP) != 0) {
+ System.out.println("SOCK_STREAM connection
hangup");
+ streamConn.Close();
+ streamConn = new
TipcConn(SocketType.SOCK_STREAM);
+ pfds[1] = streamConn.GetFd();
+ }
+
+ if ((revents[2] & Poll.EPOLLHUP) != 0) {
+ System.out.println("SOCK_SEQPACKET connection
hangup");
+ seqpacketConn.Close();
+ seqpacketConn = new
TipcConn(SocketType.SOCK_SEQPACKET);
+ pfds[2] = seqpacketConn.GetFd();
+ }
+
+ if ((revents[3] & Poll.EPOLLIN) != 0) {
+ if (topSrv.GetEvt(srvAddr, null, up, new
Integer(0)) != 0) {
+ System.err.println("reception of
service event failed");
+ break;
+ }
+ if (srvAddr.Type == Common.RDM_SRV_TYPE) {
+ long srv_node = rdm_service_demo();
+ rdm_reject_demo(srv_node);
+ }
+
+ if (srvAddr.Type == Common.STREAM_SRV_TYPE) {
+ stream_service_demo();
+ }
+ if (srvAddr.Type == Common.SEQPKT_SRV_TYPE) {
+ seqpacket_service_demo();
+ }
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ System.out.println("****** TIPC JAVA API Demo Client Started
******");
+ new Tipc_Java_Api_Client();
+ System.out.println("****** TIPC JAVA API Demo Finished ******");
+ }
+
+}
diff --git a/demos/tipcj/connection/Tipc_Java_Api_Server.java
b/demos/tipcj/connection/Tipc_Java_Api_Server.java
new file mode 100644
index 000000000000..f71ce8fe370f
--- /dev/null
+++ b/demos/tipcj/connection/Tipc_Java_Api_Server.java
@@ -0,0 +1,170 @@
+package com.tipcj.demos;
+
+import java.math.BigInteger;
+
+import com.tipcj.*;
+
+public class Tipc_Java_Api_Server implements Runnable {
+
+ public TipcConn rdmsd;
+ public TipcConn strsd;
+ public TipcConn pktsd;
+
+ public TipcConn bind_service(int type, int scope, SocketType sktype,
String sk_str) {
+ TipcConn srv = new TipcConn(sktype);
+ int ret = 0;
+
+ if (srv.GetFd() <= 0) {
+ System.out.println("failed to create " + sk_str +"
socket");
+ return null;
+ }
+
+ ret = srv.Bind(type, 0, ~0, scope);
+ if (ret != 0) {
+ System.err.println("failed to bind " + sk_str + "
socket");
+ srv.Close();
+ return null;
+ }
+
+ System.out.println("Bound " + sk_str + " socket " +
srv.Sockaddr() + " to " + new TipcServiceRange(type, 0, ~0, scope));
+ return srv;
+ }
+
+ public void recv_rdm_msg() {
+ byte[] msg = new byte[Common.BUF_SIZE];
+ TipcAddr cli = new TipcAddr();
+ Integer err = new Integer(0);
+
+ int ret = 0;
+
+ ret = rdmsd.Recvfrom(msg, cli, null, err);
+ System.out.println("-------------------------------------");
+ if (ret <= 0) {
+ System.out.println("unexpected message on RDM socket");
+ return;
+ }
+
+ System.out.println(String.format("Received msg: %s on SOCK_RDM
<-- %s", new String(msg), cli));
+ System.out.println(String.format("Responding with: %s --> %s",
new String("Huh?"), cli));
+
+ ret = rdmsd.Sendto(new String("Huh?").getBytes(), cli);
+ if (ret <= 0) {
+ System.out.println("Server: failed to send");
+ }
+ System.out.println("-------------------------------------");
+ }
+
+ public int recv_stream_setup() {
+ int newsd;
+ TipcAddr cli = new TipcAddr();
+ byte[] msg = new byte[Common.BUF_SIZE];
+ int ret = -1;
+
+ System.out.println("-------------------------------------");
+
+ strsd.Listen(32);
+ newsd = strsd.Accept(cli);
+ if (newsd <= 0) {
+ System.out.println("accept on SOCK_STREAM failed");
+ return -1;
+ }
+
+ ret = strsd.Recv(newsd, msg, false);
+ if (ret <= 0) {
+ System.out.println("unexpected message on STREAM
socket\n");
+ return -1;
+ }
+
+ System.out.println(String.format("Received msg: %s on STREAM
connection", new String(msg)));
+ System.out.println(String.format("SOCK_STREAM connection
established --> %s", cli));
+
+ System.out.println(String.format("Responding with: %s", new
String("Huh?")));
+
+ ret = strsd.Send(newsd, new String("Huh?").getBytes());
+ if (ret <= 0) {
+ System.out.println("failed to respond");
+ return -1;
+ }
+
+ System.out.println("-------------------------------------");
+ return newsd;
+ }
+
+ public int recv_seqpacket_setup() {
+ int newsd;
+ TipcAddr cli = new TipcAddr();
+ byte[] msg = new byte[Common.BUF_SIZE];
+ int ret = -1;
+
+ System.out.println("-------------------------------------");
+ pktsd.Listen(32);
+ newsd = pktsd.Accept(cli);
+
+ if (newsd <= 0) {
+ System.out.println("accept on SOCK_SEQPACKET failed");
+ return -1;
+ }
+
+ System.out.println(String.format("SOCK_SEQPACKET connection
established <-- %s", cli));
+
+ ret = pktsd.Recv(newsd, msg, true);
+ if (ret <= 0) {
+ System.out.println("unexpected message on
SOCK_SEQPACKET socket\n");
+ return -1;
+ }
+ System.out.println(String.format("Received msg: %s on
SOCK_SEQPACKET connection", new String(msg)));
+ System.out.println(String.format("Responding with: %s", new
String("Huh?")));
+
+ ret = pktsd.Send(newsd, new String("Huh?").getBytes());
+ if (ret <= 0) {
+ System.out.println("failed to respond");
+ return -1;
+ }
+
+ System.out.println("-------------------------------------");
+ return newsd;
+ }
+
+ public void run() {
+ // TODO Auto-generated method stub
+ final int[] fds = new int[] {0, 0};
+ final short[] events = new short[] { Poll.EPOLLIN |
Poll.EPOLLHUP, Poll.EPOLLIN | Poll.EPOLLHUP };
+ final Integer[] revents = new Integer[fds.length];
+
+ while (true) {
+ recv_rdm_msg();
+ fds[0] = recv_stream_setup();
+ fds[1] = recv_seqpacket_setup();
+ while (Poll.pollset(fds, events, revents, 3000000) >=0)
{
+ for (int i = 0; i<fds.length; i++) {
+ if ((revents[i] & Poll.EPOLLHUP) != 0) {
+
System.out.println("-------------------------------------");
+ if (i == 0) {
+
System.out.println("SOCK_STREAM Connection hangup");
+ } else {
+
System.out.println("SOCK_SEQPACKET Connection hangup");
+ }
+ TipcConn.Close(fds[i]);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ public Tipc_Java_Api_Server() {
+ this.rdmsd = bind_service(Common.RDM_SRV_TYPE, 0,
SocketType.SOCK_RDM, "RDM");
+ this.strsd = bind_service(Common.STREAM_SRV_TYPE, 0,
SocketType.SOCK_STREAM, "STREAM");
+ this.pktsd = bind_service(Common.SEQPKT_SRV_TYPE, 0,
SocketType.SOCK_SEQPACKET, "SEQPACKET");
+ }
+
+ public static void main(String[] args) {
+ System.out.println("****** TIPC JAVA API Demo Server Started
******");
+ Tipc_Java_Api_Server demo = new Tipc_Java_Api_Server();
+
+ // Looping handle
+ demo.run();
+ System.out.println("****** TIPC JAVA API Demo Server Finished
******");
+ }
+
+}
diff --git a/demos/tipcj/hello_world/Hello_Java_Api_Client.java
b/demos/tipcj/hello_world/Hello_Java_Api_Client.java
new file mode 100644
index 000000000000..9ded0891b53e
--- /dev/null
+++ b/demos/tipcj/hello_world/Hello_Java_Api_Client.java
@@ -0,0 +1,70 @@
+package com.tipcj.demos;
+
+import java.nio.ByteBuffer;
+
+import com.tipcj.*;
+
+public class Hello_Java_Api_Client {
+ public static final int SERVER_TYPE = 18888;
+ public static final int SERVER_INST = 17;
+ public static final int BUF_SIZE = 40;
+
+ public static void main(String[] args) {
+ TipcConn tipcConn = null;
+ TipcAddr server = new TipcAddr(SERVER_TYPE, SERVER_INST, 0);
+ byte[] inbuf = new byte[BUF_SIZE];
+ byte[] outbuf = new String("Hello World!!!").getBytes();
+ boolean up = false;
+ ByteBuffer bytebuffer = ByteBuffer.allocateDirect(BUF_SIZE);
+
+ System.out.println("****** TIPC hello world client started
******\n");
+
+ up = TipcSrvConn.SrvWait(server, 10000);
+ if (!up) {
+ System.out.println("Client: server {" + SERVER_TYPE +
"," + SERVER_INST + "} not published within 10 [s]");
+ return;
+ }
+
+ tipcConn = new TipcConn(SocketType.SOCK_RDM);
+ if (tipcConn.Sendto(outbuf, server) < 0) {
+ System.out.println("Client: failed to send");
+ tipcConn.Close();
+ return;
+ }
+
+ System.out.println("Client: sent message: " + new
String(outbuf));
+
+ int ret = tipcConn.Recv(bytebuffer, bytebuffer.capacity(),
false);
+ if (ret <= 0 ) {
+ System.out.println("Client: unexpected response");
+ tipcConn.Close();
+ return;
+ }
+
+ bytebuffer.get(inbuf, 0, ret);
+ System.out.println("Client: received response: " + new
String(inbuf));
+
+ /**
+ * Topology tracking
+ */
+ /**
+ TipcSrvConn srvTrack = new TipcSrvConn(0,
ServiceType.TIPC_LINK_STATE);
+ TipcAddr srvAddr = new TipcAddr();
+ TipcAddr idAddr = new TipcAddr();
+ Integer upEvt = new Integer(0);
+ Integer expire = new Integer(0);
+
+ while (srvTrack.GetEvt(srvAddr, idAddr, upEvt, expire) >= 0) {
+ System.out.println(srvAddr + "-" + idAddr + "-" +
upEvt.toString() + "-" + expire.toString());
+ try {
+ //sleep 1 seconds
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ */
+ System.out.println("****** TIPC hello client finished ******");
+ tipcConn.Close();
+ }
+}
diff --git a/demos/tipcj/hello_world/Hello_Java_Api_Server.java
b/demos/tipcj/hello_world/Hello_Java_Api_Server.java
new file mode 100644
index 000000000000..03e9324d2a14
--- /dev/null
+++ b/demos/tipcj/hello_world/Hello_Java_Api_Server.java
@@ -0,0 +1,59 @@
+package com.tipcj.demos;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+
+import com.tipcj.*;
+
+public class Hello_Java_Api_Server {
+ public static final int SERVER_TYPE = 18888;
+ public static final int SERVER_INST = 17;
+ public static final int BUF_SIZE = 40;
+
+ public static void main(String[] args) {
+ ByteBuffer bytebuffer = ByteBuffer.allocateDirect(BUF_SIZE);
+ byte[] inbuf = new byte[BUF_SIZE];
+ byte[] outbuf = new String("Uh?").getBytes();
+ TipcConn serverConn = null;
+ int ret;
+
+ System.out.println("****** TIPC hello world server started
******\n");
+
+ /**
+ * Create TipcConn instance
+ */
+ serverConn = new TipcConn(SocketType.SOCK_RDM);
+
+ /**
+ * Bind to service instance
+ */
+ ret = serverConn.Bind(SERVER_TYPE, SERVER_INST, SERVER_INST, 0);
+ if (ret != 0) {
+ System.out.println("Server: failed to bind port name");
+ serverConn.Close();
+ return;
+ }
+
+ Integer err = new Integer(0);
+ TipcAddr client = new TipcAddr();
+
+ ret = serverConn.Recvfrom(bytebuffer, bytebuffer.capacity(),
client, null, err);
+ if (ret <= 0) {
+ System.out.println("Server: unexpected message");
+ return;
+ }
+
+ bytebuffer.duplicate().get(inbuf, 0, ret);
+ System.out.println("Server: Message received: " + new
String(inbuf));
+
+ ret = serverConn.Sendto(outbuf, client);
+ if (ret < 0) {
+ System.out.println("Server: failed to send");
+ }
+
+ System.out.println("Server: Sent response : " + new
String(outbuf));
+ System.out.println("****** TIPC hello world server finished
******");
+
+ serverConn.Close();
+ }
+}
diff --git a/demos/tipcj/hello_world/Makefile.am
b/demos/tipcj/hello_world/Makefile.am
new file mode 100644
index 000000000000..92e5ee6e9dff
--- /dev/null
+++ b/demos/tipcj/hello_world/Makefile.am
@@ -0,0 +1,29 @@
+bin_PROGRAMS=Hello_Java_Api_Client Hello_Java_Api_Server
+
+Hello_Java_Api_Client_SOURCES=
+Hello_Java_Api_Server_SOURCES=
+
+CLIENT_OBJECTS=com/tipcj/demos/Hello_Java_Api_Client.class
+SERVER_OBJECTS=com/tipcj/demos/Hello_Java_Api_Server.class
+CLEANFILES=$(CLIENT_OBJECTS) $(SERVER_OBJECTS)
+
+Hello_Java_Api_Client$(EXEEXT): $(CLIENT_OBJECTS)
+ $(shell $(MKDIR_P) .libs)
+ jar cfm [email protected] ./Manifest_client.txt -C .libs $(CLIENT_OBJECTS)
+ tar cvfz [email protected] [email protected] -C ../../../tipcj .libs/libtipcj.jar
.libs/libtipcj.so
+ cp ../../../tipcj/.libs/libtipcj.jar ../../../tipcj/.libs/libtipcj.so
.libs
+
+com/tipcj/demos/%.class: %.java
+ @echo "Compiling $<"
+ $(shell $(MKDIR_P) .libs)
+ $(shell javac -cp ../../../tipcj/.libs:.libs -d .libs $< )
+
+Hello_Java_Api_Server$(EXEEXT): $(SERVER_OBJECTS)
+ $(shell $(MKDIR_P) .libs)
+ jar cfm [email protected] ./Manifest_server.txt -C .libs $(SERVER_OBJECTS)
+ tar cvfz [email protected] [email protected] -C ../../../tipcj .libs/libtipcj.jar
.libs/libtipcj.so
+ cp ../../../tipcj/.libs/libtipcj.jar ../../../tipcj/.libs/libtipcj.so
.libs
+
+clean-generic:
+ rm -rf Hello_Java_Api_Client$(EXEEXT).jar
Hello_Java_Api_Server$(EXEEXT).jar Hello_Java_Api_Client$(EXEEXT).tar.gz
Hello_Java_Api_Server$(EXEEXT).tar.gz
+
diff --git a/demos/tipcj/hello_world/Manifest_client.txt
b/demos/tipcj/hello_world/Manifest_client.txt
new file mode 100644
index 000000000000..85269a85a124
--- /dev/null
+++ b/demos/tipcj/hello_world/Manifest_client.txt
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: com.tipcj.demos.Hello_Java_Api_Client
+Class-Path: .libs/libtipcj.jar .libs/libtipcj.so
diff --git a/demos/tipcj/hello_world/Manifest_server.txt
b/demos/tipcj/hello_world/Manifest_server.txt
new file mode 100644
index 000000000000..3a02ffd1935e
--- /dev/null
+++ b/demos/tipcj/hello_world/Manifest_server.txt
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: com.tipcj.demos.Hello_Java_Api_Server
+Class-Path: .libs/libtipcj.jar .libs/libtipcj.so
diff --git a/tipcj/Makefile.am b/tipcj/Makefile.am
new file mode 100644
index 000000000000..a92b43ea4c31
--- /dev/null
+++ b/tipcj/Makefile.am
@@ -0,0 +1,33 @@
+#AUTOMAKE_OPTIONS=subdir-objects
+CPPFLAGS+=-I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -I./include
+
+bin_PROGRAMS=tipcj
+tipcj_SOURCES=
+
+TIPCJ_OBJECTS=com/tipcj/ServiceType.class \
+ com/tipcj/TipcConfig.class \
+ com/tipcj/SocketType.class \
+ com/tipcj/TipcBaseApi.class \
+ com/tipcj/TipcAddr.class \
+ com/tipcj/TipcConn.class \
+ com/tipcj/TipcHelper.class \
+ com/tipcj/TipcSrvConn.class \
+ com/tipcj/TipcServiceRange.class \
+ com/tipcj/Poll.class
+
+tipcj$(EXEEXT): libtipcj.so libtipcj.jar
+
+libtipcj.jar:
+ $(shell cd .libs && jar cfm $@ ../Manifest.txt $(TIPCJ_OBJECTS))
+
+libtipcj.so: .libs $(TIPCJ_OBJECTS) include/tipcjni.h
+ $(AM_V_CC)$(COMPILE) -fPIC -shared -o .libs/$@ libtipcj.c
../libtipc/libtipc.c
+
+include/tipcjni.h:
+ $(shell javah -o $@ -classpath .libs com.tipcj.TipcBaseApi)
+
+com/tipcj/%.class: com/tipcj/%.java
+ $(shell javac -d .libs $< )
+
+.libs:
+ $(shell $(MKDIR_P) .libs)
diff --git a/tipcj/Manifest.txt b/tipcj/Manifest.txt
new file mode 100644
index 000000000000..e8db25f64236
--- /dev/null
+++ b/tipcj/Manifest.txt
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Class-Path: libs/libtipcj.so
diff --git a/tipcj/com/tipcj/Poll.java b/tipcj/com/tipcj/Poll.java
new file mode 100644
index 000000000000..35f0929fbdf6
--- /dev/null
+++ b/tipcj/com/tipcj/Poll.java
@@ -0,0 +1,47 @@
+package com.tipcj;
+
+public class Poll {
+ /**
+ * Epoll event masks
+ */
+ public static final short EPOLLIN = 0x00000001;
+ public static final short EPOLLPRI = 0x00000002;
+ public static final short EPOLLOUT = 0x00000004;
+ public static final short EPOLLERR = 0x00000008;
+ public static final short EPOLLHUP = 0x00000010;
+ public static final short EPOLLNVAL = 0x00000020;
+ public static final short EPOLLRDNORM = 0x00000040;
+ public static final short EPOLLRDBAND = 0x00000080;
+ public static final short EPOLLWRNORM = 0x00000100;
+ public static final short EPOLLWRBAND = 0x00000200;
+ public static final short EPOLLMSG = 0x00000400;
+ public static final short EPOLLRDHUP = 0x00002000;
+
+ /**
+ * JNI instance
+ */
+ static {
+ tipcj = TipcBaseApi.getInstance();
+ }
+
+ public static final int poll(int fd, short events, java.lang.Integer
revents, int timeout) {
+ return tipcj.tipc_poll(fd, events, revents, timeout);
+ }
+
+ public static final int pollset(int[] fds, short events,
java.lang.Integer[] revents, int timeout) {
+ short[] jevents = new short[fds.length];
+ for (int i=0; i<fds.length; i++) {
+ jevents[i] = events;
+ }
+ return pollset(fds, jevents, revents, timeout);
+ }
+
+ public static final int pollset(int[] fds, short[] events,
java.lang.Integer[] revents, int timeout) {
+ for (int i=0; i<revents.length; i++) {
+ revents[i] = 0;
+ }
+ return tipcj.tipc_pollset(fds, events, revents, timeout);
+ }
+
+ private static TipcBaseApi tipcj;
+}
diff --git a/tipcj/com/tipcj/ServiceType.java b/tipcj/com/tipcj/ServiceType.java
new file mode 100644
index 000000000000..5f79c9e75bfc
--- /dev/null
+++ b/tipcj/com/tipcj/ServiceType.java
@@ -0,0 +1,23 @@
+package com.tipcj;
+
+public class ServiceType {
+ int val;
+
+ public ServiceType(int srvtype) {
+ this.val = srvtype;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof ServiceType) {
+ return val == ((ServiceType) obj).val;
+ }
+ return false;
+ }
+
+ /* node state service type */
+ public static final ServiceType TIPC_NODE_STATE = new
ServiceType(TipcConfig.TIPC_NODE_STATE);
+ /* topology server service type */
+ public static final ServiceType TIPC_TOP_SRV = new
ServiceType(TipcConfig.TIPC_TOP_SRV);
+ /* link state service type */
+ public static final ServiceType TIPC_LINK_STATE = new
ServiceType(TipcConfig.TIPC_LINK_STATE);
+}
diff --git a/tipcj/com/tipcj/SocketType.java b/tipcj/com/tipcj/SocketType.java
new file mode 100644
index 000000000000..6f3d6ae2eb00
--- /dev/null
+++ b/tipcj/com/tipcj/SocketType.java
@@ -0,0 +1,24 @@
+package com.tipcj;
+
+public final class SocketType {
+ int val;
+
+ @SuppressWarnings("unused")
+ private SocketType() {};
+
+ public SocketType(int sktype) {
+ this.val = sktype;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof SocketType) {
+ return val == ((SocketType) obj).val;
+ }
+ return false;
+ }
+
+ public static final SocketType SOCK_STREAM = new SocketType(1); /*
stream (connection) socket */
+ public static final SocketType SOCK_DGRAM = new SocketType(2); /*
datagram (conn.less) socket */
+ public static final SocketType SOCK_RDM = new SocketType(4); /*
reliably-delivered message */
+ public static final SocketType SOCK_SEQPACKET = new SocketType(5); /*
sequential packet socket */
+}
diff --git a/tipcj/com/tipcj/TipcAddr.java b/tipcj/com/tipcj/TipcAddr.java
new file mode 100644
index 000000000000..1670760ff4c5
--- /dev/null
+++ b/tipcj/com/tipcj/TipcAddr.java
@@ -0,0 +1,65 @@
+/**
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2018, Ericsson Canada
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of Ericsson Canada nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Version 0.1: Jon Maloy, 2018
+ *
+ * ------------------------------------------------------------------------
+ */
+
+package com.tipcj;
+
+/**
+ * @author Hoang Le ([email protected])
+ *
+ */
+public class TipcAddr {
+
+ public TipcAddr() {
+ Type = 0;
+ Instance = 0;
+ Node = 0;
+ }
+
+ public TipcAddr(long type, long instance, long node) {
+ Type = type;
+ Instance = instance;
+ Node = node;
+ }
+
+ public long Type = 0;
+ public long Instance = 0;
+ public long Node = 0;
+
+ public String toString() {
+ if (Type != 0) {
+ return String.format("%d:%d@%x", Type, Instance, Node);
+ }
+ return String.format("0:%010d@%x", Instance, Node);
+ }
+}
diff --git a/tipcj/com/tipcj/TipcBaseApi.java b/tipcj/com/tipcj/TipcBaseApi.java
new file mode 100644
index 000000000000..ffdaced07146
--- /dev/null
+++ b/tipcj/com/tipcj/TipcBaseApi.java
@@ -0,0 +1,166 @@
+/**
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2018, Ericsson Canada
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of Ericsson Canada nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Version 0.1: Jon Maloy, 2018
+ *
+ * ------------------------------------------------------------------------
+ */
+package com.tipcj;
+
+/**
+ *
+ */
+import java.io.*;
+import java.nio.*;
+import java.lang.reflect.Field;
+
+/**
+ * @author Hoang Le ([email protected])
+ *
+ */
+final class TipcBaseApi {
+
+ /**
+ * Some helper method
+ */
+ protected native int tipc_own_node();
+ protected native String tipc_linkname(long peer, long bearerid);
+
+ /**
+ * Socket: - 'Rejectable': sent messages will return if rejected at
+ * destination
+ */
+ protected native int tipc_socket(int sk_type);
+
+ protected native int tipc_sock_non_block(int sd);
+
+ protected native int tipc_sock_rejectable(int sd);
+
+ protected native int tipc_close(int sd);
+
+ protected native int tipc_sockaddr(int sd, TipcAddr addr);
+
+ protected native int tipc_bind(int sd, long type, long lower, long
upper, long scope);
+
+ protected native int tipc_unbind(int sd, long type, long lower, long
upper);
+
+ protected native int tipc_connect(int sd, TipcAddr dst);
+
+ protected native int tipc_listen(int sd, long backlog);
+
+ protected native int tipc_accept(int sd, TipcAddr src);
+
+ protected native int tipc_join(int sd, TipcAddr member, boolean events,
boolean loopback);
+
+ protected native int tipc_leave(int sd);
+
+ /**
+ * Messaging: - NULL pointer parameters are always accepted -
tipc_sendto()
+ * to an accepting socket initiates two-way connect - If no err pointer
+ * given, tipc_recvfrom() returns 0 on rejected message - If (*err !=
0) buf
+ * contains a potentially truncated rejected message - Group event:
+ * tipc_recvfrom() returns 0; err == 0/-1 indicates up/down
+ */
+ protected native int tipc_recvfrom(int sd, ByteBuffer buf, int length,
TipcAddr socket, TipcAddr member,
+ java.lang.Integer err);
+
+ protected native int tipc_recv(int sd, ByteBuffer buf, int length,
boolean waitall);
+
+ protected native int tipc_sendmsg(int sd, ByteBuffer msg, int length);
+
+ protected native int tipc_sendto(int sd, ByteBuffer msg, int length,
TipcAddr dst);
+
+ protected native int tipc_send(int sd, ByteBuffer msg, int length);
+
+ protected native int tipc_mcast(int sd, ByteBuffer msg, int length,
TipcAddr dst);
+
+ /** Topology Server:
+ * - Expiration time in [ms]
+ * - If (expire < 0) subscription never expires
+ */
+ protected native int tipc_topsrv_conn(long topsrv_node);
+ protected native int tipc_srv_subscr(int sd, long type, long lower,
long upper, boolean all, int expire);
+ protected native int tipc_srv_evt(int sd, TipcAddr srv, TipcAddr addr,
java.lang.Integer up, java.lang.Integer expired);
+ protected native boolean tipc_srv_wait(TipcAddr srv, int expire);
+
+ /**
+ * C poll API wrapper
+ */
+ protected native int tipc_poll(int fd, short events, java.lang.Integer
revents, int timeout);
+ protected native int tipc_pollset(int[] fds, short[] events,
java.lang.Integer[] revents, int timeout);
+
+ static {
+
+ String libSysPath = System.getProperty("java.library.path");
+ libSysPath += System.getProperty("user.dir") +
File.pathSeparator + ".libs";
+ System.setProperty("java.library.path", libSysPath);
+
+ try {
+ /**
+ * Work-around to make sure java.library.path updated
at runtime
+ */
+ Field fieldSysPath =
ClassLoader.class.getDeclaredField("sys_paths");
+ fieldSysPath.setAccessible(true);
+ fieldSysPath.set(null, null);
+ } catch (Exception e) {
+ }
+
+ /**
+ * Load native library in static initializer of class
+ */
+ try {
+ System.loadLibrary("tipcj");
+ } catch (UnsatisfiedLinkError e) {
+ System.out.println("Specific -Djava.library.path where
libtipcj.so is located");
+ }
+ }
+
+ /**
+ *
+ */
+ private static final TipcBaseApi instance = new TipcBaseApi();
+
+ /**
+ *
+ */
+ public static int OwnNode = 0;
+
+ /**
+ * Non expose this class
+ */
+ private TipcBaseApi() {}
+
+ /**
+ *
+ * @return
+ */
+ protected static TipcBaseApi getInstance() {
+ return instance;
+ }
+}
diff --git a/tipcj/com/tipcj/TipcConfig.java b/tipcj/com/tipcj/TipcConfig.java
new file mode 100644
index 000000000000..41809a9bb649
--- /dev/null
+++ b/tipcj/com/tipcj/TipcConfig.java
@@ -0,0 +1,49 @@
+package com.tipcj;
+
+public interface TipcConfig {
+ public static final int TIPC_WAIT_FOREVER = ~0; /* timeout for
permanent subscription */
+
+ /**
+ * Application-accessible service types
+ */
+ public static final int TIPC_NODE_STATE = 0; /* node state service
type */
+ public static final int TIPC_TOP_SRV = 1; /* topology server
service type */
+ public static final int TIPC_LINK_STATE = 2; /* link state service
type */
+ public static final int TIPC_RESERVED_TYPES = 64; /* lowest
user-allowed service type */
+
+ /**
+ * Publication scopes when binding service / service range
+ */
+ public static final int TIPC_CLUSTER_SCOPE = 2; /* 0 can also be used
*/
+ public static final int TIPC_NODE_SCOPE = 3;
+
+ /**
+ * Limiting values for messages
+ */
+ public static final int TIPC_MAX_USER_MSG_SIZE = 66000;
+
+ /**
+ * Message importance levels
+ */
+ public static final int TIPC_LOW_IMPORTANCE = 0;
+ public static final int TIPC_MEDIUM_IMPORTANCE = 1;
+ public static final int TIPC_HIGH_IMPORTANCE = 2;
+ public static final int TIPC_CRITICAL_IMPORTANCE = 3;
+
+ /**
+ * Msg rejection/connection shutdown reasons
+ */
+ public static final int TIPC_OK = 0;
+ public static final int TIPC_ERR_NO_NAME = 1;
+ public static final int TIPC_ERR_NO_PORT = 2;
+ public static final int TIPC_ERR_NO_NODE = 3;
+ public static final int TIPC_ERR_OVERLOAD = 4;
+ public static final int TIPC_CONN_SHUTDOWN = 5;
+
+ /**
+ * TIPC topology subscription service definitions
+ */
+ public static final int TIPC_SUB_PORTS = 0x01; /* filter: evt
at each match */
+ public static final int TIPC_SUB_SERVICE = 0x02; /* filter: evt
at first up/last down */
+ public static final int TIPC_SUB_CANCEL = 0x04; /* filter:
cancel a subscription */
+}
diff --git a/tipcj/com/tipcj/TipcConn.java b/tipcj/com/tipcj/TipcConn.java
new file mode 100644
index 000000000000..7def31fa1b21
--- /dev/null
+++ b/tipcj/com/tipcj/TipcConn.java
@@ -0,0 +1,320 @@
+/**
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2018, Ericsson Canada
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of Ericsson Canada nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Version 0.1: Jon Maloy, 2018
+ *
+ * ------------------------------------------------------------------------
+ */
+package com.tipcj;
+
+import java.nio.BufferOverflowException;
+/**
+ * @author Hoang Le ([email protected])
+ *
+ */
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+
+public class TipcConn {
+
+ /**
+ * JNI instance
+ */
+ static {
+ tipcj = TipcBaseApi.getInstance();
+ }
+
+ public TipcConn(ByteBuffer buffer, SocketType sk_type) {
+ poolBuffer = buffer;
+ this.Fd = Socket(sk_type);
+ if (this.Fd > 0) {
+ this.isOpen = true;
+ }
+ }
+
+ public TipcConn(SocketType sk_type) {
+ this.Fd = Socket(sk_type);
+ if (this.Fd > 0) {
+ this.isOpen = true;
+ }
+ /*
+ * initialize default byte buffer
+ */
+ poolBuffer =
ByteBuffer.allocateDirect(TipcConfig.TIPC_MAX_USER_MSG_SIZE);
+ }
+
+ /**
+ * Create AF_TIPC socket API
+ */
+ public int Socket(SocketType sk_type) {
+ return tipcj.tipc_socket(sk_type.val);
+ }
+
+ public int GetFd() {
+ return this.Fd;
+ }
+
+ /**
+ * Bind a TIPC socket to service address/socket address
+ */
+ public int Bind(int stype, int lower, int upper, int scope) {
+ return tipcj.tipc_bind(Fd, stype, lower, upper, scope);
+ }
+
+ /**
+ * Unbind a bound address
+ */
+ public int Unbind(int stype, int lower, int upper) {
+ return tipcj.tipc_unbind(Fd, stype, lower, upper);
+ }
+
+ /**
+ * Close a TIPC socket
+ */
+ public int Close() {
+ return tipcj.tipc_close(Fd);
+ }
+
+ /**
+ * Get a bound socket information
+ */
+ public int Sockaddr(TipcAddr tipcAddr) {
+ return tipcj.tipc_sockaddr(Fd, tipcAddr);
+ }
+
+ public TipcAddr Sockaddr() {
+ TipcAddr tipcAddr = new TipcAddr(0,0,0);
+ int ret = 0;
+
+ ret = tipcj.tipc_sockaddr(Fd, tipcAddr);
+ if (ret == 0) {
+ return tipcAddr;
+ }
+ return null;
+ }
+
+ public int Sock_Non_Block() {
+ return tipcj.tipc_sock_non_block(Fd);
+ }
+
+ /**
+ * Set messages sent from this socket as rejectable
+ */
+ public int Sock_Rejectable() {
+ return tipcj.tipc_sock_rejectable(Fd);
+ }
+
+ public int Connect(TipcAddr dst) {
+ return tipcj.tipc_connect(Fd, dst);
+ }
+
+ public int Listen(int backlog) {
+ return tipcj.tipc_listen(Fd, backlog);
+ }
+
+ public int Accept(TipcAddr src) {
+ int ret = tipcj.tipc_accept(Fd, src);
+ return ret;
+ }
+
+ /**
+ * Group communication API
+ */
+ public int Join(TipcAddr member, boolean events, boolean loopback) {
+ return tipcj.tipc_join(Fd, member, events, loopback);
+ }
+
+ public int Leave() {
+ return tipcj.tipc_leave(Fd);
+ }
+
+ /** Messaging:
+ * - NULL pointer parameters are always accepted
+ * - tipc_sendto() to an accepting socket initiates two-way connect
+ * - If no err pointer given, tipc_recvfrom() returns 0 on rejected
message
+ * - If (*err != 0) buf contains a potentially truncated rejected
message
+ * - Group event: tipc_recvfrom() returns 0; err == 0/-1 indicates
up/down
+ */
+ public int Recvfrom(ByteBuffer buf, int len, TipcAddr socket, TipcAddr
member, java.lang.Integer err) {
+ return tipcj.tipc_recvfrom(Fd, buf, len, socket, member, err);
+ }
+
+ public int Recvfrom(byte[] rbuf, TipcAddr socket, TipcAddr member,
java.lang.Integer err) {
+ int ret = 0;
+ ByteBuffer rbytebuf = ByteBuffer.allocateDirect(rbuf.length);
+ rbytebuf.clear();
+
+ ret = Recvfrom(rbytebuf, rbytebuf.remaining(), socket, member,
err);
+ if (ret > 0) {
+ rbytebuf.get(rbuf, 0, ret);
+ }
+ rbytebuf.clear();
+ return ret;
+ }
+
+ public int Recv(ByteBuffer buf, int len, boolean waitall) {
+ return tipcj.tipc_recv(Fd, buf, len, waitall);
+ }
+
+ public int Recv(byte[] rbuf, boolean waitall) {
+ int ret = 0;
+ int len = rbuf.length;
+ ByteBuffer rbytebuf = ByteBuffer.allocateDirect(len);
+ rbytebuf.clear();
+
+ ret = tipcj.tipc_recv(Fd, rbytebuf, len, waitall);
+ if (ret > 0) {
+ rbytebuf.get(rbuf, 0, ret);
+ }
+ rbytebuf.clear();
+ return ret;
+ }
+
+ public static int Recv(int sd, byte[] rbuf, boolean waitall) {
+ int ret = 0;
+ int len = rbuf.length;
+ ByteBuffer rbytebuf = ByteBuffer.allocateDirect(len);
+ rbytebuf.clear();
+
+ ret = tipcj.tipc_recv(sd, rbytebuf, len, waitall);
+ if (ret > 0) {
+ rbytebuf.get(rbuf, 0, ret);
+ }
+ rbytebuf.clear();
+ return ret;
+ }
+
+ public int Sendmsg(byte[] msg) {
+ int len = msg.length;
+ poolBuffer.clear();
+
+ if (len > poolBuffer.remaining()) {
+ len = poolBuffer.remaining();
+ }
+
+ try {
+ poolBuffer.put(msg, 0, len);
+ } catch (BufferOverflowException ex) {
+ return -1;
+ } catch (ReadOnlyBufferException ex) {
+ return -1;
+ }
+
+ return tipcj.tipc_send(Fd, poolBuffer, len);
+ }
+
+ public int Sendto(byte[] msg, TipcAddr dst) {
+ int len = msg.length;
+ poolBuffer.clear();
+
+ if (len > poolBuffer.remaining()) {
+ len = poolBuffer.remaining();
+ }
+
+ try {
+ poolBuffer.put(msg, 0, len);
+ } catch (BufferOverflowException ex) {
+ return -1;
+ } catch (ReadOnlyBufferException ex) {
+ return -1;
+ }
+
+ return tipcj.tipc_sendto(Fd, poolBuffer, len, dst);
+ }
+
+ public int Sendto(ByteBuffer buf, int len, TipcAddr dst) {
+ return tipcj.tipc_sendto(Fd, buf, len, dst);
+ }
+
+ public int Sendmcast(byte[] msg, TipcAddr dst) {
+ int len = msg.length;
+ poolBuffer.clear();
+
+ if (len > poolBuffer.remaining()) {
+ len = poolBuffer.remaining();
+ }
+
+ try {
+ poolBuffer.put(msg, 0, len);
+ } catch (BufferOverflowException ex) {
+ return -1;
+ } catch (ReadOnlyBufferException ex) {
+ return -1;
+ }
+
+ return tipcj.tipc_mcast(Fd, poolBuffer, len, dst);
+ }
+
+ public int Send(byte[] msg) {
+ int len = msg.length;
+ poolBuffer.clear();
+
+ if (len > poolBuffer.remaining()) {
+ len = poolBuffer.remaining();
+ }
+
+ try {
+ poolBuffer.put(msg, 0, len);
+ } catch (BufferOverflowException ex) {
+ return -1;
+ } catch (ReadOnlyBufferException ex) {
+ return -1;
+ }
+
+ return tipcj.tipc_send(Fd, poolBuffer, len);
+ }
+
+ public static int Send(int sd, byte[] msg) {
+ int len = msg.length;
+ ByteBuffer rbytebuf = ByteBuffer.allocateDirect(len);
+ rbytebuf.clear();
+
+ try {
+ rbytebuf.put(msg, 0, len);
+ } catch (BufferOverflowException ex) {
+ return -1;
+ } catch (ReadOnlyBufferException ex) {
+ return -1;
+ }
+
+ return tipcj.tipc_send(sd, rbytebuf, len);
+ }
+
+ /**
+ * Close a TIPC socket
+ */
+ public static int Close(int fd) {
+ return tipcj.tipc_close(fd);
+ }
+
+ private static TipcBaseApi tipcj;
+ protected int Fd = 0;
+ protected boolean isOpen = false;
+ private ByteBuffer poolBuffer;
+}
diff --git a/tipcj/com/tipcj/TipcHelper.java b/tipcj/com/tipcj/TipcHelper.java
new file mode 100644
index 000000000000..aee70b8254c8
--- /dev/null
+++ b/tipcj/com/tipcj/TipcHelper.java
@@ -0,0 +1,53 @@
+/**
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2018, Ericsson Canada
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of Ericsson Canada nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Version 0.1: Jon Maloy, 2018
+ *
+ * ------------------------------------------------------------------------
+ */
+package com.tipcj;
+
+/**
+ * @author Hoang Le ([email protected])
+ *
+ */
+public class TipcHelper {
+ /**
+ * JNI instance
+ */
+ static {
+ tipcj = TipcBaseApi.getInstance();
+ }
+
+ public static String Linkname(long peer, long bearerid) {
+ return tipcj.tipc_linkname(peer, bearerid);
+ }
+
+ private static TipcBaseApi tipcj;
+}
diff --git a/tipcj/com/tipcj/TipcServiceRange.java
b/tipcj/com/tipcj/TipcServiceRange.java
new file mode 100644
index 000000000000..a10408e4716a
--- /dev/null
+++ b/tipcj/com/tipcj/TipcServiceRange.java
@@ -0,0 +1,65 @@
+/**
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2018, Ericsson Canada
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of Ericsson Canada nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Version 0.1: Jon Maloy, 2018
+ *
+ * ------------------------------------------------------------------------
+ */
+
+package com.tipcj;
+
+/**
+ * @author Hoang Le ([email protected])
+ *
+ */
+public class TipcServiceRange {
+
+ public TipcServiceRange() {
+ Type = 0;
+ Lower = 0;
+ Upper = 0;
+ Node = 0;
+ }
+
+ public TipcServiceRange(long type, long lower, long upper, long scope) {
+ Type = type;
+ Lower = lower;
+ Upper = upper;
+ Node = scope;
+ }
+
+ public long Type = 0;
+ public long Lower = 0;
+ public long Upper = 0;
+ public long Node = 0;
+
+ public String toString() {
+ return String.format("%d:%d:%d@%x", Type, Lower, Upper, Node);
+ }
+}
diff --git a/tipcj/com/tipcj/TipcSrvConn.java b/tipcj/com/tipcj/TipcSrvConn.java
new file mode 100644
index 000000000000..063ea794813a
--- /dev/null
+++ b/tipcj/com/tipcj/TipcSrvConn.java
@@ -0,0 +1,108 @@
+/**
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2018, Ericsson Canada
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of Ericsson Canada nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Version 0.1: Jon Maloy, 2018
+ *
+ * ------------------------------------------------------------------------
+ */
+package com.tipcj;
+
+/**
+ * @author Hoang Le ([email protected])
+ *
+ */
+public class TipcSrvConn {
+ /**
+ * JNI instance
+ */
+ static {
+ tipcj = TipcBaseApi.getInstance();
+ }
+
+ @SuppressWarnings("unused")
+ private TipcSrvConn() {};
+
+ /**
+ * Constructor to connect topology server
+ * @param node
+ */
+ public TipcSrvConn(long node) {
+ this.Fd = SrvConn(node);
+ }
+
+ public TipcSrvConn(long node, ServiceType srvType) {
+ this(node);
+ if (this.Fd <= 0) {
+ return;
+ }
+
+ if (srvType.equals(ServiceType.TIPC_TOP_SRV) ||
srvType.equals(ServiceType.TIPC_LINK_STATE)) {
+ this.filterEvtAll = true;
+ }
+ /**
+ * Subscribe to subscription(s)
+ */
+ this.SrvScr(srvType.val, 0, Integer.MAX_VALUE,
this.filterEvtAll, -1);
+ }
+
+ public int getFd() {
+ return this.Fd;
+ }
+
+ /** Topology Server:
+ * - Expiration time in [ms]
+ * - If (expire < 0) subscription never expires
+ */
+ private int SrvConn(long node) {
+ return tipcj.tipc_topsrv_conn(node);
+ }
+
+ public int SrvScr(long type, long lower, long upper, boolean filterAll,
int expire) {
+ if (this.Fd <=0 ) {
+ return -1;
+ }
+ return tipcj.tipc_srv_subscr(this.Fd, type, lower, upper,
filterAll, expire);
+ }
+
+ public int GetEvt(TipcAddr srv, TipcAddr id, java.lang.Integer up,
java.lang.Integer expired) {
+ return tipcj.tipc_srv_evt(this.Fd, srv, id, up, expired);
+ }
+
+ public static boolean SrvWait(TipcAddr srv, int expire) {
+ return tipcj.tipc_srv_wait(srv, expire);
+ }
+
+ public void Close() {
+ tipcj.tipc_close(this.Fd);
+ }
+
+ private static TipcBaseApi tipcj;
+ protected int Fd = 0;
+ protected boolean filterEvtAll = false;
+}
diff --git a/tipcj/include/tipcjni.h b/tipcj/include/tipcjni.h
new file mode 100644
index 000000000000..9693726aa35b
--- /dev/null
+++ b/tipcj/include/tipcjni.h
@@ -0,0 +1,221 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_tipcj_TipcBaseApi */
+
+#ifndef _Included_com_tipcj_TipcBaseApi
+#define _Included_com_tipcj_TipcBaseApi
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_own_node
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1own_1node
+ (JNIEnv *, jobject);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_linkname
+ * Signature: (JJ)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_tipcj_TipcBaseApi_tipc_1linkname
+ (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_socket
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1socket
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sock_non_block
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sock_1non_1block
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sock_rejectable
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sock_1rejectable
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_close
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1close
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sockaddr
+ * Signature: (ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sockaddr
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_bind
+ * Signature: (IJJJJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1bind
+ (JNIEnv *, jobject, jint, jlong, jlong, jlong, jlong);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_unbind
+ * Signature: (IJJJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1unbind
+ (JNIEnv *, jobject, jint, jlong, jlong, jlong);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_connect
+ * Signature: (ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1connect
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_listen
+ * Signature: (IJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1listen
+ (JNIEnv *, jobject, jint, jlong);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_accept
+ * Signature: (ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1accept
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_join
+ * Signature: (ILcom/tipcj/TipcAddr;ZZ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1join
+ (JNIEnv *, jobject, jint, jobject, jboolean, jboolean);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_leave
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1leave
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_recvfrom
+ * Signature:
(ILjava/nio/ByteBuffer;ILcom/tipcj/TipcAddr;Lcom/tipcj/TipcAddr;Ljava/lang/Integer;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1recvfrom
+ (JNIEnv *, jobject, jint, jobject, jint, jobject, jobject, jobject);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_recv
+ * Signature: (ILjava/nio/ByteBuffer;IZ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1recv
+ (JNIEnv *, jobject, jint, jobject, jint, jboolean);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sendmsg
+ * Signature: (ILjava/nio/ByteBuffer;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sendmsg
+ (JNIEnv *, jobject, jint, jobject, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sendto
+ * Signature: (ILjava/nio/ByteBuffer;ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sendto
+ (JNIEnv *, jobject, jint, jobject, jint, jobject);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_send
+ * Signature: (ILjava/nio/ByteBuffer;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1send
+ (JNIEnv *, jobject, jint, jobject, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_mcast
+ * Signature: (ILjava/nio/ByteBuffer;ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1mcast
+ (JNIEnv *, jobject, jint, jobject, jint, jobject);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_topsrv_conn
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1topsrv_1conn
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_srv_subscr
+ * Signature: (IJJJZI)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1srv_1subscr
+ (JNIEnv *, jobject, jint, jlong, jlong, jlong, jboolean, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_srv_evt
+ * Signature:
(ILcom/tipcj/TipcAddr;Lcom/tipcj/TipcAddr;Ljava/lang/Integer;Ljava/lang/Integer;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1srv_1evt
+ (JNIEnv *, jobject, jint, jobject, jobject, jobject, jobject);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_srv_wait
+ * Signature: (Lcom/tipcj/TipcAddr;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_tipcj_TipcBaseApi_tipc_1srv_1wait
+ (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_poll
+ * Signature: (ISLjava/lang/Integer;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1poll
+ (JNIEnv *, jobject, jint, jshort, jobject, jint);
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_pollset
+ * Signature: ([I[S[Ljava/lang/Integer;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1pollset
+ (JNIEnv *, jobject, jintArray, jshortArray, jobjectArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tipcj/libtipcj.c b/tipcj/libtipcj.c
new file mode 100644
index 000000000000..76d16ac9d9ac
--- /dev/null
+++ b/tipcj/libtipcj.c
@@ -0,0 +1,594 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <error.h>
+#include <poll.h>
+#include <jni.h>
+#include "tipcc.h"
+#include "tipcjni.h"
+
+/*
+ * Caching java classes and method Ids
+ */
+static jclass jclassInt = NULL;
+static jfieldID jclassIntField = NULL;
+static jmethodID jclassIntNewObject = NULL; /* constructor java.lang.Integer */
+
+static jclass jclassTipcAddr = NULL;
+static jfieldID jtipcAddrType = NULL;
+static jfieldID jtipcAddrInstance = NULL;
+static jfieldID jtipcAddrNode = NULL;
+
+/*
+ * Function to convert from C struct tipc_addr to Java TipcAddr instance
+ */
+static void convertTipcAddrToJNI(JNIEnv* env, const struct tipc_addr* addr,
jobject jobjTipcAddr) {
+ if (!jobjTipcAddr || !addr)
+ return;
+
+ (*env)->SetLongField(env, jobjTipcAddr, jtipcAddrType, (jlong)(unsigned
long)addr->type);
+ (*env)->SetLongField(env, jobjTipcAddr, jtipcAddrInstance,
(jlong)(unsigned long)addr->instance);
+ (*env)->SetLongField(env, jobjTipcAddr, jtipcAddrNode, (jlong)(unsigned
long)addr->node);
+}
+
+/*
+ * Function to convert from Java TipcAddr instance to C struct tipc_addr
+ */
+static void convertTipcAddrFromJNI(JNIEnv* env, struct tipc_addr* addr,
jobject jobjTipcAddr) {
+ if (!addr || !jobjTipcAddr)
+ return;
+
+ addr->type = (uint32_t)(*env)->GetLongField(env, jobjTipcAddr,
jtipcAddrType);
+ addr->instance = (uint32_t)(*env)->GetLongField(env, jobjTipcAddr,
jtipcAddrInstance);
+ addr->node = (uint32_t)(*env)->GetLongField(env, jobjTipcAddr,
jtipcAddrNode);
+}
+
+jint throwOutOfMemoryError(JNIEnv *env)
+{
+ jclass localExClass;
+ localExClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+ if (localExClass) {
+ return (*env)->ThrowNew( env, localExClass, "Out Of Memory");
+ }
+ return -1;
+}
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ JNIEnv* env;
+ if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
+ return JNI_ERR;
+ } else {
+ jclass localIntClass = (*env)->FindClass(env,
"java/lang/Integer");
+
+ if (localIntClass) {
+ jclassInt = (*env)->NewGlobalRef(env, localIntClass);
+ /*
+ * Release local ref
+ */
+ (*env)->DeleteLocalRef(env, localIntClass);
+ if (jclassInt == NULL) {
+ return JNI_ERR;
+ }
+ }
+
+ jclassIntField = (*env)->GetFieldID(env, jclassInt, "value",
"I");
+ if (jclassIntField == NULL) {
+ goto releaseGlobalClassInt;
+ }
+
+ jclassIntNewObject = (*env)->GetMethodID(env, jclassInt,
"<init>", "(I)V");
+ if (jclassIntNewObject == NULL) {
+ goto releaseGlobalClassInt;
+ }
+
+ jclass localTipcAddrclass = (*env)->FindClass(env,
"com/tipcj/TipcAddr");
+ if (localTipcAddrclass == NULL) {
+ goto releaseGlobalClassInt;
+ } else {
+ jclassTipcAddr = (*env)->NewGlobalRef(env,
localTipcAddrclass);
+ /*
+ * Release local ref
+ */
+ (*env)->DeleteLocalRef(env, localTipcAddrclass);
+ }
+ jtipcAddrType = (*env)->GetFieldID(env, jclassTipcAddr, "Type",
"J");
+ jtipcAddrInstance = (*env)->GetFieldID(env, jclassTipcAddr,
"Instance", "J");
+ jtipcAddrNode = (*env)->GetFieldID(env, jclassTipcAddr, "Node",
"J");
+ if (!jtipcAddrType || !jtipcAddrInstance || !jtipcAddrNode)
+ goto releaseGlobalClassTipcAddr;
+ }
+
+ return JNI_VERSION_1_6;
+
+releaseGlobalClassTipcAddr:
+ (*env)->DeleteGlobalRef(env, jclassTipcAddr);
+releaseGlobalClassInt:
+ (*env)->DeleteGlobalRef(env, jclassInt);
+ return JNI_ERR;
+}
+
+void JNI_OnUnload(JavaVM *vm, void *reserved) {
+ JNIEnv* env;
+ if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
+ return;
+ } else {
+ (*env)->DeleteGlobalRef(env, jclassInt);
+ (*env)->DeleteGlobalRef(env, jclassTipcAddr);
+ }
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_own_node
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1own_1node
+ (JNIEnv *env, jobject jobj) {
+ return tipc_own_node();
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_linkname
+ * Signature: (JJ)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_tipcj_TipcBaseApi_tipc_1linkname
+ (JNIEnv *env, jobject jobj, jlong peer, jlong bearerid) {
+#define BUF_SZ 40
+ char buf[BUF_SZ] = {0};
+ tipc_linkname(buf, BUF_SZ, peer, bearerid);
+ return (*env)->NewStringUTF(env, buf);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_socket
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1socket
+ (JNIEnv *jenv, jobject jobj, jint sk_type) {
+ int fd;
+ fd = tipc_socket(sk_type);
+ if (fd < 0 ) {
+ printf("Err: [%s]\n", strerror(errno));
+ return 0;
+ }
+ return fd;
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sock_non_block
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sock_1non_1block
+ (JNIEnv *env, jobject obj, jint jfd) {
+ return tipc_sock_non_block(jfd);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sock_rejectable
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sock_1rejectable
+(JNIEnv *env, jobject obj, jint jfd) {
+ return tipc_sock_rejectable(jfd);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_close
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1close
+ (JNIEnv *env, jobject jobj, jint jfd) {
+ return tipc_close(jfd);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sockaddr
+ * Signature: (ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sockaddr
+ (JNIEnv *env, jobject obj, jint jfd, jobject jtipcAddr) {
+ struct tipc_addr addr = {0, 0, 0};
+ int ret = 0;
+
+ ret = tipc_sockaddr(jfd, &addr);
+ if (!ret && jtipcAddr) {
+ convertTipcAddrToJNI(env, &addr, jtipcAddr);
+ }
+
+ return ret;
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_bind
+ * Signature: (IJJJJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1bind
+ (JNIEnv *env, jobject jobj, jint sd, jlong type, jlong lower, jlong upper,
jlong scope) {
+ return tipc_bind(sd, type, lower, upper, scope);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_unbind
+ * Signature: (IJJJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1unbind
+ (JNIEnv *env, jobject jobj, jint sd, jlong type, jlong lower, jlong upper) {
+ return tipc_unbind(sd, type, lower, upper);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_connect
+ * Signature: (ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1connect
+ (JNIEnv *env, jobject jobj, jint sd, jobject jtipcAddr) {
+ struct tipc_addr addr = {0, 0, 0};
+
+ if (jtipcAddr == NULL) {
+ return -1;
+ }
+ convertTipcAddrFromJNI(env, &addr, jtipcAddr);
+ return tipc_connect(sd, &addr);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_listen
+ * Signature: (IJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1listen
+ (JNIEnv *env, jobject jobj, jint sd, jlong backlog) {
+ return tipc_listen(sd, backlog);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_accept
+ * Signature: (ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1accept
+ (JNIEnv *env, jobject obj, jint sd, jobject jtipcAddr) {
+ struct tipc_addr addr = {0, 0, 0};
+ int ret = 0;
+
+ if (jtipcAddr != NULL) {
+ ret = tipc_accept(sd, &addr);
+ if (ret) {
+ convertTipcAddrToJNI(env, &addr, jtipcAddr);
+ }
+ return ret;
+ }
+ return tipc_accept(sd, NULL);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_join
+ * Signature: (ILcom/tipcj/TipcAddr;ZZ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1join
+ (JNIEnv *env, jobject obj, jint sd, jobject jtipcAddr, jboolean jevents,
jboolean jloopback) {
+ struct tipc_addr addr = {0, 0, 0};
+ bool events = 0, loopback = 0;
+
+ if (jevents == JNI_TRUE) {
+ events = 1;
+ }
+
+ if (jloopback == JNI_TRUE) {
+ loopback = 1;
+ }
+
+ if (jtipcAddr != NULL) {
+ convertTipcAddrFromJNI(env, &addr, jtipcAddr);
+ }
+
+ return tipc_join(sd, &addr, events, loopback);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_leave
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1leave
+ (JNIEnv *env, jobject jobj, jint sd) {
+ return tipc_leave(sd);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_recvfrom
+ * Signature:
(ILjava/nio/ByteBuffer;ILcom/tipcj/TipcAddr;Lcom/tipcj/TipcAddr;Ljava/lang/Integer;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1recvfrom
+ (JNIEnv *env, jobject jobj, jint jfd, jobject jbuf, jint len, jobject
jsocket, jobject jmemberid, jobject jerr) {
+
+ struct tipc_addr socket = {0, 0, 0};
+ struct tipc_addr memberid = {0, 0, 0};
+ void *buf = NULL;
+ int err = 0;
+ int ret = 0;
+
+ buf = (void *) (*env)->GetDirectBufferAddress (env, jbuf);
+ if (buf == NULL) {
+ return throwOutOfMemoryError(env);
+ }
+
+ /*
+ * Calling TIPC C Api
+ */
+ ret = tipc_recvfrom(jfd, buf, len, &socket, &memberid, &err);
+ /**
+ * Convert c int to jInteger
+ */
+ (*env)->SetIntField(env, jerr, jclassIntField, err);
+ if (jmemberid != NULL) {
+ convertTipcAddrToJNI(env, &memberid, jmemberid);
+ }
+
+ if (jsocket != NULL) {
+ convertTipcAddrToJNI(env, &socket, jsocket);
+ }
+
+ return ret;
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_recv
+ * Signature: (ILjava/nio/ByteBuffer;IZ)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1recv
+ (JNIEnv *env, jobject jobj, jint jfd, jobject jbuf, jint len, jboolean
jwaitall) {
+ int waitall = 0;
+ void *buf = NULL;
+
+ if (jwaitall == JNI_TRUE)
+ waitall = 1;
+
+ buf = (void *) (*env)->GetDirectBufferAddress (env, jbuf);
+ if (buf == NULL) {
+ return throwOutOfMemoryError(env);
+ }
+
+ return tipc_recv(jfd, buf, len, waitall);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sendmsg
+ * Signature: (ILjava/nio/ByteBuffer;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sendmsg
+ (JNIEnv *env, jobject obj, jint jfd, jobject jbuf, jint len) {
+ void *buf = NULL;
+
+ buf = (void *) (*env)->GetDirectBufferAddress (env, jbuf);
+ if (buf == NULL) {
+ return throwOutOfMemoryError(env);
+ }
+
+ return tipc_send(jfd, buf, len);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_sendto
+ * Signature: (ILjava/nio/ByteBuffer;ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1sendto
+ (JNIEnv *env, jobject jobj, jint jfd, jobject jbuf, jint len, jobject
jtipcAddr) {
+ struct tipc_addr dst = {0,0,0};
+ void *buf = NULL;
+ int ret = 0;
+
+ buf = (void *) (*env)->GetDirectBufferAddress (env, jbuf);
+ if (buf == NULL || jtipcAddr == NULL) {
+ return throwOutOfMemoryError(env);
+ }
+ convertTipcAddrFromJNI(env, &dst, jtipcAddr);
+ /*
+ * Calling TIPC C Api
+ */
+ ret = tipc_sendto(jfd, buf, len, &dst);
+
+ return ret;
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_send
+ * Signature: (ILjava/nio/ByteBuffer;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1send
+ (JNIEnv *env, jobject jobj, jint jfd, jobject jbuf, jint len) {
+ /**
+ * TODO
+ */
+ return Java_com_tipcj_TipcBaseApi_tipc_1sendmsg(env, jobj, jfd, jbuf,
len);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_mcast
+ * Signature: (ILjava/nio/ByteBuffer;ILcom/tipcj/TipcAddr;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1mcast
+ (JNIEnv *env, jobject obj, jint sd, jobject jbuf, jint len, jobject
jtipcAddr) {
+ struct tipc_addr dst = {0,0,0};
+ void *buf = NULL;
+
+ buf = (void *) (*env)->GetDirectBufferAddress (env, jbuf);
+ if (buf == NULL || jtipcAddr == NULL) {
+ return throwOutOfMemoryError(env);
+ }
+ convertTipcAddrFromJNI(env, &dst, jtipcAddr);
+ return tipc_mcast(sd, buf, len, &dst);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_topsrv_conn
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1topsrv_1conn
+ (JNIEnv *env, jobject obj, jlong node) {
+ return tipc_topsrv_conn((uint32_t)node);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_srv_subscr
+ * Signature: (IJJJZI)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1srv_1subscr
+ (JNIEnv *env, jobject obj, jint sd, jlong type, jlong lower, jlong upper,
jboolean jall, jint expire) {
+ bool all = false;
+
+ if (jall == JNI_TRUE) {
+ all = true;
+ }
+ return tipc_srv_subscr(sd, (uint32_t)type, (uint32_t)lower,
(uint32_t)upper, all, expire);
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_srv_evt
+ * Signature:
(ILcom/tipcj/TipcAddr;Lcom/tipcj/TipcAddr;Ljava/lang/Integer;Ljava/lang/Integer;)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1srv_1evt
+ (JNIEnv *env, jobject obj, jint sd, jobject jsrv, jobject jid, jobject
javailable, jobject jexpired) {
+ struct tipc_addr srv = {0, 0, 0}, id = {0, 0, 0};
+ int ret = 0;
+ bool available = false, expired = false;
+
+ ret = tipc_srv_evt(sd, &srv, &id, &available, &expired);
+ if (!ret && !expired) {
+ if (jsrv != NULL) {
+ convertTipcAddrToJNI(env, &srv, jsrv);
+ }
+
+ if (jid != NULL) {
+ convertTipcAddrToJNI(env, &id, jid);
+ }
+ }
+
+ if (javailable) {
+ (*env)->SetIntField(env, javailable, jclassIntField, available);
+ }
+ if (jexpired) {
+ (*env)->SetIntField(env, jexpired, jclassIntField, expired);
+ }
+
+ return ret;
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_srv_wait
+ * Signature: (Lcom/tipcj/TipcAddr;I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_tipcj_TipcBaseApi_tipc_1srv_1wait
+ (JNIEnv *env, jobject jobj, jobject jtipcAddr, jint wait) {
+ struct tipc_addr srv = {0,0,0};
+ int up = 0;
+
+ convertTipcAddrFromJNI(env, &srv, jtipcAddr);
+ up = tipc_srv_wait(&srv, wait);
+ if (up)
+ return JNI_TRUE;
+
+ return JNI_FALSE;
+}
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_poll
+ * Signature: (ISLjava/lang/Integer;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1poll
+ (JNIEnv *env, jobject obj, jint jfd, jshort events, jobject revents, jint
timeout) {
+ struct pollfd pfd;
+ int ret = 0;
+
+ pfd.fd = jfd;
+ pfd.events = events;
+
+ ret = poll(&pfd, 1, timeout);
+ if (ret && revents) {
+ (*env)->SetIntField(env, revents, jclassIntField, pfd.revents);
+ }
+ return ret;
+}
+
+/*
+ * Class: com_tipcj_TipcBaseApi
+ * Method: tipc_pollset
+ * Signature: ([I[S[Ljava/lang/Integer;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_tipcj_TipcBaseApi_tipc_1pollset
+ (JNIEnv *env, jobject obj, jintArray jfds, jshortArray jevents, jobjectArray
revents, jint timeout) {
+ jsize lenFds = (*env)->GetArrayLength(env, jfds);
+ jsize lenEvtArr = (*env)->GetArrayLength(env, jevents);
+ struct pollfd *pfd = NULL;
+ int ret = 0;
+ int i = 0;
+ jint *jintArr = (*env)->GetIntArrayElements(env, jfds, 0);
+ jshort *jshortArr = (*env)->GetShortArrayElements(env, jevents, 0);
+
+ // Validate parameters
+ if (lenEvtArr != lenFds) {
+ goto releaseArr;
+ }
+
+ if (jintArr && jshortArr && lenFds >= 1) {
+ pfd = malloc(lenFds * sizeof(struct pollfd));
+ if (pfd == NULL) {
+ goto releaseArr;
+ }
+ memset(pfd, 0, lenFds * sizeof(struct pollfd));
+ }
+
+ for (i = 0; i<lenFds; i++) {
+ pfd[i].fd = jintArr[i];
+ pfd[i].events = jshortArr[i];
+ pfd[i].revents = 0;
+ }
+
+ ret = poll(pfd, lenFds, timeout);
+ for (i = 0; i<lenFds; i++) {
+ // return revents from pfd revents
+ jobject obj = (*env)->GetObjectArrayElement(env, revents, i);
+ if (obj == NULL) {
+ obj = (*env)->NewObject(env, jclassInt,
jclassIntNewObject, pfd[i].revents);
+ if (obj != NULL) {
+ (*env)->SetObjectArrayElement(env, revents, i,
obj);
+ }
+ } else {
+ (*env)->SetIntField(env, obj, jclassIntField,
pfd[i].revents);
+ }
+ }
+ free(pfd);
+
+releaseArr:
+ (*env)->ReleaseIntArrayElements(env, jfds, jintArr, 0);
+ (*env)->ReleaseShortArrayElements(env, jevents, jshortArr, 0);
+
+ return ret;
+}
--
2.7.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
tipc-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tipc-discussion