From 47a251f41e05f47b4bc19c236ab9441cef5ed42c Mon Sep 17 00:00:00 2001
From: rtrimana <rtrimana@uci.edu>
Date: Tue, 20 Dec 2016 09:57:54 -0800
Subject: [PATCH] Adjustments in stubs and skeletons for callback in callback;
 using different ports for each for now; still having problems with cross
 references in C++

---
 .../LifxLightBulb/LightBulb_Skeleton.java     |   4 +-
 iotjava/Makefile                              |  37 +++--
 iotjava/iotpolicy/IoTCompiler.java            | 142 ++++++++++++------
 iotjava/iotrmi/C++/basics/CallBack.hpp        |   7 +
 iotjava/iotrmi/C++/basics/TestClass.hpp       |   3 +
 .../C++/basics/TestClassAdvanced_Stub.cpp     |  27 ++--
 .../C++/basics/TestClassCallbacks_Stub.cpp    |  34 +++++
 .../iotrmi/C++/basics/TestClass_Skeleton.cpp  |   3 +-
 iotjava/iotrmi/Java/IoTRMICall.java           |   2 +
 iotjava/iotrmi/Java/IoTRMIObject.java         |   6 +
 iotjava/iotrmi/Java/basics/CallBack.java      |   6 +
 iotjava/iotrmi/Java/basics/TestClass.java     |   4 +-
 .../Java/basics/TestClassAdvanced_Stub.java   |  23 +--
 .../Java/basics/TestClassCallbacks_Stub.java  |  31 ++++
 .../Java/basics/TestClass_Skeleton.java       |   6 +-
 .../master/CommunicationHandler.java          |  32 ++++
 iotjava/iotruntime/master/IoTMaster.java      |  51 ++++++-
 .../iotruntime/master/ObjectInitHandler.java  |   9 +-
 iotjava/iotruntime/master/ObjectInitInfo.java |  11 +-
 .../iotruntime/messages/MessageGetObject.java |  24 ++-
 iotjava/iotruntime/slave/IoTSlave.java        |   6 +-
 .../iotpolicy/development/callbackpolicy.pol  |   2 +
 .../development/testclasspolicy_advanced.pol  |   3 +-
 .../development/testclasspolicy_callbacks.pol |  29 ++++
 .../testclassrequires_advanced.pol            |   2 +-
 .../testclassrequires_callbacks.pol           |   3 +
 localconfig/iotruntime/IoTMaster.config       |   3 +
 27 files changed, 406 insertions(+), 104 deletions(-)
 create mode 100644 iotjava/iotrmi/C++/basics/TestClassCallbacks_Stub.cpp
 create mode 100644 iotjava/iotrmi/Java/basics/TestClassCallbacks_Stub.java
 create mode 100644 localconfig/iotpolicy/development/testclasspolicy_callbacks.pol
 create mode 100644 localconfig/iotpolicy/development/testclassrequires_callbacks.pol

