Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

* Implemented Java bindings for libservalctrl

* Created Android app for installing and running kernel module
  • Loading branch information...
commit 805083c441539562c145b3f29f139d9b9907a8a3 1 parent 0edf851
@erimatnor erimatnor authored
Showing with 1,581 additions and 115 deletions.
  1. +2 −1  .gitignore
  2. +0 −4 android/Application.mk
  3. +16 −17 android/README
  4. +8 −0 android/Serval/.classpath
  5. +33 −0 android/Serval/.project
  6. +17 −0 android/Serval/AndroidManifest.xml
  7. +17 −0 android/Serval/ant.properties
  8. 0  android/Serval/assets/.gitignore
  9. +85 −0 android/Serval/build.xml
  10. +1 −1  android/{ → Serval/jni}/Android.mk
  11. +3 −0  android/Serval/jni/Application.mk
  12. +10 −0 android/Serval/local.properties
  13. +40 −0 android/Serval/proguard.cfg
  14. +11 −0 android/Serval/project.properties
  15. +179 −0 android/Serval/src/org/servalarch/serval/ServalActivity.java
  16. +1 −1  android/ServalChat/.classpath
  17. +2 −2 android/ServalChat/AndroidManifest.xml
  18. +11 −0 android/ServalChat/project.properties
  19. +5 −4 android/ServalChat/src/{edu/princeton/cs/sns → org/servalarch}/ServalChat/ChatActivity.java
  20. +3 −0  configure.ac
  21. +2 −0  include/libservalctrl/hostctrl.h
  22. +4 −2 include/libservalctrl/message_channel.h
  23. +3 −0  m4/ac_jni_include_dir.m4
  24. +2 −2 src/Makefile.am
  25. +1 −1  src/javasock/Makefile.am
  26. +2 −2 src/javasock/Manifest.txt
  27. +1 −1  src/javasock/README
  28. +23 −23 src/javasock/java/Makefile.am
  29. +1 −1  src/javasock/java/{serval → org/servalarch}/net/ServalDatagramPacket.java
  30. +4 −4 src/javasock/java/{serval → org/servalarch}/net/ServalDatagramSocket.java
  31. +2 −2 src/javasock/java/{serval → org/servalarch}/net/ServalDatagramSocketImpl.java
  32. +1 −1  src/javasock/java/{serval → org/servalarch}/net/ServalDatagramSocketImplFactory.java
  33. +1 −2  src/javasock/java/{serval → org/servalarch}/net/ServalPlainServerSocketImpl.java
  34. +2 −3 src/javasock/java/{serval → org/servalarch}/net/ServalPlainSocketImpl.java
  35. +1 −1  src/javasock/java/{serval → org/servalarch}/net/ServalServerDatagramSocket.java
  36. +1 −2  src/javasock/java/{serval → org/servalarch}/net/ServalServerSocket.java
  37. +2 −3 src/javasock/java/{serval → org/servalarch}/net/ServalSocket.java
  38. +1 −1  src/javasock/java/{serval → org/servalarch}/net/ServalSocketAddress.java
  39. +2 −4 src/javasock/java/{serval → org/servalarch}/net/ServalSocketImpl.java
  40. +1 −2  src/javasock/java/{serval → org/servalarch}/net/ServalSocketImplFactory.java
  41. +1 −1  src/javasock/java/{serval → org/servalarch}/net/ServalSocketInputStream.java
  42. +1 −1  src/javasock/java/{serval → org/servalarch}/net/ServalSocketOutputStream.java
  43. +14 −2 src/javasock/java/{serval → org/servalarch}/net/ServiceID.java
  44. +5 −5 src/javasock/java/{serval → org/servalarch}/platform/ServalNetworkStack.java
  45. +4 −2 src/javasock/java/{serval → org/servalarch}/test/TCPClient.java
  46. +5 −2 src/javasock/java/{serval → org/servalarch}/test/TCPServer.java
  47. +6 −2 src/javasock/java/{serval → org/servalarch}/test/UDPClient.java
  48. +7 −2 src/javasock/java/{serval → org/servalarch}/test/UDPServer.java
  49. +4 −0 src/libservalctrl/Makefile.am
  50. +31 −9 src/libservalctrl/hostctrl.c
  51. +11 −0 src/libservalctrl/java/.classpath
  52. +17 −0 src/libservalctrl/java/.project
  53. +29 −0 src/libservalctrl/java/Makefile.am
  54. +7 −0 src/libservalctrl/java/Manifest.txt
  55. 0  src/libservalctrl/java/bin/.gitignore
  56. +24 −0 src/libservalctrl/java/jni/Makefile.am
  57. +594 −0 src/libservalctrl/java/jni/org_servalarch_servalctrl_HostCtrl.c
  58. +89 −0 src/libservalctrl/java/jni/org_servalarch_servalctrl_HostCtrl.h
  59. +19 −0 src/libservalctrl/java/jni/org_servalarch_servalctrl_HostCtrl_HostCtrlException.h
  60. +18 −0 src/libservalctrl/java/src/Makefile.am
  61. +89 −0 src/libservalctrl/java/src/org/servalarch/servalctrl/HostCtrl.java
  62. +14 −0 src/libservalctrl/java/src/org/servalarch/servalctrl/HostCtrlCallbacks.java
  63. +7 −0 src/libservalctrl/java/src/org/servalarch/servalctrl/LocalHostCtrl.java
  64. +7 −0 src/libservalctrl/java/src/org/servalarch/servalctrl/RemoteHostCtrl.java
  65. +54 −0 src/libservalctrl/java/src/org/servalarch/servalctrl/TestApp.java
  66. +2 −0  src/libservalctrl/message_channel.c
  67. +3 −0  src/libservalctrl/message_channel_base.c
  68. +14 −0 src/libservalctrl/message_channel_internal.c
  69. +2 −0  src/libservalctrl/message_channel_internal.h
  70. +1 −1  src/servd/Android.mk
  71. +1 −1  src/stack/Makefile.am