diff --git a/benchmarks/drivers/LifxLightBulb/LightBulb_Skeleton.java b/benchmarks/drivers/LifxLightBulb/LightBulb_Skeleton.java
index 6580d8d..bca3863 100644
--- a/benchmarks/drivers/LifxLightBulb/LightBulb_Skeleton.java
+++ b/benchmarks/drivers/LifxLightBulb/LightBulb_Skeleton.java
@@ -14,13 +14,15 @@ public class LightBulb_Skeleton implements LightBulb {
 	private LightBulb mainObj;
 	private IoTRMIObject rmiObj;
 
+	private String callbackAddress;
 	private final static int object0Id = 0;	//LightBulbTest
 	private static Integer[] object0Permission = { 2, 6, 1, 3, 4, 8, 0, 5, 7, 9 };
 	private static List<Integer> set0Allowed;
 	
 
-	public LightBulb_Skeleton(LightBulb _mainObj, int _port) throws Exception {
+	public LightBulb_Skeleton(LightBulb _mainObj, String _callbackAddress, int _port) throws Exception {
 		mainObj = _mainObj;
+		callbackAddress = _callbackAddress;
 		rmiObj = new IoTRMIObject(_port);
 		set0Allowed = new ArrayList<Integer>(Arrays.asList(object0Permission));
 		___waitRequestInvokeMethod();
diff --git a/iotjava/Makefile b/iotjava/Makefile
index 1d1b04d..509d5e3 100644
--- a/iotjava/Makefile
+++ b/iotjava/Makefile
@@ -22,8 +22,15 @@ compiler:
 PHONY += run-compiler-dev
 run-compiler-dev:
 	cp ../localconfig/iotpolicy/development/*.pol $(BIN_DIR)/iotpolicy/
-	cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler testclasspolicy.pol testclassrequires.pol callbackpolicy.pol callbackrequires.pol -cplus Cplus -java Java
-	cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler callbackpolicy.pol callbackrequires.pol testclasspolicy_advanced.pol testclassrequires_advanced.pol -cplus Cplus -java Java
+	#cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler testclasspolicy.pol testclassrequires.pol callbackpolicy.pol callbackrequires.pol -cplus Cplus -java Java
+	#cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler callbackpolicy.pol callbackrequires.pol testclasspolicy_advanced.pol testclassrequires_advanced.pol -cplus Cplus -java Java
+	cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler callbackpolicy.pol callbackrequires.pol testclasspolicy_callbacks.pol testclassrequires_callbacks.pol -cplus Cplus -java Java
+
+PHONY += run-compiler-lbtest
+run-compiler-lbtest:
+	cp ../localconfig/iotpolicy/LifxLightBulb/*.pol $(BIN_DIR)/iotpolicy/
+	cp ../localconfig/iotpolicy/LifxLightBulb/*.req $(BIN_DIR)/iotpolicy/
+	cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler lifxlightbulb.pol lifxtest.req -java Java
 
 PHONY += run-compiler-lifx
 run-compiler-lifx:
@@ -50,11 +57,21 @@ compile:
 	cp ./iotrmi/C++/basics/* $(BIN_DIR)/iotpolicy/output_files/Cplus
 	cd $(BIN_DIR)/iotpolicy/output_files; cp *.java ./Java
 	cd $(BIN_DIR)/iotpolicy/output_files; cp *.hpp ./Cplus
-	cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClass_Skeleton.java
-	cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClassAdvanced_Stub.java
-	cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./TestClass_Skeleton.cpp -o ./TestClass_Skeleton.out --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
-	cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./TestClassAdvanced_Stub.cpp -o ./TestClassAdvanced_Stub.out --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
-	cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(ARM_G++) ./TestClassInterface_Skeleton.cpp -o ./TestClassInterface_Skeleton.out --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
+#	cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClass_Skeleton.java
+#	cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClassAdvanced_Stub.java
+#	cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClassCallbacks_Stub.java
+#	cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClassInterface*.java
+#	cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) TestClassComplete*.java
+#	cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) CallBackInterface_CallbackSkeleton.java
+#	cd $(BIN_DIR)/iotpolicy/output_files/Java; $(JAVAC) -cp .:..:../../../$(BIN_DIR) CallBackInterfaceWithCallBack_CallbackStub.java
+#	cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./TestClass_Skeleton.cpp -o ./TestClass_Skeleton.out --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
+	#cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./TestClassAdvanced_Stub.cpp -o ./TestClassAdvanced_Stub.out --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
+#	cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./TestClassCallbacks_Stub.cpp -o ./TestClassCallbacks_Stub.out --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
+	cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(G++) ./TestClass.hpp -o ./TestClass.out --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
+	#cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(ARM_G++) ./TestClassInterface_Skeleton.cpp -o ./TestClassInterface_Skeleton.out --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
+	#cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(ARM_G++) ./TestClassCallbacks_Stub.cpp -o ./TestClassCallbacks_Stub.out --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
+	#cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(ARM_G++) ./TestClassComplete_Stub.hpp --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
+	#cd $(BIN_DIR)/iotpolicy/output_files/Cplus; $(ARM_G++) ./TestClassInterface_Skeleton.hpp --std=c++11 -pthread -pg -I../../../../iotjava/iotrmi/C++/
 
 PHONY += run-java-skeleton
 run-java-skeleton:
@@ -63,7 +80,8 @@ run-java-skeleton:
 PHONY += run-java-stub
 run-java-stub:
 #	cd ../bin/iotpolicy/output_files/Java; $(JAVA) -cp .:../../../$(BIN_DIR) TestClass_Stub
-	cd ../bin/iotpolicy/output_files/Java; $(JAVA) -cp .:../../../$(BIN_DIR) TestClassAdvanced_Stub
+#	cd ../bin/iotpolicy/output_files/Java; $(JAVA) -cp .:../../../$(BIN_DIR) TestClassAdvanced_Stub
+	cd ../bin/iotpolicy/output_files/Java; $(JAVA) -cp .:../../../$(BIN_DIR) TestClassCallbacks_Stub
 
 PHONY += run-cplus-skeleton
 run-cplus-skeleton:
@@ -72,7 +90,8 @@ run-cplus-skeleton:
 PHONY += run-cplus-stub
 run-cplus-stub:
 #	../bin/iotpolicy/output_files/Cplus/TestClass_Stub.out
-	../bin/iotpolicy/output_files/Cplus/TestClassAdvanced_Stub.out
+#	../bin/iotpolicy/output_files/Cplus/TestClassAdvanced_Stub.out
+	../bin/iotpolicy/output_files/Cplus/TestClassCallbacks_Stub.out
 
 PHONY += folderclean
 folderclean:
diff --git a/iotjava/iotpolicy/IoTCompiler.java b/iotjava/iotpolicy/IoTCompiler.java
index 4cd5418..66287f9 100644
--- a/iotjava/iotpolicy/IoTCompiler.java
+++ b/iotjava/iotpolicy/IoTCompiler.java
@@ -48,6 +48,7 @@ public class IoTCompiler {
 	private Map<String,ParseTreeHandler> mapIntfacePTH;
 	private Map<String,DeclarationHandler> mapIntDeclHand;
 	private Map<String,Map<String,Set<String>>> mapInt2NewInts;
+	private Map<String,String> mapInt2NewIntName;
 	// Data structure to store our types (primitives and non-primitives) for compilation
 	private Map<String,String> mapPrimitives;
 	private Map<String,String> mapNonPrimitivesJava;
@@ -58,6 +59,8 @@ public class IoTCompiler {
 	private PrintWriter pw;
 	private String dir;
 	private String subdir;
+	private Map<String,Integer> mapPortCount;	// Counter for ports
+	private static int portCount = 0;
 
 
 	/**
@@ -83,6 +86,7 @@ public class IoTCompiler {
 		mapIntfacePTH = new HashMap<String,ParseTreeHandler>();
 		mapIntDeclHand = new HashMap<String,DeclarationHandler>();
 		mapInt2NewInts = new HashMap<String,Map<String,Set<String>>>();
+		mapInt2NewIntName = new HashMap<String,String>();
 		mapIntfaceObjId = new HashMap<String,Integer>();
 		mapNewIntfaceObjId = new HashMap<String,Integer>();
 		mapPrimitives = new HashMap<String,String>();
@@ -91,6 +95,7 @@ public class IoTCompiler {
 			arraysToMap(mapNonPrimitivesJava, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitiveJavaLibs);
 		mapNonPrimitivesCplus = new HashMap<String,String>();
 			arraysToMap(mapNonPrimitivesCplus, IoTRMITypes.nonPrimitivesJava, IoTRMITypes.nonPrimitivesCplus);
+		mapPortCount = new HashMap<String,Integer>();
 		pw = null;
 		dir = OUTPUT_DIRECTORY;
 		subdir = null;
@@ -177,6 +182,9 @@ public class IoTCompiler {
 			}
 			// Add interface and methods information into map
 			mapNewIntMethods.put(strInt, setMethods);
+			// Map new interface method name to the original interface
+			// TODO: perhaps need to check in the future if we have more than 1 stub interface for one original interface
+			mapInt2NewIntName.put(origInt, strInt);
 		}
 		// Map the map of interface-methods to the original interface
 		mapInt2NewInts.put(origInt, mapNewIntMethods);
@@ -476,8 +484,11 @@ public class IoTCompiler {
 		if (callbackExist) {
 			Iterator it = callbackClasses.iterator();
 			String callbackType = (String) it.next();
-			writeConstructorJavaPermission(intface);
+			writeConstructorJavaPermission(callbackType);
 			println("listCallbackObj = new ArrayList<" + callbackType + ">();");
+			DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
+			InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
+			writeJavaInitCallbackPermission(callbackType, intDecl, callbackExist);
 			println("___initCallBack();");
 		}
 		println("}\n");
@@ -520,26 +531,35 @@ public class IoTCompiler {
 	}
 
 
+	/**
+	 * HELPER: getPortCount() gets port count for different stubs and skeletons
+	 */
+	private int getPortCount(String intface) {
+
+		if (!mapPortCount.containsKey(intface))
+			mapPortCount.put(intface, portCount++);
+		return mapPortCount.get(intface);
+	}
+
+
 	/**
 	 * HELPER: writeInitCallbackJavaStub() writes callback initialization in stub
 	 */
-	private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl, boolean isGenCallbackStub) {
+	private void writeInitCallbackJavaStub(String intface, InterfaceDecl intDecl, String newStubClass) {
 
 		println("public void ___initCallBack() {");
 		// Generate main thread for callbacks
 		println("Thread thread = new Thread() {");
 		println("public void run() {");
 		println("try {");
-		if (isGenCallbackStub)	// Use the second port for a _CallbackStub class (callback in callback)
-			println("rmiObj = new IoTRMIObject(ports[1]);");
-		else
-			println("rmiObj = new IoTRMIObject(ports[0]);");
+		int port = getPortCount(newStubClass);
+		println("rmiObj = new IoTRMIObject(ports[" + port + "]);");
 		println("while (true) {");
 		println("byte[] method = rmiObj.getMethodBytes();");
-		writeJavaMethodCallbackPermission(intface);
 		println("int objId = IoTRMIObject.getObjectId(method);");
 		println(intface + "_CallbackSkeleton skel = (" + intface + "_CallbackSkeleton) listCallbackObj.get(objId);");
 		println("if (skel != null) {");
+		writeJavaMethodCallbackPermission(intface);
 		println("skel.invokeMethod(rmiObj);");
 		print("}");
 		println(" else {");
@@ -1017,7 +1037,7 @@ public class IoTCompiler {
 	/**
 	 * HELPER: writeMethodJavaStub() writes the methods of the stub class
 	 */
-	private void writeMethodJavaStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, boolean isGenCallbackStub) {
+	private void writeMethodJavaStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, String newStubClass) {
 
 		boolean isDefined = false;
 		for (String method : methods) {
@@ -1052,13 +1072,22 @@ public class IoTCompiler {
 			println("}\n");
 			// Write the init callback helper method
 			if (isCallbackMethod && !isDefined) {
-				writeInitCallbackJavaStub(callbackType, intDecl, isGenCallbackStub);
+				writeInitCallbackJavaStub(callbackType, intDecl, newStubClass);
 				isDefined = true;
 			}
 		}
 	}
 
 
+	/**
+	 * HELPER: getStubInterface() gets stub interface name based on original interface
+	 */
+	public String getStubInterface(String intface) {
+
+		return mapInt2NewIntName.get(intface);
+	}
+
+
 	/**
 	 * generateJavaStubClasses() generate stubs based on the methods list in Java
 	 */
@@ -1094,7 +1123,7 @@ public class IoTCompiler {
 				// Write constructor
 				writeConstructorJavaStub(intface, newStubClass, callbackExist, callbackClasses);
 				// Write methods
-				writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, false);
+				writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, newStubClass);
 				println("}");
 				pw.close();
 				System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".java...");
@@ -1144,8 +1173,11 @@ public class IoTCompiler {
 		if (callbackExist) {
 			Iterator it = callbackClasses.iterator();
 			String callbackType = (String) it.next();
-			writeConstructorJavaPermission(intface);
+			writeConstructorJavaPermission(callbackType);
 			println("listCallbackObj = new ArrayList<" + callbackType + ">();");
+			DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
+			InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
+			writeJavaInitCallbackPermission(callbackType, intDecl, callbackExist);
 			println("___initCallBack();");
 		}
 		println("}\n");
@@ -1192,7 +1224,7 @@ public class IoTCompiler {
 				writeConstructorJavaCallbackStub(intface, newStubClass, callbackExist, callbackClasses);
 				// Write methods
 				// TODO: perhaps need to generate callback for callback
-				writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, true);
+				writeMethodJavaStub(intMeth.getValue(), intDecl, callbackClasses, newStubClass);
 				println("}");
 				pw.close();
 				System.out.println("IoTCompiler: Generated callback stub class " + newStubClass + ".java...");
@@ -1294,7 +1326,7 @@ public class IoTCompiler {
 	/**
 	 * HELPER: writeInitCallbackJavaSkeleton() writes the init callback method for skeleton class
 	 */
-	private void writeInitCallbackJavaSkeleton(boolean callbackSkeleton) {
+	private void writeInitCallbackJavaSkeleton(boolean callbackSkeleton, String intface) {
 
 		// This is a callback skeleton generation
 		if (callbackSkeleton)
@@ -1304,10 +1336,13 @@ public class IoTCompiler {
 		print("Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int[].class, String.class, int.class },");
 		println("new Class<?>[] { null, null, null });");
 		println("ports = (int[]) paramObj[0];");
-		if (callbackSkeleton)	// If this is a callback skeleton then use the other port
-			println("rmiCall = new IoTRMICall((int) paramObj[0], (String) paramObj[1], ports[1]);");
+		String stubInt = null;
+		if (callbackSkeleton)
+			stubInt = getStubInterface(intface) + "_CallbackStub";
 		else
-			println("rmiCall = new IoTRMICall((int) paramObj[0], (String) paramObj[1], ports[0]);");
+			stubInt = getStubInterface(intface) + "_Stub";
+		int port = getPortCount(stubInt);
+		println("rmiCall = new IoTRMICall(ports[" + port + "], (String) paramObj[1], (int) paramObj[2]);");
 		println("}\n");
 	}
 
@@ -1316,7 +1351,7 @@ public class IoTCompiler {
 	 * HELPER: writeMethodJavaSkeleton() writes the method of the skeleton class
 	 */
 	private void writeMethodJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, 
-			boolean callbackSkeleton) {
+			boolean callbackSkeleton, String intface) {
 
 		boolean isDefined = false;
 		for (String method : methods) {
@@ -1346,7 +1381,7 @@ public class IoTCompiler {
 			writeStdMethodBodyJavaSkeleton(methParams, methodId, intDecl.getMethodType(method));
 			println("}\n");
 			if (isCallbackMethod && !isDefined) {	// Make sure that this function is only defined once!
-				writeInitCallbackJavaSkeleton(callbackSkeleton);
+				writeInitCallbackJavaSkeleton(callbackSkeleton, intface);
 				isDefined = true;
 			}
 		}
@@ -1391,7 +1426,7 @@ public class IoTCompiler {
 					println("}");
 				} else if (isList(paramType)) {
 					println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
-					println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, objIdCnt, ports));");
+					println("stub" + i + ".add(new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports));");
 					println("objIdCnt++;");
 					println("}");
 				}
@@ -2167,7 +2202,7 @@ public class IoTCompiler {
 			// Write constructor
 			writeConstructorJavaSkeleton(newSkelClass, intface, intDecl, methods, callbackExist);
 			// Write methods
-			writeMethodJavaSkeleton(methods, intDecl, callbackClasses, false);
+			writeMethodJavaSkeleton(methods, intDecl, callbackClasses, false, intface);
 			// Write method helper
 			writeMethodHelperJavaSkeleton(methods, intDecl, callbackClasses);
 			// Write waitRequestInvokeMethod() - main loop
@@ -2353,7 +2388,7 @@ public class IoTCompiler {
 			// Write constructor
 			writeConstructorJavaCallbackSkeleton(newSkelClass, intface, intDecl, methods);
 			// Write methods
-			writeMethodJavaSkeleton(methods, intDecl, callbackClasses, true);
+			writeMethodJavaSkeleton(methods, intDecl, callbackClasses, true, intface);
 			// Write method helper
 			writeMethodHelperJavaCallbackSkeleton(methods, intDecl, callbackClasses);
 			// Write waitRequestInvokeMethod() - main loop
@@ -2594,7 +2629,7 @@ public class IoTCompiler {
 	/**
 	 * HELPER: writeMethodCplusStub() writes the methods of the stub
 	 */
-	private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, boolean isGenCallbackStub) {
+	private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, String newStubClass) {
 
 		boolean isDefined = false;
 		for (String method : methods) {
@@ -2629,7 +2664,7 @@ public class IoTCompiler {
 			println("}\n");
 			// Write the init callback helper method
 			if (isCallbackMethod && !isDefined) {
-				writeInitCallbackCplusStub(callbackType, intDecl, isGenCallbackStub);
+				writeInitCallbackCplusStub(callbackType, intDecl, newStubClass);
 				writeInitCallbackSendInfoCplusStub(intDecl);
 				isDefined = true;
 			}
@@ -3040,8 +3075,6 @@ public class IoTCompiler {
 		// Get the object Id
 		Integer objId = mapIntfaceObjId.get(intface);
 		println("const static int objectId = " + objId + ";");
-		//mapNewIntfaceObjId.put(newIntface, objId);
-		//mapIntfaceObjId.put(intface, objId++);
 		if (callbackExist) {
 		// We assume that each class only has one callback interface for now
 			Iterator it = callbackClasses.iterator();
@@ -3063,13 +3096,16 @@ public class IoTCompiler {
 	private void writeConstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
 
 		println(newStubClass + 
-			"(int _port, const char* _skeletonAddress, const char* _callbackAddress, int _rev, bool* _bResult, vector<int> _ports) {");
+			"(int _port, const char* _skeletonAddress, string _callbackAddress, int _rev, bool* _bResult, vector<int> _ports) {");
 		println("callbackAddress = _callbackAddress;");
 		println("ports = _ports;");
 		println("rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev, _bResult);");
 		if (callbackExist) {
 			Iterator it = callbackClasses.iterator();
 			String callbackType = (String) it.next();
+			DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
+			InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
+			writeCplusInitCallbackPermission(callbackType, intDecl, callbackExist);
 			println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
 			println("th1.detach();");
 			println("___regCB();");
@@ -3128,21 +3164,20 @@ public class IoTCompiler {
 	/**
 	 * HELPER: writeInitCallbackCplusStub() writes the initialization of callback
 	 */
-	private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl, boolean isGenCallbackStub) {
+	private void writeInitCallbackCplusStub(String intface, InterfaceDecl intDecl, String newStubClass) {
 
 		println("void ___initCallBack() {");
 		println("bool bResult = false;");
-		if (isGenCallbackStub)  // Use the second port for a _CallbackStub class (callback in callback)
-			println("rmiObj = new IoTRMIObject(ports[1], &bResult);");
-		else
-			println("rmiObj = new IoTRMIObject(ports[0], &bResult);");
+		int port = getPortCount(newStubClass);
+		println("rmiObj = new IoTRMIObject(ports[" + port + "], &bResult);");
 		println("while (true) {");
 		println("char* method = rmiObj->getMethodBytes();");
-		writeCplusMethodCallbackPermission(intface);
+		//writeCplusMethodCallbackPermission(intface);
 		println("int objId = IoTRMIObject::getObjectId(method);");
 		println("if (objId < vecCallbackObj.size()) {	// Check if still within range");
 		println(intface + "_CallbackSkeleton* skel = dynamic_cast<" + intface + 
 			"_CallbackSkeleton*> (vecCallbackObj.at(objId));");
+		writeCplusMethodCallbackPermission(intface);
 		println("skel->invokeMethod(rmiObj);");
 		print("}");
 		println(" else {");
@@ -3233,7 +3268,7 @@ public class IoTCompiler {
 				writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses);
 				writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
 				// Write methods
-				writeMethodCplusStub(methods, intDecl, callbackClasses, false);
+				writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass);
 				print("}"); println(";");
 				if (callbackExist) {
 					Iterator it = callbackClasses.iterator();
@@ -3260,6 +3295,8 @@ public class IoTCompiler {
 		println("IoTRMICall *rmiCall;");
 		// Get the object Id
 		println("int objectId;");
+		println("vector<int> ports;\n");
+		println("string callbackAddress;");
 		if (callbackExist) {
 		// We assume that each class only has one callback interface for now
 			Iterator it = callbackClasses.iterator();
@@ -3269,8 +3306,6 @@ public class IoTCompiler {
 			println("vector<" + callbackType + "*> vecCallbackObj;");
 			println("static int objIdCnt;");
 			// TODO: Need to initialize address and ports if we want to have callback-in-callback
-			println("string callbackAddress;");
-			println("vector<int> ports;\n");
 			writePropertiesCplusPermission(callbackType);
 		}
 		println("\n");
@@ -3282,13 +3317,17 @@ public class IoTCompiler {
 	 */
 	private void writeConstructorCplusCallbackStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
 
-		println(newStubClass + "(IoTRMICall* _rmiCall, int _objectId, vector<int> _ports) {");
+		println(newStubClass + "(IoTRMICall* _rmiCall, string _callbackAddress, int _objectId, vector<int> _ports) {");
 		println("objectId = _objectId;");
+		println("callbackAddress = _callbackAddress;");
 		println("rmiCall = _rmiCall;");
 		println("ports = _ports;");
 		if (callbackExist) {
 			Iterator it = callbackClasses.iterator();
 			String callbackType = (String) it.next();
+			DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
+			InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
+			writeCplusInitCallbackPermission(callbackType, intDecl, callbackExist);
 			println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
 			println("th1.detach();");
 			println("___regCB();");
@@ -3336,7 +3375,7 @@ public class IoTCompiler {
 				writeConstructorCplusCallbackStub(newStubClass, callbackExist, callbackClasses);
 				writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
 				// Write methods
-				writeMethodCplusStub(methods, intDecl, callbackClasses, true);
+				writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass);
 				println("};");
 				if (callbackExist) {
 					Iterator it = callbackClasses.iterator();
@@ -3361,6 +3400,8 @@ public class IoTCompiler {
 	private void writePropertiesCplusSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
 
 		println(intface + " *mainObj;");
+		println("vector<int> ports;");
+		println("string callbackAddress;");
 		// Callback
 		if (callbackExist) {
 			Iterator it = callbackClasses.iterator();
@@ -3370,7 +3411,6 @@ public class IoTCompiler {
 			println("static int objIdCnt;");
 			println("vector<" + exchangeType + "*> vecCallbackObj;");
 			println("IoTRMICall *rmiCall;");
-			println("vector<int> ports;");
 		}
 		println("IoTRMIObject *rmiObj;\n");
 		// Keep track of object Ids of all stubs registered to this interface
@@ -3452,9 +3492,10 @@ public class IoTCompiler {
 	 */
 	private void writeConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist, InterfaceDecl intDecl, Collection<String> methods) {
 
-		println(newSkelClass + "(" + intface + " *_mainObj, int _port) {");
+		println(newSkelClass + "(" + intface + " *_mainObj, string _callbackAddress, int _port) {");
 		println("bool _bResult = false;");
 		println("mainObj = _mainObj;");
+		println("callbackAddress = _callbackAddress;");
 		println("rmiObj = new IoTRMIObject(_port, &_bResult);");
 		writeCplusInitCallbackPermission(intface, intDecl, callbackExist);
 		writeStructPermissionCplusSkeleton(methods, intDecl, intface);
@@ -3516,7 +3557,7 @@ public class IoTCompiler {
 	/**
 	 * HELPER: writeInitCallbackCplusSkeleton() writes the init callback method for skeleton class
 	 */
-	private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton) {
+	private void writeInitCallbackCplusSkeleton(boolean callbackSkeleton, String intface) {
 
 		// This is a callback skeleton generation
 		if (callbackSkeleton)
@@ -3531,10 +3572,13 @@ public class IoTCompiler {
 		println("void* paramObj[] = { &param1, &param2, &param3 };");
 		println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
 		println("bool bResult = false;");
+		String stubInt = null;
 		if (callbackSkeleton)
-			println("rmiCall = new IoTRMICall(param1[1], param2.c_str(), param3, &bResult);");
+			stubInt = getStubInterface(intface) + "_CallbackStub";
 		else
-			println("rmiCall = new IoTRMICall(param1[0], param2.c_str(), param3, &bResult);");
+			stubInt = getStubInterface(intface) + "_Stub";
+		int port = getPortCount(stubInt);
+		println("rmiCall = new IoTRMICall(param1[" + port + "], param2.c_str(), param3, &bResult);");
 		println("}\n");
 	}
 
@@ -3543,7 +3587,7 @@ public class IoTCompiler {
 	 * HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
 	 */
 	private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, 
-			Set<String> callbackClasses, boolean callbackSkeleton) {
+			Set<String> callbackClasses, boolean callbackSkeleton, String intface) {
 
 		boolean isDefined = false;
 		for (String method : methods) {
@@ -3576,7 +3620,7 @@ public class IoTCompiler {
 			writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method));
 			println("}\n");
 			if (isCallbackMethod && !isDefined) {
-				writeInitCallbackCplusSkeleton(callbackSkeleton);
+				writeInitCallbackCplusSkeleton(callbackSkeleton, intface);
 				isDefined = true;
 			}
 		}
@@ -4236,7 +4280,7 @@ public class IoTCompiler {
 			// Write deconstructor
 			writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
 			// Write methods
-			writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false);
+			writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false, intface);
 			// Write method helper
 			writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses);
 			// Write waitRequestInvokeMethod() - main loop
@@ -4259,6 +4303,8 @@ public class IoTCompiler {
 		println(intface + " *mainObj;");
 		// Keep track of object Ids of all stubs registered to this interface
 		println("int objectId;");
+		println("vector<int> ports;\n");
+		println("string callbackAddress;");
 		// Callback
 		if (callbackExist) {
 			Iterator it = callbackClasses.iterator();
@@ -4268,7 +4314,6 @@ public class IoTCompiler {
 			println("IoTRMICall* rmiCall;");
 			println("vector<" + exchangeType + "*> vecCallbackObj;");
 			println("static int objIdCnt;");
-			println("vector<int> ports;\n");
 		}
 		println("\n");
 	}
@@ -4279,8 +4324,9 @@ public class IoTCompiler {
 	 */
 	private void writeConstructorCplusCallbackSkeleton(String newSkelClass, String intface, boolean callbackExist, InterfaceDecl intDecl, Collection<String> methods) {
 
-		println(newSkelClass + "(" + intface + " *_mainObj, int _objectId) {");
+		println(newSkelClass + "(" + intface + " *_mainObj, string _callbackAddress, int _objectId) {");
 		println("mainObj = _mainObj;");
+		println("callbackAddress = _callbackAddress;");
 		println("objectId = _objectId;");
 		println("}\n");
 	}
@@ -4458,7 +4504,7 @@ public class IoTCompiler {
 			// Write deconstructor
 			writeDeconstructorCplusCallbackSkeleton(newSkelClass, callbackExist, callbackClasses);
 			// Write methods
-			writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true);
+			writeMethodCplusSkeleton(methods, intDecl, callbackClasses, true, intface);
 			// Write method helper
 			writeMethodHelperCplusCallbackSkeleton(methods, intDecl, callbackClasses);
 			// Write waitRequestInvokeMethod() - main loop
diff --git a/iotjava/iotrmi/C++/basics/CallBack.hpp b/iotjava/iotrmi/C++/basics/CallBack.hpp
index 834f2a8..a6e94c3 100644
--- a/iotjava/iotrmi/C++/basics/CallBack.hpp
+++ b/iotjava/iotrmi/C++/basics/CallBack.hpp
@@ -3,6 +3,7 @@
 
 #include <iostream>
 #include "CallBackInterface.hpp"
+#include "TestClassComplete.hpp"
 
 using namespace std;
 
@@ -12,6 +13,7 @@ class CallBack : public CallBackInterface {
 
 		int		printInt();
 		void	setInt(int _i);
+		void	needCallback(TestClassComplete* tc);
 
 	private:		
 		int		intA;
@@ -37,5 +39,10 @@ void CallBack::setInt(int _i) {
 	intA = _i;
 }
 
+void CallBack::needCallback(TestClassComplete* tc) {
+
+	cout << "Short from TestClass: " << tc->getShort(1234);
+}
+
 #endif
 
diff --git a/iotjava/iotrmi/C++/basics/TestClass.hpp b/iotjava/iotrmi/C++/basics/TestClass.hpp
index 573ff64..cc6c854 100644
--- a/iotjava/iotrmi/C++/basics/TestClass.hpp
+++ b/iotjava/iotrmi/C++/basics/TestClass.hpp
@@ -6,6 +6,8 @@
 #include <chrono>
 #include "TestClassInterface.hpp"
 #include "CallBackInterfaceWithCallBack.hpp"
+#include "Enum.hpp"
+#include "Struct.hpp"
 
 using namespace std;
 
@@ -144,6 +146,7 @@ int TestClass::callBack() {
 
 	int sum = 0;
 	for (CallBackInterfaceWithCallBack* cb : cbvec) {
+		cb->needCallback(this);
 		sum = sum + cb->printInt();
 	}
 
diff --git a/iotjava/iotrmi/C++/basics/TestClassAdvanced_Stub.cpp b/iotjava/iotrmi/C++/basics/TestClassAdvanced_Stub.cpp
index 2b8069f..069c35f 100644
--- a/iotjava/iotrmi/C++/basics/TestClassAdvanced_Stub.cpp
+++ b/iotjava/iotrmi/C++/basics/TestClassAdvanced_Stub.cpp
@@ -12,16 +12,17 @@ int main(int argc, char *argv[])
 	const char* address = "localhost";
 	//const char* address = "192.168.2.191";	// RPi2
 	//const char* skeletonAddress = "128.195.136.170";	// dc-9.calit2.uci.edu
-	//const char* callbackAddress = "128.195.204.132";	// dw-2.eecs.uci.edu (this machine)
-	const char* skeletonAddress = "192.168.2.108";	// RPi1
-	const char* callbackAddress = "192.168.2.191";	// RPi2
+	const char* skeletonAddress = "128.195.204.132";
+	const char* callbackAddress = "128.195.204.132";	// dw-2.eecs.uci.edu (this machine)
+	//const char* skeletonAddress = "192.168.2.108";	// RPi1
+	//const char* callbackAddress = "192.168.2.191";	// RPi2
 	int rev = 0;
 	bool bResult = false;
 	vector<int> ports;
 	ports.push_back(12345);
 
 	TestClassComplete *tcStub = new TestClassComplete_Stub(port, skeletonAddress, callbackAddress, rev, &bResult, ports);
-	cout << "==== ENUM ====" << endl;
+	/*cout << "==== ENUM ====" << endl;
 	Enum en;
 	en = APPLE;
 	Enum res = tcStub->handleEnum(en);
@@ -52,14 +53,14 @@ int main(int argc, char *argv[])
 	str.name = "Rahmadi";
 	str.value = 0.123;
 	str.year = 2016;
-/*	Struct resStr = tcStub->handleStruct(str);
+	Struct resStr = tcStub->handleStruct(str);
 	cout << "Name: " << resStr.name << endl;
 	cout << "Value:" << resStr.value << endl;
 	cout << "Year" << resStr.year << endl;
 	Struct resStr2 = tcStub->handleStructComplex(23, 'c', str);
 	cout << "Name: " << resStr2.name << endl;
 	cout << "Value:" << resStr2.value << endl;
-	cout << "Year" << resStr2.year << endl;*/
+	cout << "Year" << resStr2.year << endl;
 	Struct str2;
 	str2.name = "Trimananda";
 	str2.value = 0.124;
@@ -67,7 +68,7 @@ int main(int argc, char *argv[])
 	vector<Struct> vecStr;
 	vecStr.push_back(str);
 	vecStr.push_back(str2);
-/*	vector<Struct> vecRetStr = tcStub->handleStructArray(vecStr);
+	vector<Struct> vecRetStr = tcStub->handleStructArray(vecStr);
 	for (Struct st : vecRetStr) {
 		cout << "Name: " << st.name << endl;
 		cout << "Value: " << st.value << endl;
@@ -90,11 +91,11 @@ int main(int argc, char *argv[])
 		cout << "Enum value: " << en << endl;
 	}*/
 
-/*	cout << "==== CALLBACK ====" << endl;
+	cout << "==== CALLBACK ====" << endl;
 	CallBackInterface *cbSingle = new CallBack(2354);
 	tcStub->registerCallback(cbSingle);
 	cout << "Return value from callback: " << tcStub->callBack() << endl;
-	CallBackInterface *cb1 = new CallBack(23);
+	/*CallBackInterface *cb1 = new CallBack(23);
 	CallBackInterface *cb2 = new CallBack(33);
 	CallBackInterface *cb3 = new CallBack(43);
 	vector<CallBackInterface*> cb;
@@ -103,13 +104,13 @@ int main(int argc, char *argv[])
 	cb.push_back(cb3);
 	tcStub->registerCallbackArray(cb);
 	cout << "Return value from callback: " << tcStub->callBack() << endl;*/
-	CallBackInterface *cb4 = new CallBack(53);
+	/*CallBackInterface *cb4 = new CallBack(53);
 	CallBackInterface *cb5 = new CallBack(63);
 	CallBackInterface *cb6 = new CallBack(73);
 	vector<CallBackInterface*> cblist;
 	cblist.push_back(cb4);
 	cblist.push_back(cb5);
-	cblist.push_back(cb6);
+	cblist.push_back(cb6);*/
 //	tcStub->registerCallbackList(cblist);
 //	cout << "Return value from callback: " << tcStub->callBack() << endl;
 /*	tcStub->registerCallbackComplex(23, cblist, 0.1234);
@@ -141,13 +142,13 @@ int main(int argc, char *argv[])
 		cout << "Name: " << st.name << endl;
 		cout << "Value: " << st.value << endl;
 		cout << "Year: " << st.year << endl;
-	}*/
+	}
 	vector<Struct> vecRetStr3 = tcStub->handleStructThree(vecStr, vecStr, vecStr);
 	for (Struct st : vecRetStr3) {
 		cout << "Name: " << st.name << endl;
 		cout << "Value: " << st.value << endl;
 		cout << "Year: " << st.year << endl;
-	}
+	}*/
 
 	return 0;
 }
diff --git a/iotjava/iotrmi/C++/basics/TestClassCallbacks_Stub.cpp b/iotjava/iotrmi/C++/basics/TestClassCallbacks_Stub.cpp
new file mode 100644
index 0000000..f8fa236
--- /dev/null
+++ b/iotjava/iotrmi/C++/basics/TestClassCallbacks_Stub.cpp
@@ -0,0 +1,34 @@
+#include <iostream>
+#include <string>
+#include "TestClassComplete_Stub.hpp"
+#include "CallBack.hpp"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+
+	int port = 5010;
+	const char* address = "localhost";
+	//const char* address = "192.168.2.191";	// RPi2
+	//const char* skeletonAddress = "128.195.136.170";	// dc-9.calit2.uci.edu
+	const char* skeletonAddress = "128.195.204.132";
+	const char* callbackAddress = "128.195.204.132";	// dw-2.eecs.uci.edu (this machine)
+	//const char* skeletonAddress = "192.168.2.108";	// RPi1
+	//const char* callbackAddress = "192.168.2.191";	// RPi2
+	int rev = 0;
+	bool bResult = false;
+	vector<int> ports;
+	ports.push_back(12345);
+	ports.push_back(22346);
+	ports.push_back(32344);
+	ports.push_back(43212);
+
+	TestClassComplete *tcStub = new TestClassComplete_Stub(port, skeletonAddress, callbackAddress, rev, &bResult, ports);
+	cout << "==== CALLBACK ====" << endl;
+	CallBackInterface *cbSingle = new CallBack(2354);
+	tcStub->registerCallback(cbSingle);
+	cout << "Return value from callback: " << tcStub->callBack() << endl;
+
+	return 0;
+}
diff --git a/iotjava/iotrmi/C++/basics/TestClass_Skeleton.cpp b/iotjava/iotrmi/C++/basics/TestClass_Skeleton.cpp
index cea5030..5da9229 100644
--- a/iotjava/iotrmi/C++/basics/TestClass_Skeleton.cpp
+++ b/iotjava/iotrmi/C++/basics/TestClass_Skeleton.cpp
@@ -12,7 +12,8 @@ int main(int argc, char *argv[])
 
 	int port = 5010;
 	tc = new TestClass(3, 5.0, "7911");
-	tcSkel = new TestClassInterface_Skeleton(tc, port);
+	string callbackAddress = "128.195.204.132";
+	tcSkel = new TestClassInterface_Skeleton(tc, callbackAddress, port);
 
 	delete tc;
 	delete tcSkel;
diff --git a/iotjava/iotrmi/Java/IoTRMICall.java b/iotjava/iotrmi/Java/IoTRMICall.java
index 9211954..06753be 100644
--- a/iotjava/iotrmi/Java/IoTRMICall.java
+++ b/iotjava/iotrmi/Java/IoTRMICall.java
@@ -52,8 +52,10 @@ public class IoTRMICall {
 
 		// Send method info
 		byte[] methodBytes = methodToBytes(objectId, methodId, paramCls, paramObj);
+		//System.out.println("Method RMICall: " + Arrays.toString(methodBytes));
 		try {
 			rmiClient.sendBytes(methodBytes);
+			//System.out.println("Sent bytes RMICall!!!");
 		} catch (IOException ex) {
 			ex.printStackTrace();
 			throw new Error("IoTRMICall: Error when sending bytes - rmiClient.sendBytes()");
diff --git a/iotjava/iotrmi/Java/IoTRMIObject.java b/iotjava/iotrmi/Java/IoTRMIObject.java
index 3f0c19c..e88e639 100644
--- a/iotjava/iotrmi/Java/IoTRMIObject.java
+++ b/iotjava/iotrmi/Java/IoTRMIObject.java
@@ -10,6 +10,9 @@ import java.util.Map;
 import java.util.Set;
 import java.lang.reflect.*;
 
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
 
 /** Class IoTRMIObject is a class that stores info of an object.
  *  <p>
@@ -32,6 +35,7 @@ public class IoTRMIObject {
 	private IoTRMIUtil rmiUtil;
 	private IoTSocketServer rmiServer;
 	private byte[] methodBytes;
+	private Lock lock = new ReentrantLock();
 
 
 	/**
@@ -54,7 +58,9 @@ public class IoTRMIObject {
 	public byte[] getMethodBytes() throws IOException {
 
 		// Receive method info
+		//System.out.println("Method RMIObj before: " + Arrays.toString(methodBytes));
 		methodBytes = rmiServer.receiveBytes(methodBytes);
+		//System.out.println("Method RMIObj after: " + Arrays.toString(methodBytes));
 		return methodBytes;
 	}
 
diff --git a/iotjava/iotrmi/Java/basics/CallBack.java b/iotjava/iotrmi/Java/basics/CallBack.java
index 83969af..b64b1ae 100644
--- a/iotjava/iotrmi/Java/basics/CallBack.java
+++ b/iotjava/iotrmi/Java/basics/CallBack.java
@@ -26,4 +26,10 @@ public class CallBack implements CallBackInterface {
 
 		intA = _i;
 	}
+	
+	
+	public void needCallback(TestClassComplete tc) {
+
+		System.out.println("Short from TestClass: " + tc.getShort((short)1234));
+	}
 }
diff --git a/iotjava/iotrmi/Java/basics/TestClass.java b/iotjava/iotrmi/Java/basics/TestClass.java
index 1bfe8e2..1248004 100644
--- a/iotjava/iotrmi/Java/basics/TestClass.java
+++ b/iotjava/iotrmi/Java/basics/TestClass.java
@@ -74,10 +74,12 @@ public class TestClass implements TestClassInterface {
 
 
 	public int callBack() {
-
+		
 		int sum = 0;
+		System.out.println("Callback called!");
 		for (CallBackInterfaceWithCallBack cb : cblist) {
 			sum = sum + cb.printInt();
+			cb.needCallback(this);
 		}
 		return sum;
 	}
diff --git a/iotjava/iotrmi/Java/basics/TestClassAdvanced_Stub.java b/iotjava/iotrmi/Java/basics/TestClassAdvanced_Stub.java
index 84f8c6e..6fc89b5 100644
--- a/iotjava/iotrmi/Java/basics/TestClassAdvanced_Stub.java
+++ b/iotjava/iotrmi/Java/basics/TestClassAdvanced_Stub.java
@@ -15,13 +15,14 @@ public class TestClassAdvanced_Stub {
 		//String address = "localhost";
 		//String address = "192.168.2.191";	// RPi2
 		//String skeletonAddress = "128.195.136.170";	// dc-9.calit2.uci.edu
-		//String callbackAddress = "128.195.204.132";	// dw-2.eecs.uci.edu (this machine)
-		String skeletonAddress = "192.168.2.108";	// RPi1
-		String callbackAddress = "192.168.2.191";	// RPi2
+		String skeletonAddress = "128.195.204.132";
+		String callbackAddress = "128.195.204.132";	// dw-2.eecs.uci.edu (this machine)
+		//String skeletonAddress = "192.168.2.108";	// RPi1
+		//String callbackAddress = "192.168.2.191";	// RPi2
 		int rev = 0;
 
 		TestClassComplete_Stub tcstub = new TestClassComplete_Stub(port, skeletonAddress, callbackAddress, rev, ports);
-		System.out.println("==== ENUM ====");
+		/*System.out.println("==== ENUM ====");
 		Enum en = Enum.APPLE;
 		Enum res = tcstub.handleEnum(en);
 		System.out.println("Enum member: " + res);
@@ -63,7 +64,7 @@ public class TestClassAdvanced_Stub {
 			System.out.println("Year: " + st.year);
 		}
 		List<Struct> stList = new ArrayList(Arrays.asList(arrStr));
-/*		List<Struct> stRetList = tcstub.handleStructList(stList);
+		List<Struct> stRetList = tcstub.handleStructList(stList);
 		for(Struct st : stRetList) {
 			System.out.println("Name: " + st.name);
 			System.out.println("Value: " + st.value);
@@ -78,16 +79,16 @@ public class TestClassAdvanced_Stub {
 		Enum[] resArr3 = tcstub.handleEnumStruct(enArr, stList, 'c');
 		System.out.println("Enum members: " + Arrays.toString(resArr3));*/
 
-/*		System.out.println("==== CALLBACKS ====");
+		System.out.println("==== CALLBACKS ====");
 		CallBackInterface cbSingle = new CallBack(2354);
 		tcstub.registerCallback(cbSingle);
 		System.out.println("Return value from callback: " + tcstub.callBack());
-		CallBackInterface cb1 = new CallBack(23);
+		/*CallBackInterface cb1 = new CallBack(23);
 		CallBackInterface cb2 = new CallBack(33);
 		CallBackInterface cb3 = new CallBack(43);
 		CallBackInterface[] cb = { cb1, cb2, cb3 };
 		tcstub.registerCallbackArray(cb);
-		System.out.println("Return value from callback: " + tcstub.callBack());*/
+		System.out.println("Return value from callback: " + tcstub.callBack());
 		List<CallBackInterface> cblist = new ArrayList<CallBackInterface>();
 		CallBackInterface cb4 = new CallBack(53); cblist.add(cb4);
 		CallBackInterface cb5 = new CallBack(63); cblist.add(cb5);
@@ -95,7 +96,7 @@ public class TestClassAdvanced_Stub {
 //		tcstub.registerCallbackList(cblist);
 //		System.out.println("Return value from callback: " + tcstub.callBack());
 
-/*		tcstub.registerCallbackComplex(23, cblist, 0.1234);
+		tcstub.registerCallbackComplex(23, cblist, 0.1234);
 		System.out.println("Return value from callback: " + tcstub.callBack());
 		Enum[] resArr4 = tcstub.handleAll(enArr, stList, 'c', cblist);
 		System.out.println("Enum members: " + Arrays.toString(resArr4));
@@ -114,12 +115,12 @@ public class TestClassAdvanced_Stub {
 			System.out.println("Name: " + st.name);
 			System.out.println("Value: " + st.value);
 			System.out.println("Year: " + st.year);
-		}*/
+		}
 		List<Struct> stRetList3 = tcstub.handleStructThree(stList, stList, stList);
 		for(Struct st : stRetList3) {
 			System.out.println("Name: " + st.name);
 			System.out.println("Value: " + st.value);
 			System.out.println("Year: " + st.year);
-		}
+		}*/
 	}
 }
diff --git a/iotjava/iotrmi/Java/basics/TestClassCallbacks_Stub.java b/iotjava/iotrmi/Java/basics/TestClassCallbacks_Stub.java
new file mode 100644
index 0000000..390ed8f
--- /dev/null
+++ b/iotjava/iotrmi/Java/basics/TestClassCallbacks_Stub.java
@@ -0,0 +1,31 @@
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import iotruntime.master.CommunicationHandler;
+
+public class TestClassCallbacks_Stub {
+
+	public static void main(String[] args) throws Exception {
+
+		CommunicationHandler comHan = new CommunicationHandler(true);
+		int numOfPorts = 4;
+		int[] ports = comHan.getCallbackPorts(numOfPorts);
+
+		int port = 5010;
+		//String address = "localhost";
+		//String address = "192.168.2.191";	// RPi2
+		//String skeletonAddress = "128.195.136.170";	// dc-9.calit2.uci.edu
+		String skeletonAddress = "128.195.204.132";
+		String callbackAddress = "128.195.204.132";	// dw-2.eecs.uci.edu (this machine)
+		//String skeletonAddress = "192.168.2.108";	// RPi1
+		//String callbackAddress = "192.168.2.191";	// RPi2
+		int rev = 0;
+
+		TestClassComplete_Stub tcstub = new TestClassComplete_Stub(port, skeletonAddress, callbackAddress, rev, ports);
+		System.out.println("==== CALLBACKS ====");
+		CallBackInterface cbSingle = new CallBack(2354);
+		tcstub.registerCallback(cbSingle);
+		System.out.println("Registered callback!");
+		System.out.println("Return value from callback: " + tcstub.callBack());
+	}
+}
diff --git a/iotjava/iotrmi/Java/basics/TestClass_Skeleton.java b/iotjava/iotrmi/Java/basics/TestClass_Skeleton.java
index a5b7360..37a4f99 100644
--- a/iotjava/iotrmi/Java/basics/TestClass_Skeleton.java
+++ b/iotjava/iotrmi/Java/basics/TestClass_Skeleton.java
@@ -1,11 +1,13 @@
+import java.net.InetAddress;
 
 public class TestClass_Skeleton {
 
 	public static void main(String[] args) throws Exception {
 
 		int port = 5010;
+		String callbackAddress = InetAddress.getLocalHost().getHostAddress();
 		TestClass tc = new TestClass(3, 5f, "7911");
-		TestClassInterface_Skeleton tcSkel = new TestClassInterface_Skeleton(tc, port);
+		TestClassInterface_Skeleton tcSkel = new TestClassInterface_Skeleton(tc, callbackAddress, port);
 
 	}
-}
+}
\ No newline at end of file
diff --git a/iotjava/iotruntime/master/CommunicationHandler.java b/iotjava/iotruntime/master/CommunicationHandler.java
index 104f3d9..db6b161 100644
--- a/iotjava/iotruntime/master/CommunicationHandler.java
+++ b/iotjava/iotruntime/master/CommunicationHandler.java
@@ -68,6 +68,7 @@ public final class CommunicationHandler {
 	private Map<Integer, Integer> hmRMIStubPort;
 	private Set<Integer> hsDevicePort;
 	private Set<Integer> hsCallbackPort;
+	private Map<Integer, Integer[]> hmCallbackPort;
 	private int iNumOfObjects;
 	private int iNumOfHosts;
 	private boolean bVerbose;
@@ -97,6 +98,7 @@ public final class CommunicationHandler {
 		hmRMIStubPort = new HashMap<Integer, Integer>();
 		hsDevicePort = new HashSet<Integer>();
 		hsCallbackPort = new HashSet<Integer>();
+		hmCallbackPort = new HashMap<Integer, Integer[]>();
 		iNumOfObjects = 0;
 		iNumOfHosts = 0;
 		bVerbose = _bVerbose;
@@ -207,6 +209,36 @@ public final class CommunicationHandler {
 	}
 
 
+	/**
+	 * Method getCallbackPorts()
+	 * <p>
+	 * Get a set of new ports for new connections for callback objects in the program.
+	 * This newly generated port number will be recorded.
+	 *
+	 * @return  int[]	A set of callback ports
+	 */
+	public Integer[] getCallbackPorts(String sAObject, int numOfPorts) {
+
+		Integer[] ports = new Integer[numOfPorts];
+		int iNumOfObject = hmActiveObj.get(sAObject);
+
+		if (!hmCallbackPort.containsKey(iNumOfObject)) {
+			for(int i = 0; i < numOfPorts; i++) {
+				do {
+					ports[i] = random.nextInt(INT_MAX_PORT - INT_MIN_PORT + 1) + INT_MIN_PORT;
+					// Check port existence in HashMap
+				} while (portIsAvailable(ports[i]) == false);
+				hsCallbackPort.add(ports[i]);
+			}
+			hmCallbackPort.put(iNumOfObject, ports);
+		} else {
+			ports = hmCallbackPort.get(iNumOfObject);
+		}
+
+		return ports;
+	}
+
+
 	/**
 	 * Method addDevicePort()
 	 * <p>
diff --git a/iotjava/iotruntime/master/IoTMaster.java b/iotjava/iotruntime/master/IoTMaster.java
index 7bd6ed8..7b86afc 100644
--- a/iotjava/iotruntime/master/IoTMaster.java
+++ b/iotjava/iotruntime/master/IoTMaster.java
@@ -83,6 +83,7 @@ public class IoTMaster {
 	private static String STR_ZB_GATEWAY_ADDRESS;
 	private static String STR_ZB_GATEWAY_PORT;
 	private static String STR_ZB_IOTMASTER_PORT;
+	private static String STR_NUM_CALLBACK_PORTS;
 	private static boolean BOOL_VERBOSE;
 
 	/**
@@ -154,6 +155,7 @@ public class IoTMaster {
 		STR_ZB_GATEWAY_ADDRESS = null;
 		STR_ZB_GATEWAY_PORT = null;
 		STR_ZB_IOTMASTER_PORT = null;
+		STR_NUM_CALLBACK_PORTS = null;
 		BOOL_VERBOSE = false;
 	}
 
@@ -208,6 +210,7 @@ public class IoTMaster {
 		STR_ZB_GATEWAY_ADDRESS = prop.getProperty("ZIGBEE_GATEWAY_ADDRESS");
 		STR_ZB_GATEWAY_PORT = prop.getProperty("ZIGBEE_GATEWAY_PORT");
 		STR_ZB_IOTMASTER_PORT = prop.getProperty("ZIGBEE_IOTMASTER_PORT");
+		STR_NUM_CALLBACK_PORTS = prop.getProperty("NUMBER_CALLBACK_PORTS");
 		if(prop.getProperty("VERBOSE").equals(STR_YES)) {
 			BOOL_VERBOSE = true;
 		}
@@ -227,6 +230,7 @@ public class IoTMaster {
 		RuntimeOutput.print("STR_ZB_GATEWAY_ADDRESS=" + STR_ZB_GATEWAY_ADDRESS, BOOL_VERBOSE);
 		RuntimeOutput.print("STR_ZB_GATEWAY_PORT=" + STR_ZB_GATEWAY_PORT, BOOL_VERBOSE);
 		RuntimeOutput.print("STR_ZB_IOTMASTER_PORT=" + STR_ZB_IOTMASTER_PORT, BOOL_VERBOSE);
+		RuntimeOutput.print("STR_NUM_CALLBACK_PORTS=" + STR_NUM_CALLBACK_PORTS, BOOL_VERBOSE);
 		RuntimeOutput.print("BOOL_VERBOSE=" + BOOL_VERBOSE, BOOL_VERBOSE);
 		RuntimeOutput.print("IoTMaster: Information extracted successfully!", BOOL_VERBOSE);
 	}
@@ -473,7 +477,7 @@ public class IoTMaster {
 		// Extract the interface name for RMI
 		// e.g. ProximitySensorInterface, TempSensorInterface, etc.
 		
-String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
+		String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassName + STR_CFG_FILE_EXT;
 		strObjClassInterfaceName = parseConfigFile(strObjCfgFile, STR_INTERFACE_CLS_CFG);
 		strObjStubClsIntfaceName = parseConfigFile(strObjCfgFile, STR_INT_STUB_CLS_CFG);
 		// Create an object name, e.g. ProximitySensorImplPS1
@@ -531,6 +535,33 @@ String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassNa
 			STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
 		routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
 			STR_TCP_PROTOCOL, commHan.getRMIStubPort(strObjName));
+		// Send the same set of routing policies for callback ports
+		setCallbackPortsPolicy(strObjName, STR_ROUTER_ADD, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd, STR_TCP_PROTOCOL);
+	}
+
+	/**
+	 * A private method to set router policies for callback ports
+	 *
+	 * @params  strRouterAdd       				String router address
+	 * @params  strIoTSlaveControllerHostAdd  	String slave controller host address
+	 * @params  strIoTSlaveObjectHostAdd  		String slave object host address
+	 * @params	strProtocol						String protocol
+	 * @return  iPort							Integer port number
+	 */
+	private void setCallbackPortsPolicy(String strObjName, String strRouterAdd, String strIoTSlaveControllerHostAdd, 
+		String strIoTSlaveObjectHostAdd, String strProtocol) {
+
+		int iNumCallbackPorts = Integer.parseInt(STR_NUM_CALLBACK_PORTS);
+		Integer[] rmiCallbackPorts = commHan.getCallbackPorts(strObjName, iNumCallbackPorts);
+		// Iterate over port numbers and set up policies
+		for (int i=0; i<iNumCallbackPorts; i++) {
+			routerConfig.configureRouterMainPolicies(strRouterAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
+				strProtocol, rmiCallbackPorts[i]);
+			routerConfig.configureHostMainPolicies(strIoTSlaveControllerHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
+				strProtocol, rmiCallbackPorts[i]);
+			routerConfig.configureHostMainPolicies(strIoTSlaveObjectHostAdd, strIoTSlaveControllerHostAdd, strIoTSlaveObjectHostAdd,
+				strProtocol, rmiCallbackPorts[i]);
+		}
 	}
 
 	/**
@@ -885,9 +916,10 @@ String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassNa
 			strObjClassName = setInstrumenter.fieldEntryType(strObjID);
 			// Call the method to create an object
 			instrumentObject(strObjID);
+			int iNumOfPorts = Integer.parseInt(STR_NUM_CALLBACK_PORTS);
 			objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
 				strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, commHan.getRMIRegPort(strObjName), 
-				commHan.getRMIStubPort(strObjName));
+				commHan.getRMIStubPort(strObjName), commHan.getCallbackPorts(strObjName, iNumOfPorts));
 		}
 	}
 
@@ -917,9 +949,11 @@ String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassNa
 			instrumentObject(strObjID);
 			// Get the first object controller host address
 			String strFirstIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
+			int iNumOfPorts = Integer.parseInt(STR_NUM_CALLBACK_PORTS);
 			objInitHand.addObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
 				strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, 
-				commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
+				commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName), 
+				commHan.getCallbackPorts(strObjName, iNumOfPorts));
 			// Operate on the second set
 			arrFieldClasses = relationInstrumenter.secondFieldClasses(iRow);
 			arrFieldValues = relationInstrumenter.secondFieldValues(iRow);
@@ -931,7 +965,8 @@ String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassNa
 			String strSecondIoTSlaveObjectHostAdd = strIoTSlaveObjectHostAdd;
 			objInitHand.addSecondObjectIntoField(strFieldName, strIoTSlaveObjectHostAdd, strObjName,
 				strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, 
-				commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName));
+				commHan.getRMIRegPort(strObjName), commHan.getRMIStubPort(strObjName),
+				commHan.getCallbackPorts(strObjName, iNumOfPorts));
 
 			// ROUTING POLICY: first and second controller objects in IoTRelation
 			routerConfig.configureRouterMainPolicies(STR_ROUTER_ADD, strFirstIoTSlaveObjectHostAdd,
@@ -967,8 +1002,8 @@ String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassNa
 					// == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTSET
 					commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTSET_OBJECT, objInitInfo.getIoTSlaveObjectHostAdd(),
 						objInitInfo.getObjectName(), objInitInfo.getObjectClassName(), objInitInfo.getObjectClassInterfaceName(), 
-						objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()), 
-						"Get IoTSet object!", inStream, outStream);	
+						objInitInfo.getObjectStubClassInterfaceName(), objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(),
+						objInitInfo.getRMICallbackPorts()), "Get IoTSet object!", inStream, outStream);	
 				}
 				// == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTSET FIELD
 				commMasterToSlave(new MessageSimple(IoTCommCode.REINITIALIZE_IOTSET_FIELD),
@@ -985,14 +1020,14 @@ String strObjCfgFile = STR_IOT_CODE_PATH + strObjClassName + "/" + strObjClassNa
 					commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_FIRST_OBJECT, 
 						objInitInfo.getIoTSlaveObjectHostAdd(), objInitInfo.getObjectName(), objInitInfo.getObjectClassName(),
 						objInitInfo.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
-						objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort()), 
+						objInitInfo.getRMIRegistryPort(), objInitInfo.getRMIStubPort(), objInitInfo.getRMICallbackPorts()), 
 						"Get IoTRelation first object!", inStream, outStream);
 					ObjectInitInfo objSecObj = (ObjectInitInfo) it.next();
 					// == COMMUNICATION WITH IOTSLAVE CONTROLLER TO FILL IN IOTRELATION (SECOND OBJECT)
 					commMasterToSlave(new MessageGetObject(IoTCommCode.GET_IOTRELATION_SECOND_OBJECT,
 						objSecObj.getIoTSlaveObjectHostAdd(), objSecObj.getObjectName(), objSecObj.getObjectClassName(),
 						objSecObj.getObjectClassInterfaceName(), objInitInfo.getObjectStubClassInterfaceName(),
-						objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort()), 
+						objSecObj.getRMIRegistryPort(), objSecObj.getRMIStubPort(), objSecObj.getRMICallbackPorts()), 
 						"Get IoTRelation second object!", inStream, outStream);
 				}
 				// == COMMUNICATION WITH IOTSLAVE CONTROLLER TO REINITIALIZE IOTRELATION FIELD
diff --git a/iotjava/iotruntime/master/ObjectInitHandler.java b/iotjava/iotruntime/master/ObjectInitHandler.java
index 27366b6..8234e8f 100644
--- a/iotjava/iotruntime/master/ObjectInitHandler.java
+++ b/iotjava/iotruntime/master/ObjectInitHandler.java
@@ -114,11 +114,12 @@ public final class ObjectInitHandler {
 	 * @param   strObjClassInterfaceName  	String object class interface
 	 * @param	iRMIRegPort					Integer RMI registry port
 	 * @param	iRMIStubPort				Integer RMI stub port
+	 * @param	iRMICallbackPorts			Integer RMI callback ports
 	 * @return  void
 	 */
 	public void addObjectIntoField(String strField, String strIoTSlaveObjectHostAdd,
 		String strObjName, String strObjClassName, String strObjClassInterfaceName,
-		String strObjStubClsIntfaceName, int iRMIRegPort, int iRMIStubPort) {
+		String strObjStubClsIntfaceName, int iRMIRegPort, int iRMIStubPort, Integer[] iRMICallbackPorts) {
 
 		// Get index of strField
 		int iFieldIndex = listField.indexOf(strField);
@@ -127,7 +128,7 @@ public final class ObjectInitHandler {
 		List<ObjectInitInfo> list = listFieldToObject.get(iFieldIndex);
 		// Create a new ObjectInitInfo for a new object in the field
 		ObjectInitInfo objInitInfo = new ObjectInitInfo(strIoTSlaveObjectHostAdd, strObjName,
-			strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, iRMIRegPort, iRMIStubPort);
+			strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, iRMIRegPort, iRMIStubPort, iRMICallbackPorts);
 		// Add the new ObjectInitInfo
 		list.add(objInitInfo);
 	}
@@ -149,7 +150,7 @@ public final class ObjectInitHandler {
 	 */
 	public void addSecondObjectIntoField(String strField, String strIoTSlaveObjectHostAdd,
 		String strObjName, String strObjClassName, String strObjClassInterfaceName,
-		String strObjStubClsIntfaceName, int iRMIRegPort, int iRMIStubPort) {
+		String strObjStubClsIntfaceName, int iRMIRegPort, int iRMIStubPort, Integer[] iRMICallbackPorts) {
 
 		// Get index of strField
 		int iFieldIndex = listField.indexOf(strField);
@@ -157,7 +158,7 @@ public final class ObjectInitHandler {
 		List<ObjectInitInfo> list = mapFieldToSecondObject.get(iFieldIndex);
 		// Create a new ObjectInitInfo for a new object in the field
 		ObjectInitInfo objInitInfo = new ObjectInitInfo(strIoTSlaveObjectHostAdd, strObjName,
-			strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, iRMIRegPort, iRMIStubPort);
+			strObjClassName, strObjClassInterfaceName, strObjStubClsIntfaceName, iRMIRegPort, iRMIStubPort, iRMICallbackPorts);
 		// Add the new ObjectInitInfo
 		list.add(objInitInfo);
 	}
diff --git a/iotjava/iotruntime/master/ObjectInitInfo.java b/iotjava/iotruntime/master/ObjectInitInfo.java
index 39b58dc..b40ad23 100644
--- a/iotjava/iotruntime/master/ObjectInitInfo.java
+++ b/iotjava/iotruntime/master/ObjectInitInfo.java
@@ -14,6 +14,7 @@ public class ObjectInitInfo extends ObjectCreationInfo {
 	 */
 	protected int iRMIRegPort;
 	protected int iRMIStubPort;
+	protected Integer[] iRMICallbackPorts;
 
 
 	/**
@@ -21,11 +22,12 @@ public class ObjectInitInfo extends ObjectCreationInfo {
 	 */
 	public ObjectInitInfo(String _strIoTSlaveObjectHostAdd, String _strObjName, 
 		String _strObjClassName, String _strObjClassInterfaceName, String _strObjStubClsIntfaceName,
-		int _iRMIRegPort, int _iRMIStubPort) {
+		int _iRMIRegPort, int _iRMIStubPort, Integer[] _iRMICallbackPorts) {
 
 		super(_strIoTSlaveObjectHostAdd, _strObjName, _strObjClassName, _strObjClassInterfaceName, _strObjStubClsIntfaceName);
 		iRMIRegPort = _iRMIRegPort;
 		iRMIStubPort = _iRMIStubPort;
+		iRMICallbackPorts = _iRMICallbackPorts;
 	}
 
 	/**
@@ -41,4 +43,11 @@ public class ObjectInitInfo extends ObjectCreationInfo {
 	public int getRMIStubPort() {
 		return iRMIStubPort;
 	}
+
+	/**
+	 * Method getRMICallbackPorts()
+	 */
+	public Integer[] getRMICallbackPorts() {
+		return iRMICallbackPorts;
+	}
 }
diff --git a/iotjava/iotruntime/messages/MessageGetObject.java b/iotjava/iotruntime/messages/MessageGetObject.java
index 6f022e1..bd8504f 100644
--- a/iotjava/iotruntime/messages/MessageGetObject.java
+++ b/iotjava/iotruntime/messages/MessageGetObject.java
@@ -21,6 +21,7 @@ public class MessageGetObject extends Message {
 	private String sObjStubIntName;
 	private int iRMIRegPort;
 	private int iRMIStubPort;
+	private Integer[] iRMICallbackPorts;
 	private Object[] arrObjFields;
 	private Class[] arrObjFldCls;
 
@@ -28,7 +29,7 @@ public class MessageGetObject extends Message {
 	 * Class constructor (to tell IoTSlave controller to get objects for IoTSet/IoTRelation)
 	 */
 	public MessageGetObject(IoTCommCode sMsg, String sHAddress, String sOName,
-		String sOClass, String sOIName, String sOSIName, int iRRPort, int iRSPort) {
+		String sOClass, String sOIName, String sOSIName, int iRRPort, int iRSPort, Integer[] iCBPort) {
 
 
 		super(sMsg);
@@ -39,6 +40,7 @@ public class MessageGetObject extends Message {
 		sObjStubIntName = sOSIName;
 		iRMIRegPort = iRRPort;
 		iRMIStubPort = iRSPort;
+		iRMICallbackPorts = iCBPort;
 	}
 
 	/**
@@ -106,6 +108,16 @@ public class MessageGetObject extends Message {
 		return iRMIStubPort;
 	}
 
+	/**
+
+	 * getRMICallbackPorts() method
+	 *
+	 * @return  Integer[]
+	 */
+	public Integer[] getRMICallbackPorts() {
+		return iRMICallbackPorts;
+	}
+
 	/**
 	 * setHostAddress() method
 	 *
@@ -175,4 +187,14 @@ public class MessageGetObject extends Message {
 	public void setRMIStubPort(int iRSPort) {
 		iRMIStubPort = iRSPort;
 	}
+
+	/**
+	 * setRMICallbackPorts() method
+	 *
+	 * @param   iCBPort  RMI callback port numbers
+	 * @return  void
+	 */
+	public void setRMICallbackPorts(Integer[] iCBPort) {
+		iRMICallbackPorts = iCBPort;
+	}
 }
diff --git a/iotjava/iotruntime/slave/IoTSlave.java b/iotjava/iotruntime/slave/IoTSlave.java
index a2def7c..856431a 100644
--- a/iotjava/iotruntime/slave/IoTSlave.java
+++ b/iotjava/iotruntime/slave/IoTSlave.java
@@ -31,6 +31,7 @@ import java.rmi.RemoteException;
 import java.rmi.AlreadyBoundException;
 import java.rmi.NotBoundException;
 import java.rmi.server.UnicastRemoteObject;
+import java.util.Arrays;
 import java.util.Properties;
 import java.util.HashMap;
 import java.util.Map;
@@ -202,7 +203,7 @@ public class IoTSlave {
 	 * @return  void
 	 */
 	private void createCapabBasedRMIJava(MessageCreateObject sMessage) throws 
-		ClassNotFoundException, NoSuchMethodException {
+		ClassNotFoundException, NoSuchMethodException, UnknownHostException {
 
 		// Instantiate the skeleton and put in the object
 		String strObjSkelName = STR_OBJ_CLS_PFX + "." + sMessage.getObjectClass() +
@@ -438,7 +439,8 @@ public class IoTSlave {
 		Class<?> clsStub = Class.forName(strObjStubName);	// Port number is integer
 		Class[] clsStubParams = { int.class, String.class, String.class, int.class, int[].class };
 		Constructor<?> objStubCons = clsStub.getDeclaredConstructor(clsStubParams);
-		int[] ports = { sMessage.getRMIRegPort() };		// TODO: Change this temporary use of reg port for callbacks
+		Integer[] portsInteger = sMessage.getRMICallbackPorts();
+		int[] ports = Arrays.stream(portsInteger).mapToInt(Integer::intValue).toArray();
 		int rev = 0;
 		String callbackAddress = InetAddress.getLocalHost().getHostAddress();	// Callback address is this machine's address
 		Object objStubParams[] = { sMessage.getRMIStubPort(), sMessage.getHostAddress(), callbackAddress,
diff --git a/localconfig/iotpolicy/development/callbackpolicy.pol b/localconfig/iotpolicy/development/callbackpolicy.pol
index 947b899..83278d1 100644
--- a/localconfig/iotpolicy/development/callbackpolicy.pol
+++ b/localconfig/iotpolicy/development/callbackpolicy.pol
@@ -2,12 +2,14 @@ public interface CallBackInterface {
 
     public int printInt();
     public void setInt(int _i);
+	public void needCallback(TestClassInterface tc);
 
 	capability CallBack {
 		description = "The quick brown fox jumps over the smart dog";
 		description = "Another description";
 		method = "printInt()";
 		method = "setInt(int _i)";
+		method = "needCallback(TestClassInterface tc)";
 	}
 }
 
diff --git a/localconfig/iotpolicy/development/testclasspolicy_advanced.pol b/localconfig/iotpolicy/development/testclasspolicy_advanced.pol
index b7899df..76fd934 100644
--- a/localconfig/iotpolicy/development/testclasspolicy_advanced.pol
+++ b/localconfig/iotpolicy/development/testclasspolicy_advanced.pol
@@ -1,5 +1,6 @@
 public interface TestClassInterface {
 
+	public short getShort(short in);
 	public Enum handleEnum(Enum en);
 	public Enum[] handleEnumArray(Enum en[]);
 	public List<Enum> handleEnumList(List<Enum> en);
@@ -56,7 +57,7 @@ public interface TestClassInterface {
 
 	capability Callbacks {
 		description = "All the set-and-get methods";
-
+		method = "getShort(short in)";
 		method = "registerCallback(CallBackInterface _cb)";
 		method = "registerCallbackArray(CallBackInterface _cb[])";
 		method = "registerCallbackList(List<CallBackInterface> _cb)";
diff --git a/localconfig/iotpolicy/development/testclasspolicy_callbacks.pol b/localconfig/iotpolicy/development/testclasspolicy_callbacks.pol
new file mode 100644
index 0000000..e79088c
--- /dev/null
+++ b/localconfig/iotpolicy/development/testclasspolicy_callbacks.pol
@@ -0,0 +1,29 @@
+public interface TestClassInterface {
+
+	public short getShort(short in);
+	public void registerCallback(CallBackInterface _cb);
+	public int callBack();
+
+	capability Callbacks {
+		description = "All the set-and-get methods";
+		method = "getShort(short in)";
+		method = "registerCallback(CallBackInterface _cb)";
+		method = "callBack()";
+	}
+	
+	enum Enum {
+
+		APPLE,
+		ORANGE,
+		GRAPE
+	}
+
+	struct Struct {
+
+		string 	name;
+		float	value;
+		int	year;
+	}
+}
+
+
diff --git a/localconfig/iotpolicy/development/testclassrequires_advanced.pol b/localconfig/iotpolicy/development/testclassrequires_advanced.pol
index b00b4cf..f7e2804 100644
--- a/localconfig/iotpolicy/development/testclassrequires_advanced.pol
+++ b/localconfig/iotpolicy/development/testclassrequires_advanced.pol
@@ -1,3 +1,3 @@
 
-requires TestClassInterface with EnumsStructs, Callbacks as interface TestClassComplete;
+requires TestClassInterface with EnumStructs, Callbacks as interface TestClassComplete;
 
diff --git a/localconfig/iotpolicy/development/testclassrequires_callbacks.pol b/localconfig/iotpolicy/development/testclassrequires_callbacks.pol
new file mode 100644
index 0000000..4ae575b
--- /dev/null
+++ b/localconfig/iotpolicy/development/testclassrequires_callbacks.pol
@@ -0,0 +1,3 @@
+
+requires TestClassInterface with Callbacks as interface TestClassComplete;
+
diff --git a/localconfig/iotruntime/IoTMaster.config b/localconfig/iotruntime/IoTMaster.config
index 3ec22ea..da858cc 100644
--- a/localconfig/iotruntime/IoTMaster.config
+++ b/localconfig/iotruntime/IoTMaster.config
@@ -27,3 +27,6 @@ ZIGBEE_IOTMASTER_PORT=12345
 #Verboseness of runtime messages
 VERBOSE=Yes
 
+#Number of callback ports
+NUMBER_CALLBACK_PORTS=4
+
-- 
2.34.1