View
3  .gitignore
@@ -56,6 +56,8 @@ src/tools/migrate
src/javasock/classes.list
src/javasock/sources.list
src/javasock/bin/
+src/libservalctrl/java/classes.list
+src/libservalctrl/java/sources.list
android/ServalChat/bin/
android/ServalChat/gen/
stamp-h1
@@ -79,4 +81,3 @@ Makefile
*.stamp
*.jar
.DS_Store
-.project
View
4 android/Application.mk
@@ -1,4 +0,0 @@
-APP_PROJECT_PATH := $(PWD)
-APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/android/Android.mk
-APP_PLATFORM := android-8
-APP_ABI := armeabi armeabi-v7a
View
33 android/README
@@ -14,6 +14,7 @@ Prerequisites:
(r5b is known to work).
* Root access on your Android device.
* Android debug bridge - adb (from, e.g., the Android SDK).
+* Ant or Eclipse
Getting the right kernel source
-------------------------------
@@ -91,17 +92,6 @@ After overriding, re-run the prepare step.
Your kernel source tree is now ready.
-Compiling user-level binaries and libraries
--------------------------------------------
-
-In the top-level directory:
-
-$ ln -s android jni
-
-$ <Path to NDK>/ndk-build
-
-The libraries and binaries can now be found under "libs".
-
Compiling the Kernel module
---------------------------
@@ -111,17 +101,26 @@ Enter src/stack and issue the following command:
> ARCH=arm CROSS_COMPILE=arm-eabi- make serval.ko KDIR=<Path to kernel source>
-Installation
-------------
+Compiling user-level binaries and libraries
+-------------------------------------------
+
+$ cd android/Serval
+$ <Path to NDK>/ndk-build
+
+The libraries and binaries can now be found under "libs".
+
+Copy the kernel module from the previous step to the
+android/Serval/assets directory.
-Run the 'install.sh' script in this directory.
+Build the Serval Android app with Eclipse or with Ant:
-This installs binaries and the kernel module under /data/local/serval.
+$ cd android/Serval
+$ ant debug
-Loading the kernel module
+Manually Loading the kernel module
-------------------------
Run this command through "adb":
-$ adb shell su -c 'insmod /data/local/serval/serval.ko'
+$ adb shell su -c 'insmod /path/to/kernel/module/on/device/serval.ko'
View
8 android/Serval/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+ <classpathentry kind="output" path="bin/classes"/>
+</classpath>
View
33 android/Serval/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>Serval</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
17 android/Serval/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.servalarch.serval"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <uses-sdk android:minSdkVersion="8" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
+ <application android:label="@string/app_name" >
+ <activity android:name="ServalActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
View
17 android/Serval/ant.properties
@@ -0,0 +1,17 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked in Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
View
0  android/Serval/assets/.gitignore
No changes.
View
85 android/Serval/build.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Serval" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
+ unless="sdk.dir"
+ />
+
+
+<!-- extension targets. Uncomment the ones where you want to do custom work
+ in between standard targets -->
+<!--
+ <target name="-pre-build">
+ </target>
+ <target name="-pre-compile">
+ </target>
+
+ /* This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir} */
+ <target name="-post-compile">
+ </target>
+-->
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
View
2  android/Android.mk → android/Serval/jni/Android.mk
@@ -1,7 +1,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-subdirs := $(addprefix $(LOCAL_PATH)/../,$(addsuffix /Android.mk, \
+subdirs := $(addprefix $(LOCAL_PATH)/../../../,$(addsuffix /Android.mk, \
src/common \
src/libservalctrl \
src/servd \
View
3  android/Serval/jni/Application.mk
@@ -0,0 +1,3 @@
+APP_PROJECT_PATH := $(call my-dir)/../
+APP_PLATFORM := android-8
+APP_ABI := armeabi armeabi-v7a
View
10 android/Serval/local.properties
@@ -0,0 +1,10 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must *NOT* be checked in Version Control Systems,
+# as it contains information specific to your local configuration.
+
+# location of the SDK. This is only used by Ant
+# For customization when using a Version Control System, please read the
+# header note.
+sdk.dir=/Users/enordstr/Projects/android/sdk
View
40 android/Serval/proguard.cfg
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
View
11 android/Serval/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-10
View
179 android/Serval/src/org/servalarch/serval/ServalActivity.java
@@ -0,0 +1,179 @@
+package org.servalarch.serval;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import org.servalarch.serval.R;
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.CompoundButton;
+import android.widget.Toast;
+import android.widget.ToggleButton;
+
+public class ServalActivity extends Activity
+{
+ private ToggleButton moduleStatusButton;
+ private File module = null;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ File filesDir = getExternalFilesDir(null);
+ try {
+ filesDir.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ module = new File(filesDir, "serval.ko");
+ this.moduleStatusButton = (ToggleButton) findViewById(R.id.moduleStatusToggle);
+ this.moduleStatusButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView,
+ boolean isChecked) {
+ boolean isLoaded = isServalModuleLoaded();
+ String cmd;
+
+ if (isChecked) {
+ if (isLoaded)
+ return;
+
+ cmd = "insmod " + module.getAbsolutePath();
+ } else {
+ if (!isLoaded)
+ return;
+ cmd = "rmmod serval";
+ }
+
+ if (!executeSuCommand(cmd)) {
+ Toast t = Toast.makeText(getApplicationContext(), cmd + " failed!",
+ Toast.LENGTH_SHORT);
+ t.show();
+ }
+
+ if (!isServalModuleLoaded() && isChecked)
+ moduleStatusButton.setChecked(false);
+ else if (isServalModuleLoaded() && !isChecked)
+ moduleStatusButton.setChecked(true);
+ }
+ });
+ }
+
+ private boolean extractKernelModule(File module) {
+ if (module.exists())
+ return true;
+
+ try {
+ BufferedInputStream in = new BufferedInputStream(getAssets().open("serval.ko"));
+
+ byte[] buffer = new byte[1024];
+ int n, tot = 0;
+
+ FileOutputStream os = new FileOutputStream(module);
+ BufferedOutputStream out = new BufferedOutputStream(os);
+
+ while ((n = in.read(buffer, 0, 1024)) != -1) {
+ out.write(buffer, 0, n);
+ tot += n;
+ }
+ out.close();
+ in.close();
+
+ Log.d("Serval", "Wrote " + tot + " bytes to " + module.getAbsolutePath());
+ return true;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ private boolean executeSuCommand(String cmd) {
+ try {
+ Process shell;
+ int err;
+
+ shell = Runtime.getRuntime().exec("su");
+ DataOutputStream os = new DataOutputStream(shell.getOutputStream());
+ os.writeBytes(cmd + "\n");
+ os.flush();
+ os.writeBytes("exit\n");
+ os.flush();
+ os.close();
+
+ err = shell.waitFor();
+
+ if (err == 0)
+ return true;
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ Log.d("Serval", cmd + " failed!");
+
+ return false;
+ }
+
+ private boolean isServalModuleLoaded() {
+ boolean moduleIsLoaded = false;
+
+ File procModules = new File("/proc/modules");
+
+ if (procModules.exists() && procModules.canRead()) {
+ try {
+ BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(procModules)));
+
+ String line = in.readLine();
+
+ if (line.contains("serval")) {
+ moduleIsLoaded = true;
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ Log.d("Serval", "could not open /proc/modules");
+ }
+ return moduleIsLoaded;
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ }
+ @Override
+ protected void onStart() {
+ super.onStart();
+
+ Log.d("Serval", "module path is " + module.getAbsolutePath());
+
+ if (!extractKernelModule(module)) {
+ Log.d("Serval", "Could not extract kernel module");
+ }
+
+ if (isServalModuleLoaded())
+ moduleStatusButton.setChecked(true);
+ else
+ moduleStatusButton.setChecked(false);
+ }
+ @Override
+ protected void onStop() {
+ super.onStop();
+ }
+
+}
View
2  android/ServalChat/.classpath
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
- <classpathentry kind="lib" path="/Users/enordstr/Projects/serval/src/javasock/serval-javasock.jar"/>
+ <classpathentry kind="lib" path="../../src/javasock/org.servalarch.javasock.jar"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
View
4 android/ServalChat/AndroidManifest.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="edu.princeton.cs.sns.ServalChat"
+ package="org.servalarch.ServalChat"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".ChatActivity"
+ <activity android:name="org.servalarch.ServalChat.ChatActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
View
11 android/ServalChat/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-7
View
9 ...edu/princeton/cs/sns/ServalChat/ChatActivity.java → ...t/src/org/servalarch/ServalChat/ChatActivity.java
@@ -1,5 +1,5 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package edu.princeton.cs.sns.ServalChat;
+package org.servalarch.ServalChat;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@@ -9,9 +9,10 @@
import java.io.OutputStreamWriter;
import java.net.SocketTimeoutException;
-import edu.princeton.cs.sns.ServalChat.R;
-import serval.net.ServalSocket;
-import serval.net.ServiceID;
+import org.servalarch.ServalChat.R;
+import org.servalarch.net.ServalSocket;
+import org.servalarch.net.ServiceID;
+
import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
View
3  configure.ac
@@ -240,6 +240,9 @@ AC_CONFIG_FILES([Makefile
src/stack/Makefile
src/stack/Kbuild
src/libservalctrl/Makefile
+ src/libservalctrl/java/Makefile
+ src/libservalctrl/java/jni/Makefile
+ src/libservalctrl/java/src/Makefile
src/libserval/Makefile
src/servd/Makefile
src/translator/Makefile
View
2  include/libservalctrl/hostctrl.h
@@ -12,6 +12,8 @@ struct hostctrl;
Host control callbacks.
*/
struct hostctrl_callback {
+ int (*start)(struct hostctrl *hc); /* Called one time, when thread starts */
+ void (*stop)(struct hostctrl *hc); /* Called when thread stops */
int (*service_registration)(struct hostctrl *hc,
const struct service_id *srvid,
unsigned short flags,
View
6 include/libservalctrl/message_channel.h
@@ -19,8 +19,10 @@
typedef struct message_channel_callback {
void *target;
- int (*recv) (struct message_channel_callback *cb,
- message_t *msg);
+ int (*start)(struct message_channel_callback *cb);
+ void (*stop)(struct message_channel_callback *cb);
+ int (*recv)(struct message_channel_callback *cb,
+ message_t *msg);
} message_channel_callback_t;
struct message_channel_ops;
View
3  m4/ac_jni_include_dir.m4
@@ -52,8 +52,11 @@ case "$host_os" in
*) _JINC="$_JTOPDIR/include";;
esac
+AC_MSG_NOTICE(Looking for JNI headers in: $_JINC)
+
if test -f "$_JINC/jni.h"; then
JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JINC"
+ have_jni=yes
else
_JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'`
if test -f "$_JTOPDIR/include/jni.h"; then
View
4 src/Makefile.am
@@ -1,14 +1,14 @@
SUBDIRS = \
common \
stack \
- libserval \
- libservalctrl
+ libserval
if ENABLE_JAVA_BINDINGS
SUBDIRS += javasock
endif
SUBDIRS += \
+ libservalctrl \
test \
servd \
translator \
View
2  src/javasock/Makefile.am
@@ -1,5 +1,5 @@
SUBDIRS = java jni
-JARFILE = serval-javasock.jar
+JARFILE = org.servalarch.javasock.jar
MANIFEST = Manifest.txt
javasock_DATA = $(JARFILE)
javasockdir = $(datadir)/java
View
4 src/javasock/Manifest.txt
@@ -1,8 +1,8 @@
-Name: edu/princeton/cs/sns/serval/
+Name: org/servalarch/javasock
Specification-Title: Java JNI classes for Serval
Specification-Version: 1.0
Specification-Vendor: sns.cs.princeton.edu
-Implementation-Title: serval-javasock
+Implementation-Title: org.servalarch.javasock
Implementation-Version: 1.0
Implementation-Vendor: Princeton University
View
2  src/javasock/README
@@ -3,4 +3,4 @@ Serval Java bindings
Example of how to run a test application (from this directory):
-LD_LIBRARY_PATH=$PWD/jni/.libs/ java -classpath $PWD/serval-javasock.jar serval.test.TCPServer
+java -Djava.library.path==$PWD/jni/.libs/ -classpath $PWD/org.servalarch.javasock.jar serval.test.TCPServer
View
46 src/javasock/java/Makefile.am
@@ -1,26 +1,26 @@
# Do not install compiled class files. We instead generate and install
# a jar file with the class files in a subdirectory
noinst_JAVA = \
- serval/net/ServiceID.java \
- serval/net/ServalSocketAddress.java \
- serval/platform/ServalNetworkStack.java \
- serval/net/ServalDatagramPacket.java \
- serval/net/ServalDatagramSocket.java \
- serval/net/ServalDatagramSocketImpl.java \
- serval/net/ServalDatagramSocketImplFactory.java \
- serval/net/ServalServerDatagramSocket.java \
- serval/net/ServalSocketImplFactory.java \
- serval/net/ServalSocketOutputStream.java \
- serval/net/ServalSocketImpl.java \
- serval/net/ServalPlainSocketImpl.java \
- serval/net/ServalSocketInputStream.java \
- serval/net/ServalSocket.java \
- serval/net/ServalServerSocket.java \
- serval/net/ServalPlainServerSocketImpl.java \
- serval/test/TCPServer.java \
- serval/test/TCPClient.java \
- serval/test/UDPServer.java \
- serval/test/UDPClient.java
+ org/servalarch/net/ServiceID.java \
+ org/servalarch/net/ServalSocketAddress.java \
+ org/servalarch/platform/ServalNetworkStack.java \
+ org/servalarch/net/ServalDatagramPacket.java \
+ org/servalarch/net/ServalDatagramSocket.java \
+ org/servalarch/net/ServalDatagramSocketImpl.java \
+ org/servalarch/net/ServalDatagramSocketImplFactory.java \
+ org/servalarch/net/ServalServerDatagramSocket.java \
+ org/servalarch/net/ServalSocketImplFactory.java \
+ org/servalarch/net/ServalSocketOutputStream.java \
+ org/servalarch/net/ServalSocketImpl.java \
+ org/servalarch/net/ServalPlainSocketImpl.java \
+ org/servalarch/net/ServalSocketInputStream.java \
+ org/servalarch/net/ServalSocket.java \
+ org/servalarch/net/ServalServerSocket.java \
+ org/servalarch/net/ServalPlainServerSocketImpl.java \
+ org/servalarch/test/TCPServer.java \
+ org/servalarch/test/TCPClient.java \
+ org/servalarch/test/UDPServer.java \
+ org/servalarch/test/UDPClient.java
EXTRA_DIST=
@@ -31,9 +31,9 @@ JAVAROOT=$(top_builddir)/src/javasock/java
AM_JAVACFLAGS=
clean-local:
- rm -f serval/test/*~
- rm -f serval/net/*~
- rm -f serval/platform/*~
+ rm -f org/servalarch/test/*~
+ rm -f org/servalarch/net/*~
+ rm -f org/servalarch/platform/*~
rm -f *~
rm -f *.class
rm -f *.stamp
View
2  ...avasock/java/serval/net/ServalDatagramPacket.java → ...java/org/servalarch/net/ServalDatagramPacket.java
@@ -1,5 +1,5 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.net;
+package org.servalarch.net;
import java.net.InetAddress;
import java.net.SocketAddress;
View
8 ...avasock/java/serval/net/ServalDatagramSocket.java → ...java/org/servalarch/net/ServalDatagramSocket.java
@@ -1,5 +1,5 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.net;
+package org.servalarch.net;
import java.net.SocketAddress;
import java.net.SocketException;
@@ -7,9 +7,9 @@
import java.net.InetAddress;
import java.io.IOException;
import java.nio.channels.DatagramChannel;
-import serval.net.ServalDatagramSocketImpl;
-import serval.net.ServiceID;
-import serval.net.ServalDatagramSocketImplFactory;
+import org.servalarch.net.ServalDatagramSocketImpl;
+import org.servalarch.net.ServiceID;
+import org.servalarch.net.ServalDatagramSocketImplFactory;
/*
This code is based on the DatagramSocket implementation from the
View
4 ...ock/java/serval/net/ServalDatagramSocketImpl.java → .../org/servalarch/net/ServalDatagramSocketImpl.java
@@ -1,5 +1,5 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.net;
+package org.servalarch.net;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -8,7 +8,7 @@
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
-import serval.platform.ServalNetworkStack;
+import org.servalarch.platform.ServalNetworkStack;
/**
* The superclass for Serval datagram socket implementations.
View
2  ...a/serval/net/ServalDatagramSocketImplFactory.java → ...rvalarch/net/ServalDatagramSocketImplFactory.java
@@ -1,5 +1,5 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.net;
+package org.servalarch.net;
/**
* This interface defines a factory for Serval datagram socket
View
3  .../java/serval/net/ServalPlainServerSocketImpl.java → ...g/servalarch/net/ServalPlainServerSocketImpl.java
@@ -15,8 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package serval.net;
+package org.servalarch.net;
import java.io.FileDescriptor;
import java.net.SocketException;
View
5 ...vasock/java/serval/net/ServalPlainSocketImpl.java → ...ava/org/servalarch/net/ServalPlainSocketImpl.java
@@ -15,8 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package serval.net;
+package org.servalarch.net;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -35,7 +34,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
-import serval.platform.ServalNetworkStack;
+import org.servalarch.platform.ServalNetworkStack;
/**
* A concrete connected-socket implementation.
View
2  ...k/java/serval/net/ServalServerDatagramSocket.java → ...rg/servalarch/net/ServalServerDatagramSocket.java
@@ -1,5 +1,5 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.net;
+package org.servalarch.net;
import java.net.SocketAddress;
import java.io.IOException;
View
3  src/javasock/java/serval/net/ServalServerSocket.java → ...k/java/org/servalarch/net/ServalServerSocket.java
@@ -15,8 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package serval.net;
+package org.servalarch.net;
import java.io.IOException;
import java.net.BindException;
View
5 src/javasock/java/serval/net/ServalSocket.java → ...avasock/java/org/servalarch/net/ServalSocket.java
@@ -15,8 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package serval.net;
+package org.servalarch.net;
import java.io.IOException;
import java.io.InputStream;
@@ -29,7 +28,7 @@
import java.net.SocketOptions;
import java.net.UnknownHostException;
import java.nio.channels.SocketChannel;
-import serval.platform.ServalNetworkStack;
+import org.servalarch.platform.ServalNetworkStack;
/**
* Provides a client-side TCP socket.
View
2  ...javasock/java/serval/net/ServalSocketAddress.java → .../java/org/servalarch/net/ServalSocketAddress.java
@@ -1,5 +1,5 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.net;
+package org.servalarch.net;
import java.net.SocketAddress;
import java.net.InetAddress;
View
6 src/javasock/java/serval/net/ServalSocketImpl.java → ...ock/java/org/servalarch/net/ServalSocketImpl.java
@@ -15,8 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package serval.net;
+package org.servalarch.net;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -26,8 +25,7 @@
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketOptions;
-
-import serval.platform.ServalNetworkStack;
+import org.servalarch.platform.ServalNetworkStack;
/**
View
3  ...sock/java/serval/net/ServalSocketImplFactory.java → ...a/org/servalarch/net/ServalSocketImplFactory.java
@@ -15,8 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package serval.net;
+package org.servalarch.net;
/**
* This interface defines a factory for Serval socket implementations.
View
2  ...sock/java/serval/net/ServalSocketInputStream.java → ...a/org/servalarch/net/ServalSocketInputStream.java
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package serval.net;
+package org.servalarch.net;
import java.io.IOException;
import java.io.InputStream;
View
2  ...ock/java/serval/net/ServalSocketOutputStream.java → .../org/servalarch/net/ServalSocketOutputStream.java
@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package serval.net;
+package org.servalarch.net;
import java.io.IOException;
import java.io.OutputStream;
View
16 src/javasock/java/serval/net/ServiceID.java → src/javasock/java/org/servalarch/net/ServiceID.java
@@ -1,11 +1,12 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.net;
+package org.servalarch.net;
public class ServiceID {
private byte[] identifier = null;
public static final int SERVICE_ID_MAX_BITS = 256;
public static final int SERVICE_ID_MAX_LENGTH = 20;
-
+ private String idStr = null;
+
public ServiceID() {
// Creates an invalid serviceID
}
@@ -50,4 +51,15 @@ public boolean valid() {
// FIXME: do something useful here.
return identifier != null;
}
+
+ @Override
+ public String toString() {
+ if (idStr == null) {
+ idStr = "";
+ for (int i = 0; i < 20; i++) {
+ idStr += String.format("%02x", identifier[i]);
+ }
+ }
+ return idStr;
+ }
}
View
10 ...sock/java/serval/platform/ServalNetworkStack.java → ...a/org/servalarch/platform/ServalNetworkStack.java
@@ -1,10 +1,10 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.platform;
+package org.servalarch.platform;
-import serval.net.ServalDatagramSocketImpl;
-import serval.net.ServalSocketImpl;
-import serval.net.ServiceID;
-import serval.net.ServalDatagramPacket;
+import org.servalarch.net.ServalDatagramSocketImpl;
+import org.servalarch.net.ServalSocketImpl;
+import org.servalarch.net.ServiceID;
+import org.servalarch.net.ServalDatagramPacket;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InterruptedIOException;
View
6 src/javasock/java/serval/test/TCPClient.java → src/javasock/java/org/servalarch/test/TCPClient.java
@@ -1,5 +1,5 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.test;
+package org.servalarch.test;
import java.io.IOException;
import java.io.InputStreamReader;
@@ -9,7 +9,9 @@
import java.lang.System;
import java.lang.Thread;
import java.lang.Runnable;
-import serval.net.*;
+
+import org.servalarch.net.ServalSocket;
+import org.servalarch.net.ServiceID;
public class TCPClient {
private ServalSocket sock;
View
7 src/javasock/java/serval/test/TCPServer.java → src/javasock/java/org/servalarch/test/TCPServer.java
@@ -1,5 +1,5 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.test;
+package org.servalarch.test;
import java.net.SocketTimeoutException;
import java.io.IOException;
@@ -10,7 +10,10 @@
import java.lang.System;
import java.lang.Thread;
import java.lang.Runnable;
-import serval.net.*;
+
+import org.servalarch.net.ServalServerSocket;
+import org.servalarch.net.ServalSocket;
+import org.servalarch.net.ServiceID;
public class TCPServer {
private ServalServerSocket serverSock;
View
8 src/javasock/java/serval/test/UDPClient.java → src/javasock/java/org/servalarch/test/UDPClient.java
@@ -1,11 +1,15 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.test;
+package org.servalarch.test;
import java.io.IOException;
import java.lang.System;
import java.lang.Thread;
import java.lang.Runnable;
-import serval.net.*;
+
+import org.servalarch.net.ServalDatagramPacket;
+import org.servalarch.net.ServalDatagramSocket;
+import org.servalarch.net.ServiceID;
+
public class UDPClient {
private ServalDatagramSocket sock;
View
9 src/javasock/java/serval/test/UDPServer.java → src/javasock/java/org/servalarch/test/UDPServer.java
@@ -1,11 +1,16 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-package serval.test;
+package org.servalarch.test;
import java.net.SocketTimeoutException;
import java.lang.System;
import java.lang.Thread;
import java.lang.Runnable;
-import serval.net.*;
+
+import org.servalarch.net.ServalDatagramPacket;
+import org.servalarch.net.ServalDatagramSocket;
+import org.servalarch.net.ServalServerDatagramSocket;
+import org.servalarch.net.ServiceID;
+
public class UDPServer {
private ServalServerDatagramSocket serverSock;
View
4 src/libservalctrl/Makefile.am
@@ -1,3 +1,7 @@
+SUBDIRS = \
+ . \
+ java
+
lib_LTLIBRARIES = libservalctrl.la
libservalctrl_la_DEPENDENCIES = \
View
40 src/libservalctrl/hostctrl.c
@@ -32,14 +32,27 @@ static int hostctrl_recv(struct message_channel_callback *mcb,
struct hostctrl *hc = (struct hostctrl *)mcb->target;
struct ctrlmsg *cm = (struct ctrlmsg *)m->data;
- LOG_DBG("Received message on channel\n");
-
if (!hc->ops)
return 0;
return hc->ops->ctrlmsg_recv(hc, cm, &m->from);
}
+static int on_start_message_channel(struct message_channel_callback *mcb)
+{
+ struct hostctrl *hc = (struct hostctrl *)mcb->target;
+ if (hc->cbs)
+ return hc->cbs->start(hc);
+ return 0;
+}
+
+static void on_stop_message_channel(struct message_channel_callback *mcb)
+{
+ struct hostctrl *hc = (struct hostctrl *)mcb->target;
+ if (hc->cbs)
+ hc->cbs->stop(hc);
+}
+
static struct hostctrl *hostctrl_create(struct message_channel *mc,
const struct hostctrl_callback *cbs,
void *context)
@@ -55,6 +68,8 @@ static struct hostctrl *hostctrl_create(struct message_channel *mc,
hc->mccb.target = hc;
hc->mccb.recv = hostctrl_recv;
+ hc->mccb.start = on_start_message_channel;
+ hc->mccb.stop = on_stop_message_channel;
hc->mc = mc;
hc->context = context;
hc->ops = hops[message_channel_get_type(mc)];
@@ -109,7 +124,7 @@ struct hostctrl *hostctrl_local_create(const struct hostctrl_callback *cbs,
peer.sun_family = PF_UNIX;
strcpy(peer.sun_path, SERVAL_STACK_CTRL_PATH);
-
+
mc = message_channel_get_generic(MSG_CHANNEL_UNIX, SOCK_DGRAM,
0, (struct sockaddr *)&local,
sizeof(local),
@@ -118,7 +133,7 @@ struct hostctrl *hostctrl_local_create(const struct hostctrl_callback *cbs,
#endif
if (!mc) {
- LOG_DBG("Could not create local host control interface\n");
+ LOG_ERR("Could not create local host control interface\n");
return NULL;
}
}
@@ -127,9 +142,12 @@ struct hostctrl *hostctrl_local_create(const struct hostctrl_callback *cbs,
if (!hc)
message_channel_put(mc);
- else if (flags & HCF_START)
- hostctrl_start(hc);
-
+ else if (flags & HCF_START) {
+ if (hostctrl_start(hc) == -1) {
+ hostctrl_free(hc);
+ return NULL;
+ }
+ }
return hc;
}
@@ -157,8 +175,12 @@ hostctrl_remote_create_specific(const struct hostctrl_callback *cbs,
if (!hc)
message_channel_put(mc);
- else if (flags & HCF_START)
- hostctrl_start(hc);
+ else if (flags & HCF_START) {
+ if (hostctrl_start(hc) == -1) {
+ hostctrl_free(hc);
+ return NULL;
+ }
+ }
return hc;
}
View
11 src/libservalctrl/java/.classpath
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="lib" path="../../javasock/org.servalarch.javasock.jar">
+ <attributes>
+ <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="../../src/javasock"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
17 src/libservalctrl/java/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>servalctrl</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
29 src/libservalctrl/java/Makefile.am
@@ -0,0 +1,29 @@
+SUBDIRS = \
+ jni \
+ src
+
+JARFILE = org.servalarch.servalctrl.jar
+MANIFEST = Manifest.txt
+javasock_DATA = $(JARFILE)
+javasockdir = $(datadir)/java
+EXTRA_DIST = $(MANIFEST) README
+CLASSFILES = $(shell find ./bin -name *.class -print)
+
+classes.list: $(SUBDIRS) $(CLASSFILES)
+ @echo $(CLASSFILES)
+ (cd bin; find . -name "*.class" -print > ../$@)
+
+sources.list: $(SUBDIRS) $(SOURCEFILES)
+ @echo $(SOURCEFILES)
+ (cd src; find . -name "*.java" -print > ../$@)
+
+$(JARFILE): classes.list sources.list $(MANIFEST)
+ @echo "Creating Jar file"
+ (cd bin; jar cfm ../$@ ../$(MANIFEST) @../classes.list)
+ (cd src; jar uf ../$@ @../sources.list)
+
+clean-local:
+ rm -f *~
+ rm -f $(JARFILE)
+ rm -f classes.list
+ rm -f sources.list
View
7 src/libservalctrl/java/Manifest.txt
@@ -0,0 +1,7 @@
+Name: org/servalarch/servalctrl
+Specification-Title: Java JNI wrapper for libservalctrl
+Specification-Version: 1.0
+Specification-Vendor: sns.cs.princeton.edu
+Implementation-Title: org.servalarch.servalctrl
+Implementation-Version: 1.0
+Implementation-Vendor: Princeton University
View
0  src/libservalctrl/java/bin/.gitignore
No changes.
View
24 src/libservalctrl/java/jni/Makefile.am
@@ -0,0 +1,24 @@
+lib_LTLIBRARIES = libservalctrl_jni.la
+
+libservalctrl_jni_la_DEPENDENCIES = \
+ $(top_srcdir)/src/libservalctrl/libservalctrl.la
+
+libservalctrl_jni_la_SOURCES = \
+ org_servalarch_servalctrl_HostCtrl.c
+
+noinst_HEADERS = \
+ org_servalarch_servalctrl_HostCtrl.h
+
+libservalctrl_jni_la_CPPFLAGS = \
+ -I$(top_srcdir)/include \
+ $(JAVA_INCLUDE)
+
+libservalctrl_jni_la_LDFLAGS = \
+ -L$(top_srcdir)/src/libservalctrl \
+ -lservalctrl
+
+#libservalctrl_jni_la_LIBADD = \
+# $(top_srcdir)/src/common/libcommon.la
+
+clean-local:
+ rm -f *~
View
594 src/libservalctrl/java/jni/org_servalarch_servalctrl_HostCtrl.c
@@ -0,0 +1,594 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include <libservalctrl/hostctrl.h>
+#include <libservalctrl/init.h>
+#include "org_servalarch_servalctrl_HostCtrl.h"
+
+/*
+ These conversion macros are needed to stop the compiler from
+ complaining about converting a 64-bit jlong value to a 32-bit
+ pointer value on 32-bit platforms.
+ */
+#if defined(__LP64__)
+#define ptr_to_jlong(p) (p ? (jlong)p : 0)
+#define jlong_to_ptr(l) ((void *)((uintptr_t)l))
+#else
+#define ptr_to_jlong(p) (p ? (jlong)((jint)p) : 0)
+#define jlong_to_ptr(l) ((void *) (((uintptr_t)l) & 0xffffffff))
+#endif
+
+static JavaVM *jvm = NULL;
+
+struct jni_context {
+ JNIEnv *env;
+ jobject obj;
+ jclass cls;
+ jobject callbacks;
+ jclass hostctrl_cls;
+ jclass callbacks_cls;
+ struct hostctrl *hc;
+};
+
+static struct jni_context *get_native_context(JNIEnv *env, jobject obj)
+{
+ jclass cls = (*env)->GetObjectClass(env, obj);
+ jfieldID fid = (*env)->GetFieldID(env, cls, "nativeHandle", "J");
+
+ if (!fid)
+ return NULL;
+
+ return (struct jni_context *)jlong_to_ptr((*env)->GetLongField(env, obj, fid));
+}
+
+static int set_native_context(JNIEnv *env, jobject obj, struct jni_context *ctx)
+{
+ jfieldID fid = (*env)->GetFieldID(env, ctx->cls, "nativeHandle", "J");
+
+ if (!fid)
+ return -1;
+
+ (*env)->SetLongField(env, obj, fid, ptr_to_jlong(ctx));
+
+ return 0;
+}
+
+static int fill_in_service_id(JNIEnv *env, jobject obj, struct service_id *sid)
+{
+ jboolean isCopy = JNI_FALSE;
+ jclass cls = (*env)->GetObjectClass(env, obj);
+ jfieldID fid;
+ jbyteArray array;
+ jbyte *buffer;
+
+ fid = (*env)->GetFieldID(env, cls, "identifier", "[B");
+
+ if (!fid)
+ return -1;
+
+ array = (*env)->GetObjectField(env, obj, fid);
+
+ if (!array)
+ return -1;
+
+ buffer = (*env)->GetByteArrayElements(env, array, &isCopy);
+
+ if (!buffer)
+ return -1;
+
+ memcpy(sid->s_sid, buffer, (*env)->GetArrayLength(env, array));
+
+ (*env)->ReleaseByteArrayElements(env, array, buffer, 0);
+
+ return 0;
+}
+
+static int fill_in_addr(JNIEnv *env, jobject obj, struct in_addr *ipaddr)
+{
+ jboolean isCopy = JNI_FALSE;
+ jclass cls;
+ jmethodID mid;
+ jbyteArray array;
+ jbyte *buffer;
+
+ cls = (*env)->FindClass(env, "java/net/InetAddress");
+
+ if (!cls)
+ return -1;
+
+ mid = (*env)->GetMethodID(env, cls, "getAddress", "()[B");
+
+ if (!mid)
+ return -1;
+
+ array = (*env)->CallObjectMethod(env, obj, mid);
+
+ if (!array)
+ return -1;
+
+ buffer = (*env)->GetByteArrayElements(env, array, &isCopy);
+
+ if (!buffer)
+ return -1;
+
+ memcpy(&ipaddr->s_addr, buffer, (*env)->GetArrayLength(env, array));
+
+ (*env)->ReleaseByteArrayElements(env, array, buffer, 0);
+
+ return 0;
+}
+
+static jobject get_callbacks(JNIEnv *env, struct jni_context *ctx)
+{
+ jfieldID fid;
+
+ fid = (*env)->GetFieldID(env, ctx->hostctrl_cls, "callbacks",
+ "Lorg/servalarch/servalctrl/HostCtrlCallbacks;");
+
+ if (!fid) {
+ fprintf(stderr, "could not get fid\n");
+ return NULL;
+ }
+
+ return (*env)->GetObjectField(env, ctx->obj, fid);
+}
+
+static jobject new_service_id(JNIEnv *env, const struct service_id *srvid)
+{
+ jclass cls = (*env)->FindClass(env, "org/servalarch/net/ServiceID");
+ jbyteArray arr;
+ jobject service_id;
+ jmethodID cid;
+
+ if (!cls)
+ return NULL;
+
+ cid = (*env)->GetMethodID(env, cls, "<init>", "([B)V");
+
+ if (!cid)
+ return NULL;
+
+ arr = (*env)->NewByteArray(env, 20);
+
+ if (!arr)
+ return NULL;
+
+ (*env)->SetByteArrayRegion(env, arr, 0, 20, (jbyte *)srvid->s_sid);
+
+ service_id = (*env)->NewObject(env, cls, cid, arr);
+
+ (*env)->DeleteLocalRef(env, arr);
+
+ return service_id;
+}
+
+static jobject new_inet4addr(JNIEnv *env, const struct in_addr *ipaddr)
+{
+ jclass cls = (*env)->FindClass(env, "java/net/InetAddress");
+ jbyteArray arr;
+ jobject addr;
+ jmethodID mid;
+
+ if (!cls) {
+ fprintf(stderr, "could not find InetAddress class\n");
+ return NULL;
+ }
+
+ mid = (*env)->GetStaticMethodID(env, cls, "getByAddress", "([B)Ljava/net/InetAddress;");
+
+ if (!mid) {
+ fprintf(stderr, "could not find getByAddress mid\n");
+ return NULL;
+ }
+
+ arr = (*env)->NewByteArray(env, 4);
+
+ if (!arr) {
+ fprintf(stderr, "could not create byteArray\n");
+ return NULL;
+ }
+
+ (*env)->SetByteArrayRegion(env, arr, 0, 4, (jbyte *)ipaddr);
+
+ addr = (*env)->CallStaticObjectMethod(env, cls, mid, arr);
+
+ if (!addr) {
+ fprintf(stderr, "addr is NULL\n");
+ }
+
+ (*env)->DeleteLocalRef(env, arr);
+
+ return addr;
+}
+
+static int service_registration(struct hostctrl *hc,
+ const struct service_id *srvid,
+ unsigned short flags,
+ unsigned short prefix,
+ const struct in_addr *ip,
+ const struct in_addr *old_ip)
+{
+ struct jni_context *ctx = (struct jni_context *)hc->context;
+ JNIEnv *env = ctx->env;
+ jobject service_id, addr, old_addr = NULL;
+ jmethodID mid;
+
+ mid = (*env)->GetMethodID(env, ctx->callbacks_cls, "serviceRegistration",
+ "(Lorg/servalarch/net/ServiceID;IILjava/net/InetAddress;Ljava/net/InetAddress;)V");
+
+ if (!mid) {
+ fprintf(stderr, "could not find mid\n");
+ return -1;
+ }
+ service_id = new_service_id(env, srvid);
+
+ if (!service_id) {
+ fprintf(stderr, "could not create serviceID\n");
+ return -1;
+ }
+
+ addr = new_inet4addr(env, ip);
+
+ if (!addr) {
+ fprintf(stderr, "could not create addr1\n");
+ goto err_addr;
+ }
+
+ if (old_ip) {
+ old_addr = new_inet4addr(env, old_ip);
+
+ if (!old_addr) {
+ fprintf(stderr, "could not create addr2\n");
+ goto err_old_addr;
+ }
+ }
+
+ (*env)->CallVoidMethod(env, get_callbacks(env, ctx), mid, service_id, (jint)flags,
+ (jint)prefix, addr, old_addr);
+
+ (*env)->DeleteLocalRef(env, old_addr);
+err_old_addr:
+ (*env)->DeleteLocalRef(env, addr);
+err_addr:
+ (*env)->DeleteLocalRef(env, service_id);
+
+ return 0;
+}
+
+static int service_unregistration(struct hostctrl *hc,
+ const struct service_id *srvid,
+ unsigned short flags,
+ unsigned short prefix,
+ const struct in_addr *ip)
+{
+ struct jni_context *ctx = (struct jni_context *)hc->context;
+ JNIEnv *env = ctx->env;
+ jobject service_id, addr;
+ jmethodID mid;
+
+ mid = (*env)->GetMethodID(env, ctx->callbacks_cls, "serviceUnregistration",
+ "(Lorg/servalarch/net/ServiceID;IILjava/net/InetAddress;)V");
+
+ if (!mid)
+ return -1;
+
+ service_id = new_service_id(env, srvid);
+
+ if (!service_id)
+ return -1;
+
+ addr = new_inet4addr(env, ip);
+
+ if (!addr)
+ goto err_addr;
+
+ (*env)->CallVoidMethod(env, get_callbacks(env, ctx), mid, service_id, (jint)flags,
+ (jint)prefix, addr);
+
+ (*env)->DeleteLocalRef(env, addr);
+err_addr:
+ (*env)->DeleteLocalRef(env, service_id);
+
+ return 0;
+}
+
+static int service_stat_update(struct hostctrl *hc,
+ struct service_info_stat *stat,
+ unsigned int num_stat)
+{
+ /*
+ struct jni_context *ctx = (struct jni_context *)hc->context;
+ JNIEnv *env = ctx->env;
+ */
+ return 0;
+}
+
+static int service_get(struct hostctrl *hc,
+ const struct service_id *srvid,
+ unsigned short flags,
+ unsigned short prefix,
+ unsigned int priority,
+ unsigned int weight,
+ struct in_addr *ip)
+{
+ struct jni_context *ctx = (struct jni_context *)hc->context;
+ JNIEnv *env = ctx->env;
+ jobject service_id, addr;
+ jmethodID mid;
+
+ mid = (*env)->GetMethodID(env, ctx->callbacks_cls, "serviceGet",
+ "(Lorg/servalarch/net/ServiceID;IIIILjava/net/InetAddress;)V");
+
+ if (!mid)
+ return -1;
+
+ service_id = new_service_id(env, srvid);
+
+ if (!service_id)
+ return -1;
+
+ addr = new_inet4addr(env, ip);
+
+ if (!addr)
+ goto err_addr;
+
+ (*env)->CallVoidMethod(env, get_callbacks(env, ctx), mid, service_id, (jint)flags,
+ (jint)prefix, (jint)priority, (jint)weight, addr);
+
+ (*env)->DeleteLocalRef(env, addr);
+err_addr:
+ (*env)->DeleteLocalRef(env, service_id);
+
+ return 0;
+}
+
+static int hostctrl_on_start(struct hostctrl *hc)
+{
+ struct jni_context *ctx = (struct jni_context *)hc->context;
+ (*jvm)->AttachCurrentThread(jvm, (void **)&ctx->env, NULL);
+ return 0;
+}
+
+static void hostctrl_on_stop(struct hostctrl *hc) {
+ if ((*jvm)->DetachCurrentThread(jvm) != JNI_OK) {
+ fprintf(stderr, "%s: Could not detach callback thread\n", __func__);
+ }
+}
+
+static struct hostctrl_callback cb = {
+ .start = hostctrl_on_start,
+ .stop = hostctrl_on_stop,
+ .service_registration = service_registration,
+ .service_unregistration = service_unregistration,
+ .service_stat_update = service_stat_update,
+ .service_get = service_get,
+};
+
+
+enum {
+ HOSTCTRL_LOCAL,
+ HOSTCTRL_REMOTE,
+};
+
+jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_nativeInit(JNIEnv *env, jobject obj, jint type)
+{
+ struct jni_context *ctx;
+ jclass cls = (*env)->GetObjectClass(env, obj);
+ jclass hostctrl_cls = (*env)->FindClass(env, "org/servalarch/servalctrl/HostCtrl");
+ jclass callbacks_cls;
+
+ if (!hostctrl_cls) {
+ fprintf(stderr, "%s could not find HostCtrl class\n", __func__);
+ return -1;
+ }
+
+ callbacks_cls = (*env)->FindClass(env, "org/servalarch/servalctrl/HostCtrlCallbacks");
+
+ if (!callbacks_cls) {
+ fprintf(stderr, "%s could not find HostCtrlCallbacks class\n", __func__);
+ return -1;
+ }
+
+ ctx = malloc(sizeof(*ctx));
+
+ if (!ctx)
+ return -1;
+
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->obj = (*env)->NewGlobalRef(env, obj);
+ ctx->cls = (*env)->NewGlobalRef(env, cls);
+ ctx->hostctrl_cls = (*env)->NewGlobalRef(env, hostctrl_cls);
+ ctx->callbacks_cls = (*env)->NewGlobalRef(env, callbacks_cls);
+ ctx->callbacks = (*env)->NewGlobalRef(env, get_callbacks(env, ctx));
+ ctx->env = NULL; /* Initialized on callback thread when it starts */
+
+ if (set_native_context(env, obj, ctx) == -1) {
+ free(ctx);
+ return -1;
+ }
+
+ if (type == HOSTCTRL_LOCAL)
+ ctx->hc = hostctrl_local_create(&cb, ctx, HCF_NONE);
+ else if (type == HOSTCTRL_REMOTE)
+ ctx->hc = hostctrl_remote_create(&cb, ctx, HCF_NONE);
+ else
+ return -1;
+
+ if (!ctx->hc)
+ return -1;
+
+ if (hostctrl_start(ctx->hc) == -1) {
+ hostctrl_free(ctx->hc);
+ ctx->hc = NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
+void JNICALL Java_org_servalarch_servalctrl_HostCtrl_nativeFree(JNIEnv *env, jobject obj)
+{
+ struct jni_context *ctx = get_native_context(env, obj);
+ if (ctx->hc)
+ hostctrl_free(ctx->hc);
+ (*env)->DeleteGlobalRef(env, ctx->obj);
+ (*env)->DeleteGlobalRef(env, ctx->cls);
+ (*env)->DeleteGlobalRef(env, ctx->hostctrl_cls);
+ (*env)->DeleteGlobalRef(env, ctx->callbacks_cls);
+ (*env)->DeleteGlobalRef(env, ctx->callbacks);
+ free(ctx);
+}
+
+jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_migrateFlow(JNIEnv *env, jobject obj,
+ jlong flowid, jstring ifname)
+{
+ const char *name;
+ struct jni_context *ctx = get_native_context(env, obj);
+ struct flow_id fl = { .s_id32 = htonl(flowid) };
+ int ret;
+
+ name = (*env)->GetStringUTFChars(env, ifname, 0);
+
+ if (!name)
+ return -1;
+
+ ret = hostctrl_flow_migrate(ctx->hc, &fl, name);
+
+ (*env)->ReleaseStringUTFChars(env, ifname, name);
+
+ return ret;
+}
+
+jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_migrateInterface(JNIEnv *env, jobject obj, jstring fromIface, jstring toIface)
+{
+ const char *from, *to;
+ struct jni_context *ctx = get_native_context(env, obj);
+ int ret;
+
+ from = (*env)->GetStringUTFChars(env, fromIface, 0);
+
+ if (!from)
+ return -1;
+
+ to = (*env)->GetStringUTFChars(env, toIface, 0);
+
+ if (!to) {
+ (*env)->ReleaseStringUTFChars(env, fromIface, from);
+ return -1;
+ }
+
+ ret = hostctrl_interface_migrate(ctx->hc, from, to);
+
+ (*env)->ReleaseStringUTFChars(env, fromIface, from);
+ (*env)->ReleaseStringUTFChars(env, toIface, to);
+
+ return ret;
+}
+
+jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_addService4(JNIEnv *env, jobject obj,
+ jobject service_id, jint prefix_bits,
+ jint priority, jint weight, jobject addr)
+{
+ struct jni_context *ctx = get_native_context(env, obj);
+ struct service_id srvid;
+ struct in_addr ipaddr;
+
+ if (fill_in_service_id(env, service_id, &srvid) == -1)
+ return -1;
+
+ if (fill_in_addr(env, addr, &ipaddr) == -1)
+ return -1;
+
+ return hostctrl_service_add(ctx->hc, &srvid, (unsigned short)prefix_bits,
+ (unsigned int)priority, (unsigned int)weight, &ipaddr);
+}
+
+jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_getService4(JNIEnv *env, jobject obj,
+ jobject service_id, jint prefix_bits,
+ jobject addr)
+{
+ struct jni_context *ctx = get_native_context(env, obj);
+ struct service_id srvid;
+ struct in_addr ipaddr;
+
+ if (fill_in_service_id(env, service_id, &srvid) == -1)
+ return -1;
+
+ if (fill_in_addr(env, addr, &ipaddr) == -1)
+ return -1;
+
+ return hostctrl_service_get(ctx->hc, &srvid, (unsigned short)prefix_bits, &ipaddr);
+}
+
+jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_removeService4(JNIEnv *env, jobject obj,
+ jobject service_id, jint prefix_bits,
+ jobject addr)
+{
+ struct jni_context *ctx = get_native_context(env, obj);
+ struct service_id srvid;
+ struct in_addr ipaddr;
+
+ if (fill_in_service_id(env, service_id, &srvid) == -1)
+ return -1;
+
+ if (fill_in_addr(env, addr, &ipaddr) == -1)
+ return -1;
+
+ return hostctrl_service_remove(ctx->hc, &srvid, (unsigned short)prefix_bits, &ipaddr);
+}
+
+jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_registerService4(JNIEnv *env, jobject obj,
+ jobject service_id, jint prefix_bits,
+ jobject addr)
+{
+ struct jni_context *ctx = get_native_context(env, obj);
+ struct service_id srvid;
+ struct in_addr ipaddr;
+
+ if (fill_in_service_id(env, service_id, &srvid) == -1)
+ return -1;
+
+ if (fill_in_addr(env, addr, &ipaddr) == -1)
+ return -1;
+
+ return hostctrl_service_register(ctx->hc, &srvid, (unsigned short)prefix_bits, &ipaddr);
+}
+
+jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_unregisterService4(JNIEnv *env, jobject obj,
+ jobject service_id, jint prefix_bits)
+{
+ struct jni_context *ctx = get_native_context(env, obj);
+ struct service_id srvid;
+
+ if (fill_in_service_id(env, service_id, &srvid) == -1)
+ return -1;
+
+ return hostctrl_service_unregister(ctx->hc, &srvid, (unsigned short)prefix_bits);
+}
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
+{
+ JNIEnv *env;
+ int ret;
+
+ jvm = vm;
+
+ if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4) != JNI_OK) {
+ fprintf(stderr, "Could not get JNI env in JNI_OnLoad\n");
+ return -1;
+ }
+
+ ret = libservalctrl_init();
+
+ return ret == 0 ? JNI_VERSION_1_4 : ret;
+}
+
+JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
+{
+ JNIEnv *env = NULL;
+
+ libservalctrl_fini();
+
+ if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_4) != JNI_OK) {
+ fprintf(stderr, "Could not get JNI env in JNI_OnUnload\n");
+ return;
+ }
+}
View
89 src/libservalctrl/java/jni/org_servalarch_servalctrl_HostCtrl.h
@@ -0,0 +1,89 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_servalarch_servalctrl_HostCtrl */
+
+#ifndef _Included_org_servalarch_servalctrl_HostCtrl
+#define _Included_org_servalarch_servalctrl_HostCtrl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_servalarch_servalctrl_HostCtrl_HOSTCTRL_LOCAL
+#define org_servalarch_servalctrl_HostCtrl_HOSTCTRL_LOCAL 0L
+#undef org_servalarch_servalctrl_HostCtrl_HOSTCTRL_REMOTE
+#define org_servalarch_servalctrl_HostCtrl_HOSTCTRL_REMOTE 1L
+/*
+ * Class: org_servalarch_servalctrl_HostCtrl
+ * Method: nativeInit
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_nativeInit
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: org_servalarch_servalctrl_HostCtrl
+ * Method: nativeFree
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_servalarch_servalctrl_HostCtrl_nativeFree
+ (JNIEnv *, jobject);
+
+/*
+ * Class: org_servalarch_servalctrl_HostCtrl
+ * Method: migrateFlow
+ * Signature: (JLjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_migrateFlow
+ (JNIEnv *, jobject, jlong, jstring);
+
+/*
+ * Class: org_servalarch_servalctrl_HostCtrl
+ * Method: migrateInterface
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_migrateInterface
+ (JNIEnv *, jobject, jstring, jstring);
+
+/*
+ * Class: org_servalarch_servalctrl_HostCtrl
+ * Method: addService4
+ * Signature: (Lorg/servalarch/net/ServiceID;IIILjava/net/Inet4Address;)I
+ */
+JNIEXPORT jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_addService4
+ (JNIEnv *, jobject, jobject, jint, jint, jint, jobject);
+
+/*
+ * Class: org_servalarch_servalctrl_HostCtrl
+ * Method: getService4
+ * Signature: (Lorg/servalarch/net/ServiceID;ILjava/net/Inet4Address;)I
+ */
+JNIEXPORT jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_getService4
+ (JNIEnv *, jobject, jobject, jint, jobject);
+
+/*
+ * Class: org_servalarch_servalctrl_HostCtrl
+ * Method: removeService4
+ * Signature: (Lorg/servalarch/net/ServiceID;ILjava/net/Inet4Address;)I
+ */
+JNIEXPORT jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_removeService4
+ (JNIEnv *, jobject, jobject, jint, jobject);
+
+/*
+ * Class: org_servalarch_servalctrl_HostCtrl
+ * Method: registerService4
+ * Signature: (Lorg/servalarch/net/ServiceID;ILjava/net/Inet4Address;)I
+ */
+JNIEXPORT jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_registerService4
+ (JNIEnv *, jobject, jobject, jint, jobject);
+
+/*
+ * Class: org_servalarch_servalctrl_HostCtrl
+ * Method: unregisterService4
+ * Signature: (Lorg/servalarch/net/ServiceID;I)I
+ */
+JNIEXPORT jint JNICALL Java_org_servalarch_servalctrl_HostCtrl_unregisterService4
+ (JNIEnv *, jobject, jobject, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
View
19 src/libservalctrl/java/jni/org_servalarch_servalctrl_HostCtrl_HostCtrlException.h
@@ -0,0 +1,19 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class org_servalarch_servalctrl_HostCtrl_HostCtrlException */
+
+#ifndef _Included_org_servalarch_servalctrl_HostCtrl_HostCtrlException
+#define _Included_org_servalarch_servalctrl_HostCtrl_HostCtrlException
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_servalarch_servalctrl_HostCtrl_HostCtrlException_serialVersionUID
+#define org_servalarch_servalctrl_HostCtrl_HostCtrlException_serialVersionUID -3042686055658047285LL
+#undef org_servalarch_servalctrl_HostCtrl_HostCtrlException_serialVersionUID
+#define org_servalarch_servalctrl_HostCtrl_HostCtrlException_serialVersionUID -3387516993124229948LL
+#undef org_servalarch_servalctrl_HostCtrl_HostCtrlException_serialVersionUID
+#define org_servalarch_servalctrl_HostCtrl_HostCtrlException_serialVersionUID 1037378741410447851LL
+#ifdef __cplusplus
+}
+#endif
+#endif
View
18 src/libservalctrl/java/src/Makefile.am
@@ -0,0 +1,18 @@
+noinst_JAVA = \
+ org/servalarch/servalctrl/HostCtrl.java \
+ org/servalarch/servalctrl/LocalHostCtrl.java \
+ org/servalarch/servalctrl/RemoteHostCtrl.java \
+ org/servalarch/servalctrl/HostCtrlCallbacks.java \
+ org/servalarch/servalctrl/TestApp.java
+
+EXTRA_DIST = $(noinst_JAVA)
+
+JAVAROOT = $(top_builddir)/src/libservalctrl/java/bin
+
+AM_JAVACFLAGS=-classpath $(top_builddir)/src/javasock/java:$(top_builddir)/src/libservalctrl/java/src
+
+clean-local:
+ rm -f org/servalarch/servalctrl/*~
+ rm -f *~
+ rm -f *.class
+ rm -f *.stamp
View
89 src/libservalctrl/java/src/org/servalarch/servalctrl/HostCtrl.java
@@ -0,0 +1,89 @@
+package org.servalarch.servalctrl;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import org.servalarch.net.ServiceID;
+
+public abstract class HostCtrl {
+ private long nativeHandle = 0;
+ private final HostCtrlCallbacks callbacks;
+ private int type;
+ private boolean isDisposed = false;
+ protected static final int HOSTCTRL_LOCAL = 0;
+ protected static final int HOSTCTRL_REMOTE = 1;
+ private native int nativeInit(int type);
+ private native void nativeFree();
+
+ public HostCtrl(int type, final HostCtrlCallbacks cb) throws HostCtrlException {
+ switch (type) {
+ case HOSTCTRL_LOCAL:
+ case HOSTCTRL_REMOTE:
+ int ret = nativeInit(type);
+
+ if (ret == -1)
+ throw new HostCtrlException("Initialization failure ret=" + ret);
+ break;
+ default:
+ throw new IllegalArgumentException("No such host control type " + type);
+ }
+ this.type = type;
+ this.callbacks = cb;
+ }
+
+ public native int migrateFlow(long flowID, String toDevice);
+ public native int migrateInterface(String fromDevice, String toDevice);
+ private native int addService4(ServiceID id, int prefixBits, int prority, int weight, Inet4Address addr);
+ private native int getService4(ServiceID id, int prefixBits, Inet4Address addr);
+ private native int removeService4(ServiceID id, int prefixBits, Inet4Address addr);
+ private native int registerService4(ServiceID id, int prefixBits, Inet4Address oldAddr);
+ private native int unregisterService4(ServiceID id, int prefixBits);
+
+ public int addService(ServiceID id, int prefixBits, int priority, int weight, InetAddress addr) {
+ if (!(addr instanceof Inet4Address)) {
+ return -1;
+ }
+ if (prefixBits < 0 || prefixBits > 256)
+ prefixBits = 0;
+ return addService4(id, prefixBits, priority, weight, (Inet4Address)addr);
+ }
+ public int getService(ServiceID id, int prefixBits, InetAddress addr)
+ {
+ if (!(addr instanceof Inet4Address)) {
+ return -1;
+ }
+ if (prefixBits < 0 || prefixBits > 256)
+ prefixBits = 0;
+ return getService4(id, prefixBits, (Inet4Address)addr);
+ }
+
+ public int removeService(ServiceID id, int prefixBits, InetAddress addr) {
+ if (!(addr instanceof Inet4Address)) {
+ return -1;
+ }
+ if (prefixBits < 0 || prefixBits > 256)
+ prefixBits = 0;
+ return removeService4(id, prefixBits, (Inet4Address)addr);
+ }
+
+ public synchronized void dispose()
+ {
+ if (!isDisposed) {
+ isDisposed = true;
+ nativeFree();
+ }
+ }
+ protected void finalize() throws Throwable
+ {
+ dispose();
+ super.finalize();
+ }
+ static {
+ System.loadLibrary("servalctrl_jni");
+ }
+ public class HostCtrlException extends Exception {
+ private static final long serialVersionUID = 1037378741410447851L;
+ HostCtrlException(String msg) {
+ super(msg);
+ }
+ }
+}
View
14 src/libservalctrl/java/src/org/servalarch/servalctrl/HostCtrlCallbacks.java
@@ -0,0 +1,14 @@
+package org.servalarch.servalctrl;
+
+import java.net.InetAddress;
+
+import org.servalarch.net.ServiceID;
+
+public interface HostCtrlCallbacks {
+ public void serviceRegistration(ServiceID id, int flags, int prefixBits,
+ InetAddress addr, InetAddress oldAddr);
+ public void serviceUnregistration(ServiceID id, int flags, int prefixBits,
+ InetAddress addr);
+ public void serviceGet(ServiceID id, int flags, int prefixBits,
+ int priority, int weight, InetAddress addr);
+}
View
7 src/libservalctrl/java/src/org/servalarch/servalctrl/LocalHostCtrl.java
@@ -0,0 +1,7 @@
+package org.servalarch.servalctrl;
+
+public class LocalHostCtrl extends HostCtrl {
+ LocalHostCtrl(HostCtrlCallbacks cbs) throws HostCtrlException {
+ super(HostCtrl.HOSTCTRL_LOCAL, cbs);
+ }
+}
View
7 src/libservalctrl/java/src/org/servalarch/servalctrl/RemoteHostCtrl.java
@@ -0,0 +1,7 @@
+package org.servalarch.servalctrl;
+
+public class RemoteHostCtrl extends HostCtrl {
+ RemoteHostCtrl(HostCtrlCallbacks cbs) throws HostCtrlException {
+ super(HostCtrl.HOSTCTRL_REMOTE, cbs);
+ }
+}
View
54 src/libservalctrl/java/src/org/servalarch/servalctrl/TestApp.java
@@ -0,0 +1,54 @@
+package org.servalarch.servalctrl;
+
+import java.net.InetAddress;
+
+import org.servalarch.net.ServiceID;
+import org.servalarch.servalctrl.HostCtrl.HostCtrlException;
+
+public class TestApp {
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ LocalHostCtrl hc;
+ try {
+ hc = new LocalHostCtrl(new HostCtrlCallbacks() {
+
+ @Override
+ public void serviceRegistration(ServiceID id, int flags,