From f77e9eb60a5846f469320af729bac0bd1e16c1eb Mon Sep 17 00:00:00 2001 From: rtrimana Date: Wed, 4 Jan 2017 17:31:23 -0800 Subject: [PATCH] Preparing 3rd benchmark for porting with capability-based RMI --- benchmarks/IrrigationController/Makefile | 2 +- benchmarks/Makefile | 2 +- .../GPSGatewayCallback_CallbackSkeleton.java | 55 + .../GPSGatewaySmart_Stub.java | 146 +++ benchmarks/SpeakerController/Makefile | 21 +- .../SpeakerController/RoomSmart_Stub.java | 36 + .../SpeakerCallback_CallbackSkeleton.java | 44 + .../SpeakerController/SpeakerController.java | 113 +- .../SpeakerController/SpeakerSmart_Stub.java | 174 ++++ benchmarks/drivers/AudioRoom/AudioRoom.config | 1 + benchmarks/drivers/AudioRoom/AudioRoom.java | 27 + .../drivers/AudioRoom/Room_Skeleton.java | 63 ++ .../GPSPhoneGateway/GPSPhoneGateway.config | 1 + .../GPSPhoneGateway/GPSPhoneGateway.java | 204 ++++ .../drivers/GPSPhoneGateway/PhoneInfo.java | 104 ++ .../GPSPhoneGateway/PhoneInfoInterface.java | 18 + benchmarks/drivers/IHome/IHome.config | 1 + benchmarks/drivers/IHome/IHome.java | 970 ++++++++++++++++++ benchmarks/drivers/Makefile | 20 +- benchmarks/interfaces/GPSGateway.java | 15 + benchmarks/interfaces/GPSGatewayCallback.java | 9 + benchmarks/interfaces/GPSGatewaySmart.java | 16 + .../interfaces/GPSGatewaySmartCallback.java | 10 + benchmarks/interfaces/Speaker.java | 18 + benchmarks/interfaces/SpeakerCallback.java | 8 + benchmarks/interfaces/SpeakerSmart.java | 19 + .../interfaces/SpeakerSmartCallback.java | 9 + iotjava/Makefile | 19 + localconfig/iotpolicy/AudioRoom/audioroom.pol | 11 + localconfig/iotpolicy/AudioRoom/roomsmart.req | 3 + .../GPSPhoneGateway/gpsgatewaycallback.pol | 13 + .../GPSPhoneGateway/gpsphonegateway.pol | 29 + .../GPSPhoneGateway/smartgpsgateway.req | 3 + .../smartgpsgatewaycallback.req | 3 + localconfig/iotpolicy/IHome/ihome.pol | 47 + localconfig/iotpolicy/IHome/smartspeaker.req | 3 + .../iotpolicy/IHome/smartspeakercallback.req | 3 + .../iotpolicy/IHome/speakercallback.pol | 11 + 38 files changed, 2164 insertions(+), 87 deletions(-) create mode 100644 benchmarks/SpeakerController/GPSGatewayCallback_CallbackSkeleton.java create mode 100644 benchmarks/SpeakerController/GPSGatewaySmart_Stub.java create mode 100644 benchmarks/SpeakerController/RoomSmart_Stub.java create mode 100644 benchmarks/SpeakerController/SpeakerCallback_CallbackSkeleton.java create mode 100644 benchmarks/SpeakerController/SpeakerSmart_Stub.java create mode 100644 benchmarks/drivers/AudioRoom/AudioRoom.config create mode 100644 benchmarks/drivers/AudioRoom/AudioRoom.java create mode 100644 benchmarks/drivers/AudioRoom/Room_Skeleton.java create mode 100644 benchmarks/drivers/GPSPhoneGateway/GPSPhoneGateway.config create mode 100644 benchmarks/drivers/GPSPhoneGateway/GPSPhoneGateway.java create mode 100644 benchmarks/drivers/GPSPhoneGateway/PhoneInfo.java create mode 100644 benchmarks/drivers/GPSPhoneGateway/PhoneInfoInterface.java create mode 100644 benchmarks/drivers/IHome/IHome.config create mode 100644 benchmarks/drivers/IHome/IHome.java create mode 100644 benchmarks/interfaces/GPSGateway.java create mode 100644 benchmarks/interfaces/GPSGatewayCallback.java create mode 100644 benchmarks/interfaces/GPSGatewaySmart.java create mode 100644 benchmarks/interfaces/GPSGatewaySmartCallback.java create mode 100644 benchmarks/interfaces/Speaker.java create mode 100644 benchmarks/interfaces/SpeakerCallback.java create mode 100644 benchmarks/interfaces/SpeakerSmart.java create mode 100644 benchmarks/interfaces/SpeakerSmartCallback.java create mode 100644 localconfig/iotpolicy/AudioRoom/audioroom.pol create mode 100644 localconfig/iotpolicy/AudioRoom/roomsmart.req create mode 100644 localconfig/iotpolicy/GPSPhoneGateway/gpsgatewaycallback.pol create mode 100644 localconfig/iotpolicy/GPSPhoneGateway/gpsphonegateway.pol create mode 100644 localconfig/iotpolicy/GPSPhoneGateway/smartgpsgateway.req create mode 100644 localconfig/iotpolicy/GPSPhoneGateway/smartgpsgatewaycallback.req create mode 100644 localconfig/iotpolicy/IHome/ihome.pol create mode 100644 localconfig/iotpolicy/IHome/smartspeaker.req create mode 100644 localconfig/iotpolicy/IHome/smartspeakercallback.req create mode 100644 localconfig/iotpolicy/IHome/speakercallback.pol diff --git a/benchmarks/IrrigationController/Makefile b/benchmarks/IrrigationController/Makefile index ff040f3..e338f79 100644 --- a/benchmarks/IrrigationController/Makefile +++ b/benchmarks/IrrigationController/Makefile @@ -12,7 +12,7 @@ all: irrigation PHONY += irrigation irrigation: - $(JAVAC) $(JFLAGS) $(CHECKER_OPT) $(ASTUBS) *.java + $(JAVAC) $(JFLAGS) *.java cd $(BIN_DIR)/IrrigationController; $(JAR) $(JARFLAGS) IrrigationController.jar ../IrrigationController/*.class ../iotcode/interfaces/*.class cp IrrigationController.config $(BIN_DIR)/IrrigationController cp -rf ./resources ./help_files $(BIN_DIR)/IrrigationController diff --git a/benchmarks/Makefile b/benchmarks/Makefile index 3a130eb..f4cbd4c 100644 --- a/benchmarks/Makefile +++ b/benchmarks/Makefile @@ -4,7 +4,7 @@ BOOFJARS := $(BOOFDIR)/BoofCV-feature-0.21.jar:$(BOOFDIR)/BoofCV-io-0.21.jar:$(B include $(BASE)/common.mk -all: interfaces annotation drivers Lifxtest SmartLights Irrigation +all: interfaces annotation drivers Lifxtest SmartLights Irrigation Speaker PHONY += interfaces interfaces: diff --git a/benchmarks/SpeakerController/GPSGatewayCallback_CallbackSkeleton.java b/benchmarks/SpeakerController/GPSGatewayCallback_CallbackSkeleton.java new file mode 100644 index 0000000..91c2d15 --- /dev/null +++ b/benchmarks/SpeakerController/GPSGatewayCallback_CallbackSkeleton.java @@ -0,0 +1,55 @@ +package SpeakerController; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import iotrmi.Java.IoTRMICall; +import iotrmi.Java.IoTRMIObject; + +import iotcode.interfaces.*; + +public class GPSGatewayCallback_CallbackSkeleton implements GPSGatewayCallback { + + private GPSGatewayCallback mainObj; + private int objectId = 0; + private String callbackAddress; + + + public GPSGatewayCallback_CallbackSkeleton(GPSGatewayCallback _mainObj, String _callbackAddress, int _objectId) throws Exception { + callbackAddress = _callbackAddress; + mainObj = _mainObj; + objectId = _objectId; + } + + public void newRoomIDRetrieved(int _roomIdentifier) { + mainObj.newRoomIDRetrieved(_roomIdentifier); + } + + public void newRingStatusRetrieved(boolean _ringStatus) { + mainObj.newRingStatusRetrieved(_ringStatus); + } + + public void ___newRoomIDRetrieved(IoTRMIObject rmiObj) { + Object[] paramObj = rmiObj.getMethodParams(new Class[] { int.class }, + new Class[] { null }); + newRoomIDRetrieved((int) paramObj[0]); + } + + public void ___newRingStatusRetrieved(IoTRMIObject rmiObj) { + Object[] paramObj = rmiObj.getMethodParams(new Class[] { boolean.class }, + new Class[] { null }); + newRingStatusRetrieved((boolean) paramObj[0]); + } + + public void invokeMethod(IoTRMIObject rmiObj) throws IOException { + int methodId = rmiObj.getMethodId(); + switch (methodId) { + case 0: ___newRoomIDRetrieved(rmiObj); break; + case 1: ___newRingStatusRetrieved(rmiObj); break; + default: + throw new Error("Method Id " + methodId + " not recognized!"); + } + } + +} diff --git a/benchmarks/SpeakerController/GPSGatewaySmart_Stub.java b/benchmarks/SpeakerController/GPSGatewaySmart_Stub.java new file mode 100644 index 0000000..f5bc2ca --- /dev/null +++ b/benchmarks/SpeakerController/GPSGatewaySmart_Stub.java @@ -0,0 +1,146 @@ +package SpeakerController; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import iotrmi.Java.IoTRMICall; +import iotrmi.Java.IoTRMIObject; + +import iotcode.interfaces.*; + +public class GPSGatewaySmart_Stub implements GPSGatewaySmart { + + private IoTRMICall rmiCall; + private String callbackAddress; + private int[] ports; + + private final static int objectId = 0; + // Callback properties + private IoTRMIObject rmiObj; + List listCallbackObj; + private int objIdCnt = 0; + private final static int object0Id = 0; //GPSGatewaySmartCallback + private static Integer[] object0Permission = { 0, 1 }; + private static List set0Allowed; + + + public GPSGatewaySmart_Stub(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception { + callbackAddress = _callbackAddress; + ports = _ports; + rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev); + set0Allowed = new ArrayList(Arrays.asList(object0Permission)); + listCallbackObj = new ArrayList(); + set0Allowed.add(-9999); + ___initCallBack(); + } + + public void setNewRoomIDAvailable(boolean bValue) { + int methodId = 5; + Class retType = void.class; + Class[] paramCls = new Class[] { boolean.class }; + Object[] paramObj = new Object[] { bValue }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public void setNewRingStatusAvailable(boolean bValue) { + int methodId = 6; + Class retType = void.class; + Class[] paramCls = new Class[] { boolean.class }; + Object[] paramObj = new Object[] { bValue }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public void stop() { + int methodId = 2; + Class retType = void.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public void start() { + int methodId = 1; + Class retType = void.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public void init() { + int methodId = 0; + Class retType = void.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public int getRoomID() { + int methodId = 3; + Class retType = int.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + return (int)retObj; + } + + public void registerCallback(GPSGatewayCallback _callbackTo) { + try { + GPSGatewayCallback_CallbackSkeleton skel0 = new GPSGatewayCallback_CallbackSkeleton(_callbackTo, callbackAddress, objIdCnt++); + listCallbackObj.add(skel0); + } catch (Exception ex) { + ex.printStackTrace(); + throw new Error("Exception when generating skeleton objects!"); + } + + int methodId = 7; + Class retType = void.class; + Class[] paramCls = new Class[] { int.class }; + Object[] paramObj = new Object[] { new Integer(1) }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public void ___initCallBack() { + Thread thread = new Thread() { + public void run() { + try { + rmiObj = new IoTRMIObject(ports[0]); + while (true) { + byte[] method = rmiObj.getMethodBytes(); + int objId = IoTRMIObject.getObjectId(method); + GPSGatewayCallback_CallbackSkeleton skel = (GPSGatewayCallback_CallbackSkeleton) listCallbackObj.get(objId); + if (skel != null) { + int methodId = IoTRMIObject.getMethodId(method); + if (!set0Allowed.contains(methodId)) { + throw new Error("Callback object for GPSGatewayCallback is not allowed to access method: " + methodId); + } + skel.invokeMethod(rmiObj); + } else { + throw new Error("GPSGatewayCallback: Object with Id " + objId + " not found!"); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + throw new Error("Error instantiating class GPSGatewayCallback_CallbackSkeleton!"); + } + } + }; + thread.start(); + + int methodId = -9998; + Class retType = void.class; + Class[] paramCls = new Class[] { int[].class, String.class, int.class }; + Object[] paramObj = new Object[] { ports, callbackAddress, 0 }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public boolean getRingStatus() { + int methodId = 4; + Class retType = boolean.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + return (boolean)retObj; + } + +} diff --git a/benchmarks/SpeakerController/Makefile b/benchmarks/SpeakerController/Makefile index 80be525..1c042f0 100644 --- a/benchmarks/SpeakerController/Makefile +++ b/benchmarks/SpeakerController/Makefile @@ -10,25 +10,10 @@ JLAYERJARS := $(JLAYERDIR)/jl1.0.1.jar JFLAGS = -d $(BIN_DIR) -cp $(BOOFJARS):$(BIN_DIR):.:$(JLAYERJARS) JARFLAGS = cf -# checker option -# -CHECKER_OPT = -processor iotchecker.IoTJavaChecker +all: speaker -ASTUBS = -Astubs=../../checker/astubs/ - -all: check - -PHONY += check -check: - $(JAVAC) $(JFLAGS) $(CHECKER_OPT) $(ASTUBS) *.java - cd $(BIN_DIR)/SpeakerController; $(JAR) $(JARFLAGS) SpeakerController.jar ../SpeakerController/*.class ../iotcode/interfaces/*.class - cp SpeakerController.config $(BIN_DIR)/SpeakerController - zip -r SpeakerController.zip ./music - mv SpeakerController.zip $(BIN_DIR)/SpeakerController - -PHONY += nocheck - -nocheck: +PHONY += speaker +speaker: $(JAVAC) $(JFLAGS) *.java cd $(BIN_DIR)/SpeakerController; $(JAR) $(JARFLAGS) SpeakerController.jar ../SpeakerController/*.class ../iotcode/interfaces/*.class cp SpeakerController.config $(BIN_DIR)/SpeakerController diff --git a/benchmarks/SpeakerController/RoomSmart_Stub.java b/benchmarks/SpeakerController/RoomSmart_Stub.java new file mode 100644 index 0000000..a45b775 --- /dev/null +++ b/benchmarks/SpeakerController/RoomSmart_Stub.java @@ -0,0 +1,36 @@ +package SpeakerController; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import iotrmi.Java.IoTRMICall; +import iotrmi.Java.IoTRMIObject; + +import iotcode.interfaces.RoomSmart; + +public class RoomSmart_Stub implements RoomSmart { + + private IoTRMICall rmiCall; + private String callbackAddress; + private int[] ports; + + private final static int objectId = 0; + + + public RoomSmart_Stub(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception { + callbackAddress = _callbackAddress; + ports = _ports; + rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev); + } + + public int getRoomID() { + int methodId = 0; + Class retType = int.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + return (int)retObj; + } + +} diff --git a/benchmarks/SpeakerController/SpeakerCallback_CallbackSkeleton.java b/benchmarks/SpeakerController/SpeakerCallback_CallbackSkeleton.java new file mode 100644 index 0000000..808ae44 --- /dev/null +++ b/benchmarks/SpeakerController/SpeakerCallback_CallbackSkeleton.java @@ -0,0 +1,44 @@ +package SpeakerController; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import iotrmi.Java.IoTRMICall; +import iotrmi.Java.IoTRMIObject; + +import iotcode.interfaces.*; + +public class SpeakerCallback_CallbackSkeleton implements SpeakerCallback { + + private SpeakerCallback mainObj; + private int objectId = 0; + private String callbackAddress; + + + public SpeakerCallback_CallbackSkeleton(SpeakerCallback _mainObj, String _callbackAddress, int _objectId) throws Exception { + callbackAddress = _callbackAddress; + mainObj = _mainObj; + objectId = _objectId; + } + + public void speakerDone() { + mainObj.speakerDone(); + } + + public void ___speakerDone(IoTRMIObject rmiObj) { + Object[] paramObj = rmiObj.getMethodParams(new Class[] { }, + new Class[] { }); + speakerDone(); + } + + public void invokeMethod(IoTRMIObject rmiObj) throws IOException { + int methodId = rmiObj.getMethodId(); + switch (methodId) { + case 0: ___speakerDone(rmiObj); break; + default: + throw new Error("Method Id " + methodId + " not recognized!"); + } + } + +} diff --git a/benchmarks/SpeakerController/SpeakerController.java b/benchmarks/SpeakerController/SpeakerController.java index 17fcd67..00b6dba 100644 --- a/benchmarks/SpeakerController/SpeakerController.java +++ b/benchmarks/SpeakerController/SpeakerController.java @@ -7,7 +7,7 @@ import iotruntime.slave.IoTRelation; // IoT driver packages import iotcode.interfaces.*; -//import iotcode.annotation.*; +import iotcode.annotation.*; // Standard Java packages @@ -26,7 +26,7 @@ import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; // Checker annotations -import iotchecker.qual.*; +//import iotchecker.qual.*; /** Class SpeakerController for the smart home application benchmark *

@@ -50,23 +50,23 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway /** * IoT Sets of Devices */ - @config private IoTSet < @NonLocalRemote GPSGateway > gpsSet; - @config private IoTSet < @NonLocalRemote Speaker > speakerSet; + @config private IoTSet < GPSGatewaySmart > gpsSet; + @config private IoTSet < SpeakerSmart > speakerSet; /** * IoT Sets of Things that are not devices such as rooms */ - @config private IoTSet < @NonLocalRemote Room > audioRooms; + @config private IoTSet < RoomSmart > audioRooms; /** * IoT Relations */ - @config private IoTRelation < @NonLocalRemote Room, @NonLocalRemote Speaker > roomSpeakerRel; + @config private IoTRelation < RoomSmart, SpeakerSmart > roomSpeakerRel; /** * The state that the room main lights are supposed to be in */ - Map < @NonLocalRemote Room, Boolean > roomSpeakersOnOffStatus = new HashMap < @NonLocalRemote Room, Boolean > (); + Map < RoomSmart, Boolean > roomSpeakersOnOffStatus = new HashMap < RoomSmart, Boolean > (); // used to notify if new data is available private AtomicBoolean newDataAvailable = new AtomicBoolean(false); @@ -87,22 +87,13 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway /** Callback method for when room ID is retrieved. * - * @param _ggw [GPSGateway]. + * @param _roomIdentifier [int]. * @return [void] None. */ - public void newRoomIDRetrieved(@NonLocalRemote GPSGateway _ggw) { - - try { - // get the parameters that the interface (phone app) reads from the user - roomIdentifier = _ggw.getRoomID(); + public void newRoomIDRetrieved(int _roomIdentifier) { - System.out.println("DEBUG: New room ID is retrieved from phone!!! Room: " + roomIdentifier); - - // Data is read, so we set this back to false - _ggw.setNewRoomIDAvailable(false); - } catch (RemoteException ex) { - ex.printStackTrace(); - } + roomIdentifier = _roomIdentifier; + System.out.println("DEBUG: New room ID is retrieved from phone!!! Room: " + roomIdentifier); // new data available so set it to true newDataAvailable.set(true); @@ -111,22 +102,13 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway /** Callback method for when ring status is retrieved. * - * @param _ggw [GPSGateway]. + * @param _ringStatus [boolean]. * @return [void] None. */ - public void newRingStatusRetrieved(@NonLocalRemote GPSGateway _ggw) { - - try { - // get the parameters that the interface (phone app) reads from the user - ringStatus = _ggw.getRingStatus(); + public void newRingStatusRetrieved(boolean _ringStatus) { - System.out.println("DEBUG: New ring status is retrieved from phone!!! Status: " + ringStatus); - - // Data is read, so we set this back to false - _ggw.setNewRingStatusAvailable(false); - } catch (RemoteException ex) { - ex.printStackTrace(); - } + ringStatus = _ringStatus; + System.out.println("DEBUG: New ring status is retrieved from phone!!! Status: " + ringStatus); // new data available so set it to true newDataAvailable.set(true); @@ -135,11 +117,10 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway /** Callback method when a speaker has finished playing what is in its audio buffer. * - * @param _speaker [Speaker]. * @return [void] None. */ - public void speakerDone(@NonLocalRemote Speaker _speaker) { - for (@NonLocalRemote Speaker speakers : speakerSet.values()) { + public void speakerDone() { + for (SpeakerSmart speakers : speakerSet.values()) { playbackDone.set(true); } } @@ -157,7 +138,7 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway private void updateSpeakersAction() { // Stream music on speakers based on their status - for (@NonLocalRemote Room room : audioRooms.values()) { + for (RoomSmart room : audioRooms.values()) { // Check status of the room if (roomSpeakersOnOffStatus.get(room)) { @@ -168,15 +149,15 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway // Get the speaker objects one by one assuming that we could have // more than one speaker per room - for (@NonLocalRemote Speaker speakers : roomSpeakerRel.get(room)) { + for (SpeakerSmart speakers : roomSpeakerRel.get(room)) { // System.out.println("DEBUG: Turn on speaker!"); - try { + //try { // start the speaker playback if the speaker is not playing yet if (!speakers.getPlaybackState()) { - System.out.println("Turning a speaker On"); + System.out.println("Turning a speaker On in room: " + room.getRoomID()); speakers.startPlayback(); speakers.setPosition(currentPosition); @@ -187,9 +168,9 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway } - } catch (RemoteException e) { - e.printStackTrace(); - } + //} catch (RemoteException e) { + // e.printStackTrace(); + //} } if (currPosCount != 0) { @@ -201,12 +182,12 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway if (Math.abs(currentPosOfSpeakers - currentPosition) > CURRENT_POSITION_SAMPLE_THRESHOLD) { // we were kind of far so update all the positions - for (@NonLocalRemote Speaker speakers : roomSpeakerRel.get(room)) { - try { + for (SpeakerSmart speakers : roomSpeakerRel.get(room)) { + //try { speakers.setPosition(currentPosOfSpeakers); - } catch (RemoteException e) { - e.printStackTrace(); - } + //} catch (RemoteException e) { + // e.printStackTrace(); + //} } } @@ -216,7 +197,7 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway - } else { + } /*else { // Room status is "off" // used to get the average of the speakers position @@ -225,7 +206,7 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway // Get the speaker objects one by one assuming that we could have // more than one speaker per room - for (@NonLocalRemote Speaker speakers : roomSpeakerRel.get(room)) { + for (Speaker speakers : roomSpeakerRel.get(room)) { // System.out.println("DEBUG: Turn off speaker!"); try { // Turning off speaker if they are still on @@ -251,7 +232,7 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway if (currPosCount != 0) { currentPosition = (int)(currPosTotal / currPosCount); } - } + }*/ } // a speaker has finished playing and so we should change all the audio buffers @@ -278,7 +259,7 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway if (ringStatus) { // Turn off all speakers if ring status is true (phone is ringing) - for (@NonLocalRemote Room room : audioRooms.values()) { + for (RoomSmart room : audioRooms.values()) { // System.out.println("DEBUG: Update status off for speakers! Phone is ringing!!!"); // Turn off speaker @@ -289,9 +270,9 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway // Phone is not ringing... just play music on the right speaker // Check for every room - for (@NonLocalRemote Room room : audioRooms.values()) { + for (RoomSmart room : audioRooms.values()) { - try { + //try { // Turn on the right speaker based on room ID sent from phone app // Stream audio to a speaker based on room ID if (room.getRoomID() == roomIdentifier) { @@ -309,9 +290,9 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway roomSpeakersOnOffStatus.put(room, false); } - } catch (RemoteException ex) { - ex.printStackTrace(); - } + //} catch (RemoteException ex) { + // ex.printStackTrace(); + //} } } // Finish processing data - put this back to false @@ -328,7 +309,7 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway System.out.println("Stopping all device playback"); // stop all devices that are still playing and clear their buffers // they are about to end playback anyways - for (@NonLocalRemote Speaker speakers : speakerSet.values()) { + for (SpeakerSmart speakers : speakerSet.values()) { try { if (speakers.getPlaybackState()) { @@ -390,7 +371,7 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway System.out.println("Loading Speakers"); // send the new data to all the speakers - for (@NonLocalRemote Speaker speakers : speakerSet.values()) { + for (SpeakerSmart speakers : speakerSet.values()) { System.out.println("Loading a single speaker with data"); try { speakers.loadData(compressedArray, 0, compressedArray.length); @@ -418,27 +399,27 @@ public class SpeakerController extends UnicastRemoteObject implements GPSGateway public void init() throws RemoteException, InterruptedException { // Initialize the rooms - for (@NonLocalRemote Room room : audioRooms.values()) { + for (RoomSmart room : audioRooms.values()) { // All rooms start with the speakers turned off roomSpeakersOnOffStatus.put(room, false); } // Setup the cameras, start them all and assign each one a motion detector - for (@NonLocalRemote GPSGateway gw : gpsSet.values()) { + for (GPSGatewaySmart gw : gpsSet.values()) { - try { + //try { // initialize, register callback, and start the gateway gw.init(); gw.registerCallback(this); gw.start(); - } catch (RemoteException ex) { - ex.printStackTrace(); - } + //} catch (RemoteException ex) { + // ex.printStackTrace(); + //} } //Initialize the speakers - for (@NonLocalRemote Speaker speakers : speakerSet.values()) { + for (SpeakerSmart speakers : speakerSet.values()) { speakers.init(); } diff --git a/benchmarks/SpeakerController/SpeakerSmart_Stub.java b/benchmarks/SpeakerController/SpeakerSmart_Stub.java new file mode 100644 index 0000000..71147e6 --- /dev/null +++ b/benchmarks/SpeakerController/SpeakerSmart_Stub.java @@ -0,0 +1,174 @@ +package SpeakerController; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import iotrmi.Java.IoTRMICall; +import iotrmi.Java.IoTRMIObject; + +import iotcode.interfaces.*; + +public class SpeakerSmart_Stub implements SpeakerSmart { + + private IoTRMICall rmiCall; + private String callbackAddress; + private int[] ports; + + private final static int objectId = 0; + // Callback properties + private IoTRMIObject rmiObj; + List listCallbackObj; + private int objIdCnt = 0; + private final static int object0Id = 0; //SpeakerSmartCallback + private static Integer[] object0Permission = { 0 }; + private static List set0Allowed; + + + public SpeakerSmart_Stub(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception { + callbackAddress = _callbackAddress; + ports = _ports; + rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev); + set0Allowed = new ArrayList(Arrays.asList(object0Permission)); + listCallbackObj = new ArrayList(); + set0Allowed.add(-9999); + ___initCallBack(); + } + + public int getPosition() { + int methodId = 6; + Class retType = int.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + return (int)retObj; + } + + public boolean stopPlayback() { + int methodId = 2; + Class retType = boolean.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + return (boolean)retObj; + } + + public void clearData() { + int methodId = 9; + Class retType = void.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public boolean startPlayback() { + int methodId = 1; + Class retType = boolean.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + return (boolean)retObj; + } + + public boolean getPlaybackState() { + int methodId = 3; + Class retType = boolean.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + return (boolean)retObj; + } + + public boolean setVolume(float _percent) { + int methodId = 4; + Class retType = boolean.class; + Class[] paramCls = new Class[] { float.class }; + Object[] paramObj = new Object[] { _percent }; + Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + return (boolean)retObj; + } + + public float getVolume() { + int methodId = 5; + Class retType = float.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + return (float)retObj; + } + + public void setPosition(int _mSec) { + int methodId = 7; + Class retType = void.class; + Class[] paramCls = new Class[] { int.class }; + Object[] paramObj = new Object[] { _mSec }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public void loadData(short _samples[], int _offs, int _len) { + int methodId = 8; + Class retType = void.class; + Class[] paramCls = new Class[] { short[].class, int.class, int.class }; + Object[] paramObj = new Object[] { _samples, _offs, _len }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public void init() { + int methodId = 0; + Class retType = void.class; + Class[] paramCls = new Class[] { }; + Object[] paramObj = new Object[] { }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public void registerCallback(SpeakerCallback _cb) { + try { + SpeakerCallback_CallbackSkeleton skel0 = new SpeakerCallback_CallbackSkeleton(_cb, callbackAddress, objIdCnt++); + listCallbackObj.add(skel0); + } catch (Exception ex) { + ex.printStackTrace(); + throw new Error("Exception when generating skeleton objects!"); + } + + int methodId = 10; + Class retType = void.class; + Class[] paramCls = new Class[] { int.class }; + Object[] paramObj = new Object[] { new Integer(1) }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + + public void ___initCallBack() { + Thread thread = new Thread() { + public void run() { + try { + rmiObj = new IoTRMIObject(ports[0]); + while (true) { + byte[] method = rmiObj.getMethodBytes(); + int objId = IoTRMIObject.getObjectId(method); + SpeakerCallback_CallbackSkeleton skel = (SpeakerCallback_CallbackSkeleton) listCallbackObj.get(objId); + if (skel != null) { + int methodId = IoTRMIObject.getMethodId(method); + if (!set0Allowed.contains(methodId)) { + throw new Error("Callback object for SpeakerCallback is not allowed to access method: " + methodId); + } + skel.invokeMethod(rmiObj); + } else { + throw new Error("SpeakerCallback: Object with Id " + objId + " not found!"); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + throw new Error("Error instantiating class SpeakerCallback_CallbackSkeleton!"); + } + } + }; + thread.start(); + + int methodId = -9998; + Class retType = void.class; + Class[] paramCls = new Class[] { int[].class, String.class, int.class }; + Object[] paramObj = new Object[] { ports, callbackAddress, 0 }; + rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj); + } + +} diff --git a/benchmarks/drivers/AudioRoom/AudioRoom.config b/benchmarks/drivers/AudioRoom/AudioRoom.config new file mode 100644 index 0000000..6af9ab2 --- /dev/null +++ b/benchmarks/drivers/AudioRoom/AudioRoom.config @@ -0,0 +1 @@ +INTERFACE_CLASS=Room diff --git a/benchmarks/drivers/AudioRoom/AudioRoom.java b/benchmarks/drivers/AudioRoom/AudioRoom.java new file mode 100644 index 0000000..06714b0 --- /dev/null +++ b/benchmarks/drivers/AudioRoom/AudioRoom.java @@ -0,0 +1,27 @@ +package iotcode.AudioRoom; + +import iotcode.interfaces.Room; + +/** AudioRoom holds room ID that tells which room it is + * in association with speakers + * + * @author Rahmadi Trimananda + * @version 1.0 + * @since 2016-04-29 + */ +public class AudioRoom implements Room { + + /** + * AudioRoom class properties + */ + private int iRoomID; + + public AudioRoom(int _iRoomID) { + this.iRoomID = _iRoomID; + System.out.println("AudioRoom ID: " + this.iRoomID); + } + + public int getRoomID() { + return this.iRoomID; + } +} diff --git a/benchmarks/drivers/AudioRoom/Room_Skeleton.java b/benchmarks/drivers/AudioRoom/Room_Skeleton.java new file mode 100644 index 0000000..b9b9b3b --- /dev/null +++ b/benchmarks/drivers/AudioRoom/Room_Skeleton.java @@ -0,0 +1,63 @@ +package iotcode.AudioRoom; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import iotrmi.Java.IoTRMICall; +import iotrmi.Java.IoTRMIObject; + +import iotcode.interfaces.Room; + +public class Room_Skeleton implements Room { + + private Room mainObj; + private IoTRMIObject rmiObj; + + private String callbackAddress; + private final static int object0Id = 0; //RoomSmart + private static Integer[] object0Permission = { 0 }; + private static List set0Allowed; + + + public Room_Skeleton(Room _mainObj, String _callbackAddress, int _port) throws Exception { + mainObj = _mainObj; + callbackAddress = _callbackAddress; + rmiObj = new IoTRMIObject(_port); + set0Allowed = new ArrayList(Arrays.asList(object0Permission)); + ___waitRequestInvokeMethod(); + } + + public int getRoomID() { + return mainObj.getRoomID(); + } + + public void ___getRoomID() throws IOException { + Object[] paramObj = rmiObj.getMethodParams(new Class[] { }, + new Class[] { }); + Object retObj = getRoomID(); + rmiObj.sendReturnObj(retObj); + } + + private void ___waitRequestInvokeMethod() throws IOException { + while (true) { + rmiObj.getMethodBytes(); + int _objectId = rmiObj.getObjectId(); + int methodId = rmiObj.getMethodId(); + if (_objectId == object0Id) { + if (!set0Allowed.contains(methodId)) { + throw new Error("Object with object Id: " + _objectId + " is not allowed to access method: " + methodId); + } + } + else { + throw new Error("Object Id: " + _objectId + " not recognized!"); + } + switch (methodId) { + case 0: ___getRoomID(); break; + default: + throw new Error("Method Id " + methodId + " not recognized!"); + } + } + } + +} diff --git a/benchmarks/drivers/GPSPhoneGateway/GPSPhoneGateway.config b/benchmarks/drivers/GPSPhoneGateway/GPSPhoneGateway.config new file mode 100644 index 0000000..081970f --- /dev/null +++ b/benchmarks/drivers/GPSPhoneGateway/GPSPhoneGateway.config @@ -0,0 +1 @@ +INTERFACE_CLASS=GPSGateway diff --git a/benchmarks/drivers/GPSPhoneGateway/GPSPhoneGateway.java b/benchmarks/drivers/GPSPhoneGateway/GPSPhoneGateway.java new file mode 100644 index 0000000..404292b --- /dev/null +++ b/benchmarks/drivers/GPSPhoneGateway/GPSPhoneGateway.java @@ -0,0 +1,204 @@ +package iotcode.GPSPhoneGateway; + +// Java standard library +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.Iterator; +import java.util.List; +import java.net.UnknownHostException; + +// RMI Packages +import java.rmi.Remote; +import java.rmi.RemoteException; + +// IoTRuntime library +import iotruntime.stub.IoTRemoteCall; +import iotruntime.slave.IoTSet; +import iotruntime.slave.IoTDeviceAddress; +import iotcode.annotation.*; +import iotcode.interfaces.*; + +// Checker annotations +//import iotchecker.qual.*; + +/** GPSPhoneGateway that uses IoTRemoteCall and PhoneInfo class + * to get information from a phone app + * + * @author Rahmadi Trimananda + * @version 1.0 + * @since 2016-04-27 + */ +public class GPSPhoneGateway implements GPSGateway { + + /** + * PhoneGateway class properties + */ + private PhoneInfo phoneInfo; + private IoTRemoteCall iotRemCall; + private List listPGWCallback; + private AtomicBoolean doEnd; + private Thread callbackThread; + private Thread workerThread; + private IoTDeviceAddress iotDevAdd; + + @config private IoTSet gps_address; + + /** + * Constructor + */ + public GPSPhoneGateway() throws RemoteException { + } + + /** + * Init() function + */ + public void init() { + + // Get address + Iterator it = gps_address.iterator(); + iotDevAdd = (IoTDeviceAddress) it.next(); +// try { +// iotDevAdd = new IoTDeviceAddress("192.168.2.100", 1234, 8000); +// } catch (Exception ex) { +// } + System.out.println("Address: " + iotDevAdd.getCompleteAddress()); + System.out.println("Source port: " + iotDevAdd.getSourcePortNumber()); + System.out.println("Destination port: " + iotDevAdd.getDestinationPortNumber()); + + // Get server + phoneInfo = new PhoneInfo(); + listPGWCallback = new ArrayList(); + doEnd = new AtomicBoolean(false); + + // Threads + callbackThread = null; + workerThread = null; + } + + /** + * Start() function to start threads + */ + public void start() { + doEnd.set(false); + + // Launch IoTRemoteCall server in a separate thread + workerThread = new Thread(new Runnable() { + public void run() { + iotRemCall = new IoTRemoteCall(PhoneInfoInterface.class, + phoneInfo, iotDevAdd.getDestinationPortNumber(), + IoTDeviceAddress.getLocalHostAddress()); + } + }); + workerThread.start(); + System.out.println("GPSPhoneGateway: Worker thread started!"); + + callbackThread = new Thread(new Runnable() { + public void run() { + doCallbacks(); + } + }); + callbackThread.start(); + System.out.println("GPSPhoneGateway: Callback thread started!"); + } + + /** + * Stop() function to stop threads + */ + public void stop() { + doEnd.set(true); + + try { + callbackThread.join(); + workerThread.join(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Register callbacks + */ + public void registerCallback(GPSGatewaySmartCallback _c) { + listPGWCallback.add(_c); + } + + /** + * Do callbacks + */ + private void doCallbacks() { + + while (!doEnd.get()) { + + for (GPSGatewaySmartCallback c : listPGWCallback) { + + //try { + // Only call back if there is new data + if (phoneInfo.isNewRoomIDAvailable()) { + + System.out.println("GPSPhoneGateway: new room ID available - call back!"); + // Call back! + //c.newRoomIDRetrieved(this); + c.newRoomIDRetrieved(this.getRoomID()); + //this.setNewRoomIDAvailable(false); + + // Set back to false after reading + phoneInfo.setNewRoomIDAvailable(false); + + } else if (phoneInfo.isNewRingStatusAvailable()) { + + System.out.println("GPSPhoneGateway: new ring status available - call back!"); + // Call back! + //c.newRingStatusRetrieved(this); + c.newRingStatusRetrieved(this.getRingStatus()); + //this.setNewRingStatusAvailable(false); + + // Set back to false after reading + phoneInfo.setNewRingStatusAvailable(false); + } + + //} catch (RemoteException ex) { + // ex.printStackTrace(); + //} + } + } + } + + /** + * Simply return phoneInfo.iRoomIdentifier + */ + public int getRoomID() { + + return phoneInfo.getRoomID(); + } + + /** + * Simply return phoneInfo.bRingStatus + */ + public boolean getRingStatus() { + + return phoneInfo.getRingStatus(); + } + + /** + * Set phoneInfo.bNewRoomIDAvail + */ + public void setNewRoomIDAvailable(boolean bValue) { + + phoneInfo.setNewRoomIDAvailable(bValue); + } + + /** + * Set phoneInfo.bNewRingStatusAvail + */ + public void setNewRingStatusAvailable(boolean bValue) { + + phoneInfo.setNewRingStatusAvailable(bValue); + } + +/* public static void main(String[] args) throws UnknownHostException, RemoteException { + + @LocalRemote GPSPhoneGateway gpg = new @LocalRemote GPSPhoneGateway(); + gpg.init(); + gpg.start(); + }*/ +} diff --git a/benchmarks/drivers/GPSPhoneGateway/PhoneInfo.java b/benchmarks/drivers/GPSPhoneGateway/PhoneInfo.java new file mode 100644 index 0000000..c09697b --- /dev/null +++ b/benchmarks/drivers/GPSPhoneGateway/PhoneInfo.java @@ -0,0 +1,104 @@ +package iotcode.GPSPhoneGateway; + +/** PhoneInfo that implements PhoneInfoInterface + * + * @author Rahmadi Trimananda + * @version 1.0 + * @since 2016-04-27 + */ +public class PhoneInfo implements PhoneInfoInterface { + + /** + * PhoneInfo class properties + */ + private int iRoomIdentifier; + private boolean bRingStatus; + private boolean bNewRoomIDAvail; + private boolean bNewRingStatusAvail; + + /** + * Constructor + */ + public PhoneInfo() { + this.iRoomIdentifier = 0; + this.bRingStatus = false; + this.bNewRoomIDAvail = false; + this.bNewRingStatusAvail = false; + } + + /** + * Set room identifier info from the phone app using IoTRemoteCall + * + * @param iId Room identifier (integer) + * @return String + */ + public String setRoomID(Integer iId) { + + this.iRoomIdentifier = iId; + this.bNewRoomIDAvail = true; + System.out.println("New room ID set: " + this.iRoomIdentifier); + return "info sent"; + } + + /** + * Set ring status info from the phone app using IoTRemoteCall + * + * @param bStatus Ring status (true/false) + * @return String + */ + public String setRingStatus(Boolean bStatus) { + + this.bRingStatus = bStatus; + this.bNewRingStatusAvail = true; + System.out.println("New ring status set: " + this.bRingStatus); + return "info sent"; + } + + /** + * Simply return this.iRoomIdentifier + */ + public int getRoomID() { + + return this.iRoomIdentifier; + } + + /** + * Simply return this.bRingStatus + */ + public boolean getRingStatus() { + + return this.bRingStatus; + } + + /** + * Simply return this.bNewRoomIDAvail + */ + public boolean isNewRoomIDAvailable() { + + return this.bNewRoomIDAvail; + } + + /** + * Simply return this.bNewRingStatusAvail + */ + public boolean isNewRingStatusAvailable() { + + return this.bNewRingStatusAvail; + } + + /** + * Set this.bNewRoomIDAvail + */ + public void setNewRoomIDAvailable(boolean bValue) { + + this.bNewRoomIDAvail = bValue; + } + + /** + * Set this.bNewRingStatusAvail + */ + public void setNewRingStatusAvailable(boolean bValue) { + + this.bNewRingStatusAvail = bValue; + } +} diff --git a/benchmarks/drivers/GPSPhoneGateway/PhoneInfoInterface.java b/benchmarks/drivers/GPSPhoneGateway/PhoneInfoInterface.java new file mode 100644 index 0000000..08b17c1 --- /dev/null +++ b/benchmarks/drivers/GPSPhoneGateway/PhoneInfoInterface.java @@ -0,0 +1,18 @@ +package iotcode.GPSPhoneGateway; + +/** PhoneInfoInterface interface to be implemented by a real class + * + * @author Rahmadi Trimananda + * @version 1.0 + * @since 2016-04-27 + */ +public interface PhoneInfoInterface { + + /** + * GPSPhoneGateway takes 2 inputs + * - Room identifier (getRoomID) + * - Phone status (getRingStatus: ringing/not ringing) + */ + String setRoomID(Integer iId); + String setRingStatus(Boolean bStatus); +} diff --git a/benchmarks/drivers/IHome/IHome.config b/benchmarks/drivers/IHome/IHome.config new file mode 100644 index 0000000..276b02e --- /dev/null +++ b/benchmarks/drivers/IHome/IHome.config @@ -0,0 +1 @@ +INTERFACE_CLASS=Speaker \ No newline at end of file diff --git a/benchmarks/drivers/IHome/IHome.java b/benchmarks/drivers/IHome/IHome.java new file mode 100644 index 0000000..a9bcf0d --- /dev/null +++ b/benchmarks/drivers/IHome/IHome.java @@ -0,0 +1,970 @@ +package iotcode.IHome; + +// IoT Packages +import iotcode.interfaces.*; +import iotcode.annotation.*; +import iotruntime.IoTUDP; +import iotruntime.IoTTCP; +import iotruntime.slave.IoTSet; +import iotruntime.slave.IoTDeviceAddress; + +// RMI Packages +import java.rmi.Remote; +import java.rmi.RemoteException; + +// Checker annotations +//import iotchecker.qual.*; + +// Standard Java Packages +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.Map; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.List; +import java.util.ArrayList; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.PrintWriter; +import java.io.ByteArrayInputStream; +import java.util.LinkedList; +import java.util.concurrent.Semaphore; +import java.util.concurrent.CopyOnWriteArrayList; + + +public class IHome implements Speaker { + + + /******************************************************************************************************************************************* + ** Constants + *******************************************************************************************************************************************/ + + public static final float VOLUME_MUTED_VALUE_DB = (float) (-144.0); + public static final float VOLUME_MIN_VALUE_DB = (float) (-30.0); + public static final float VOLUME_MAX_VALUE_DB = (float) (-0.0); + public static final float DEFAULT_VOLUME = (float) (30.0); + + public static final long SEQUENCE_NUMBER_INITIAL_VALUE = 18086; + public static final long SEQUENCE_NUMBER_WRAP_AROUND = 32768L; + public static final long RTP_TIMESTAMP_INITIAL_VALUE = 3132223670L; + public static final long RTP_TIMESTAMP_INCREMENT_VALUE = 352L; + public static final long SOURCE_ID = 1326796157; + public static final long SEQUENCE_ID = 0x86b27741; + + private IoTDeviceAddress tcpAddress = null; + private IoTDeviceAddress myAddress = null; + private IoTDeviceAddress controlAddress = null; + private IoTDeviceAddress timingAddress = null; + private IoTDeviceAddress serverAddress = null; + + private IoTTCP iHomeTCPConnection = null; + + private AtomicBoolean driverIsShuttingDown = new AtomicBoolean(); + private boolean didClose = false; + + private AtomicBoolean didEnd = new AtomicBoolean(); + private AtomicBoolean playbackStarted = new AtomicBoolean(); + private AtomicBoolean playbackFileIsDone = new AtomicBoolean(); + private AtomicBoolean isDoneEnding = new AtomicBoolean(); + private AtomicBoolean playbackState = new AtomicBoolean(); + + private AtomicBoolean didInit = new AtomicBoolean(); + private AtomicBoolean playbackAboutToStart = new AtomicBoolean(); + private AtomicBoolean settingVolume = new AtomicBoolean(); + private AtomicBoolean playbackAboutToStop = new AtomicBoolean(); + + + + private long sequenceNumber = SEQUENCE_NUMBER_INITIAL_VALUE; + private long rtpTimestamp = RTP_TIMESTAMP_INITIAL_VALUE; + + private long currentPlaybackTime = 0; + static Semaphore currentPlaybackTimeMutex = new Semaphore(1); + + private long desiredPlaybackTime = 0; + static Semaphore desiredPlaybackTimeMutex = new Semaphore(1); + + + private String connectionURL = ""; + private float currentVolume = DEFAULT_VOLUME; + private LinkedList audioLinkedList = new LinkedList(); + + private List < SpeakerSmartCallback > callbackList = new CopyOnWriteArrayList< SpeakerSmartCallback > (); + + /******************************************************************************************************************************************* + ** Threads + *******************************************************************************************************************************************/ + private Thread timingThread = null; + private Thread audioThread = null; + private Thread controlThread = null; + private Thread monitorThread = null; + + + @config private IoTSet speakerAddresses; + + public IHome() { + didInit.set(false); + playbackAboutToStart.set(false); + settingVolume.set(false); + } + + /******************************************************************************************************************************************* + ** + ** Speaker Interface Methods + ** + *******************************************************************************************************************************************/ + + public void init() { + + if (didInit.compareAndSet(false, true) == false) { + return; // already init + } + + didEnd.set(false); + isDoneEnding.set(true); + playbackFileIsDone.set(false); + Map addrCount = new HashMap(); + + + // get correct addresses + for (IoTDeviceAddress devAdrr : speakerAddresses.values()) { + if (addrCount.containsKey(devAdrr.getAddress())) { + addrCount.put(devAdrr.getAddress(), addrCount.get(devAdrr.getAddress()) + 1); + } else { + addrCount.put(devAdrr.getAddress(), 1); + } + } + + for (IoTDeviceAddress devAdrr : speakerAddresses.values()) { + if (addrCount.get(devAdrr.getAddress()) <= 1) { + myAddress = devAdrr; + } else { + if (devAdrr.getIsDstPortWildcard()) { + if (controlAddress == null) { + controlAddress = devAdrr; + } else if (timingAddress == null) { + timingAddress = devAdrr; + } else { + serverAddress = devAdrr; + } + } else { + tcpAddress = devAdrr; + } + } + } + + System.out.println("tcpAddress: " + tcpAddress.getAddress() + ":" + tcpAddress.getSourcePortNumber() + + ":" + tcpAddress.getDestinationPortNumber()); + System.out.println("myAddress: " + myAddress.getAddress() + ":" + myAddress.getSourcePortNumber() + + ":" + myAddress.getDestinationPortNumber()); + System.out.println("controlAddress: " + controlAddress.getAddress() + ":" + controlAddress.getSourcePortNumber() + + ":" + controlAddress.getDestinationPortNumber()); + System.out.println("timingAddress: " + timingAddress.getAddress() + ":" + timingAddress.getSourcePortNumber() + + ":" + timingAddress.getDestinationPortNumber()); + System.out.println("serverAddress: " + serverAddress.getAddress() + ":" + serverAddress.getSourcePortNumber() + + ":" + serverAddress.getDestinationPortNumber()); + + // Launch the worker function in a separate thread. + monitorThread = new Thread(new Runnable() { + public void run() { + monitorThreadWorker(); + } + }); + monitorThread.start(); + } + + + + public boolean startPlayback() { + + + if (playbackAboutToStart.compareAndSet(false, true) == false) { + return false; + } + + if (playbackStarted.get()) { + return true; + } + + if (isDoneEnding.get() == false) { + return false; + } + + // Reset all Parameters + didEnd.set(false); + playbackFileIsDone.set(false); + playbackState.set(true); + + try { + currentPlaybackTimeMutex.acquire(); + currentPlaybackTime = 0; + } catch (Exception e) { + e.printStackTrace(); + } + currentPlaybackTimeMutex.release(); + + + + try { + desiredPlaybackTimeMutex.acquire(); + desiredPlaybackTime = 0; + } catch (Exception e) { + e.printStackTrace(); + } + desiredPlaybackTimeMutex.release(); + + sequenceNumber = SEQUENCE_NUMBER_INITIAL_VALUE; + rtpTimestamp = RTP_TIMESTAMP_INITIAL_VALUE; + + try { + // start TCP connection + iHomeTCPConnection = new IoTTCP(tcpAddress); + iHomeTCPConnection.setReuseAddress(true); + + // Get in and out communication + PrintWriter tcpOut = new PrintWriter(iHomeTCPConnection.getOutputStream(), true); + BufferedReader tcpIn = new BufferedReader(new InputStreamReader(iHomeTCPConnection.getInputStream())); + + + String session = String.valueOf(SOURCE_ID); + connectionURL = "rtsp://" + myAddress.getAddress() + "/" + session; + + // Construct The commands + String optionsCommand = "OPTIONS * RTSP/1.0\r\n" + + "CSeq: 1\r\n" + + "User-Agent: iTunes/11.0.4 (Windows; N)\r\n" + + "Client-Instance: c0cb804fd20e80f6\r\n" + + "Apple-Challenge: i8j36XRYVmSZs9nZ7Kf0Cg\r\n\r\n"; + + String announceCommandBody = "v=0\r\n" + + "o=iTunes " + session + " 0 IN IP4 " + myAddress.getAddress() + "\r\n" + + "s=iTunes\r\n" + + "c=IN IP4 " + tcpAddress.getAddress() + "\r\n" + + "t=0 0\r\n" + + "m=audio 0 RTP/AVP 96\r\n" + + "a=rtpmap:96 AppleLossless\r\n" + + "a=fmtp:96 352 0 16 40 10 14 2 255 0 0 44100\r\n"; + + String announceCommand = "ANNOUNCE " + connectionURL + " RTSP/1.0\r\n" + + "CSeq: 1\r\n" + + "Content-Type: application/sdp\r\n" + + "Content-Length: " + announceCommandBody.length() + "\r\n" + + "User-Agent: iTunes/11.0.4 (Windows; N)\r\n\r\n" + + announceCommandBody; + + + // get the ports that we are going to tell the iHome to use + int ourControlPort = controlAddress.getSourcePortNumber(); + int ourTimingPort = timingAddress.getSourcePortNumber(); + + String setupCommand = "SETUP " + connectionURL + " RTSP/1.0\r\n" + + "CSeq: 2\r\n" + + "Transport: RTP/AVP/UDP;unicast;interleaved=0-1;mode=record;control_port=" + Integer.toString(ourControlPort) + ";timing_port=" + Integer.toString(ourTimingPort) + "\r\n" + + "User-Agent: iTunes/11.0.4 (Windows; N)\r\n\r\n"; + + String recordCommand = "RECORD " + connectionURL + " RTSP/1.0\r\nCSeq: 3\r\nSession: 1\r\nRange: npt=0-\r\nRTP-Info: seq=" + sequenceNumber + ";rtptime=" + rtpTimestamp + "\r\nUser-Agent: iTunes/11.0.4 (Windows; N)\r\n\r\n"; + + + Thread.sleep(100); + tcpOut.print(optionsCommand); + tcpOut.flush(); + while (!tcpIn.ready()) { + } + while (tcpIn.ready()) { + String answer = tcpIn.readLine(); + System.out.println(answer); + } + + Thread.sleep(100); + tcpOut.print(announceCommand); + tcpOut.flush(); + + while (!tcpIn.ready()) { + } + while (tcpIn.ready()) { + String answer = tcpIn.readLine(); + System.out.println(answer); + } + + Thread.sleep(100); + tcpOut.print(setupCommand); + tcpOut.flush(); + while (!tcpIn.ready()) { + } + + // ports that the speaker told us to communicate over + int serverPort = -1; + int controlPort = -1; + int timingPort = -1; + + while (tcpIn.ready()) { + String answer = tcpIn.readLine(); + System.out.println(answer); + + if (answer.contains("Transport")) { + + String[] splitString = answer.split(";"); + + for (String str : splitString) { + String[] keyValue = str.split("="); + + if (keyValue.length == 2) { + if (keyValue[0].equals("server_port")) { + serverPort = Integer.parseInt(keyValue[1]); + + } else if (keyValue[0].equals("control_port")) { + controlPort = Integer.parseInt(keyValue[1]); + + } else if (keyValue[0].equals("timing_port")) { + timingPort = Integer.parseInt(keyValue[1]); + } + + } + } + + } + } + + serverAddress.setDstPort(serverPort); + controlAddress.setDstPort(controlPort); + timingAddress.setDstPort(timingPort); + + // Launch the worker function in a separate thread. + // Must launch timing thread before record message since record message + // syncs with timing + timingThread = new Thread(new Runnable() { + public void run() { + timingWorkerFunction(); + } + }); + timingThread.start(); + + + // give the timing thread some time to set itself up + Thread.sleep(100); + + tcpOut.print(recordCommand); + tcpOut.flush(); + while (!tcpIn.ready()) { + } + while (tcpIn.ready()) { + String answer = tcpIn.readLine(); + System.out.println(answer); + } + + + + + // Launch the worker function in a separate thread. + controlThread = new Thread(new Runnable() { + public void run() { + controlWorkerFunction(); + } + }); + controlThread.start(); + + + playbackFileIsDone.set(false); + + // wait for audio Data + Thread.sleep(1000); + + // Launch the worker function in a separate thread. + audioThread = new Thread(new Runnable() { + public void run() { + audioWorkerFunction(); + } + }); + audioThread.start(); + + + + + // playback has officially Started + playbackStarted.set(true); + + // playback started + playbackAboutToStart.set(true); + + // Set the volume to the current volume + setVolume(currentVolume); + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + return true; + } + + public boolean stopPlayback() { + + if (playbackAboutToStop.compareAndSet(false, true) == false) { + return false; + } + + isDoneEnding.set(false); + playbackState.set(false); + if (playbackStarted.get() == false) { + return false; + } + + playbackStarted.set(false); + didEnd.set(true); + + try { + timingThread.join(); + audioThread.join(); + controlThread.join(); + } catch (Exception e) { + e.printStackTrace(); + } + + isDoneEnding.set(true); + + + String teardownCommand = "TEARDOWN " + connectionURL + " RTSP/1.0\r\n" + + "CSeq: 32\r\n" + + "Session: 1\r\n" + + "User-Agent: iTunes/11.0.4 (Windows; N)\r\n\r\n"; + + + + try { + // Get in and out communication + PrintWriter tcpOut = new PrintWriter(iHomeTCPConnection.getOutputStream(), true); + BufferedReader tcpIn = new BufferedReader(new InputStreamReader(iHomeTCPConnection.getInputStream())); + + tcpOut.print(teardownCommand); + tcpOut.flush(); + while (!tcpIn.ready()) { + } + while (tcpIn.ready()) { + String answer = tcpIn.readLine(); + System.out.println(answer); + } + + // close the connection + iHomeTCPConnection.close(); + + } catch (Exception e) { + e.printStackTrace(); + } + + playbackAboutToStop.set(false); + + return true; + } + + + public boolean getPlaybackState() { + return playbackState.get(); + } + + public boolean setVolume(float _percent) { + + if (settingVolume.compareAndSet(false, true) == false) { + return false; + } + + // keep in range of percentage + if (_percent < 0) { + _percent = 0; + } else if (_percent > 100) { + _percent = 100; + } + + // cant set the volume if there is no playback + if (playbackStarted.get() == false) { + return false; + } + + // convert the volume from a percentage to a db + float dbVolume = 0; + if (_percent > 0) { + + dbVolume = ((float)(_percent / 100.0) * (float)(VOLUME_MAX_VALUE_DB - VOLUME_MIN_VALUE_DB)) + (float)VOLUME_MIN_VALUE_DB; + + // cap the volume to a level that the speaker supports + if (dbVolume > VOLUME_MAX_VALUE_DB) { + dbVolume = VOLUME_MAX_VALUE_DB; + } + } + + // construct the command + String body = "volume: " + String.format("%f", dbVolume) + "\r\n"; + String volumeCommand = "SET_PARAMETER " + connectionURL + " RTSP/1.0\r\nCSeq: 4\r\nSession: 1\r\nContent-Type: text/parameters\r\nContent-Length: " + body.length() + "\r\nUser-Agent: iTunes/11.0.4 (Windows; N)\r\n\r\n" + body; + + + + try { + // Get in and out communication + PrintWriter tcpOut = new PrintWriter(iHomeTCPConnection.getOutputStream(), true); + BufferedReader tcpIn = new BufferedReader(new InputStreamReader(iHomeTCPConnection.getInputStream())); + + // send and flush + tcpOut.print(volumeCommand); + tcpOut.flush(); + + // Wait for data to come back + while (!tcpIn.ready()) { + } + + // read the data from the iHome + while (tcpIn.ready()) { + String answer = tcpIn.readLine(); + System.out.println(answer); + } + + // update the current volume parameter + currentVolume = _percent; + } catch (Exception e) { + e.printStackTrace(); + } + + settingVolume.set(false); + + return true; + } + + public float getVolume() { + + while (settingVolume.get()) { + // block until volume set is done + } + return currentVolume; + } + + public void loadData(short[] _samples, int _offs, int _len) { + + short[] sample = new short[_len]; + int j = _offs; + for (int i = 0; i < _len; i++, j++) { + sample[i] = _samples[j]; + } + synchronized (audioLinkedList) { + audioLinkedList.addLast(sample); + } + } + + public void clearData() { + synchronized (audioLinkedList) { + audioLinkedList.clear(); + } + } + + public int getPosition() { + long pTime = 0; + try { + currentPlaybackTimeMutex.acquire(); + pTime = currentPlaybackTime; + } catch (Exception e) { + e.printStackTrace(); + } + currentPlaybackTimeMutex.release(); + + int mSecPos = (int)((pTime * 1000) / 44100); + return mSecPos; + } + + public void setPosition(int _mSec) { + int sampleNumber = (_mSec * 44100) / 1000; + + try { + desiredPlaybackTimeMutex.acquire(); + desiredPlaybackTime = sampleNumber; + } catch (Exception e) { + e.printStackTrace(); + } + desiredPlaybackTimeMutex.release(); + } + + + public void registerCallback(SpeakerSmartCallback _cb) { + callbackList.add(_cb); + } + + + /******************************************************************************************************************************************* + ** + ** Helper Methods + ** + *******************************************************************************************************************************************/ + + + private void timingWorkerFunction() { + try { + IoTUDP timingUDP = new IoTUDP(timingAddress); + + byte[] receiveData = new byte[1024]; + byte[] sendData = new byte[32]; + + while (didEnd.get() == false) { + + receiveData = timingUDP.recieveData(receiveData.length); + + long nanotime = nanoTime(); + int seconds = (int)((nanotime / 1000000000) & 0xffffffff); + long fractions = ((( nanotime % 1000000000) * (0xffffffffL)) / 1000000000); + + sendData[0] = (byte)0x80; // Header bit field + sendData[1] = (byte)0xd3; // mark bit and message payload number + + sendData[2] = (byte) 0x00; + sendData[3] = (byte) 0x07; + + sendData[4] = (byte) 0x00; + sendData[5] = (byte) 0x00; + sendData[6] = (byte) 0x00; + sendData[7] = (byte) 0x00; + + // origin time-stamp + sendData[8] = receiveData[24]; + sendData[9] = receiveData[25]; + sendData[10] = receiveData[26]; + sendData[11] = receiveData[27]; + sendData[12] = receiveData[28]; + sendData[13] = receiveData[29]; + sendData[14] = receiveData[30]; + sendData[15] = receiveData[31]; + + // arrival time-stamp + sendData[16] = (byte)((seconds >> 24) & 0xff); + sendData[17] = (byte)((seconds >> 16) & 0xff); + sendData[18] = (byte)((seconds >> 8) & 0xff); + sendData[19] = (byte)((seconds >> 0) & 0xff); + sendData[20] = (byte)((fractions >> 24) & 0xff); + sendData[21] = (byte)((fractions >> 16) & 0xff); + sendData[22] = (byte)((fractions >> 8) & 0xff); + sendData[23] = (byte)((fractions >> 0) & 0xff); + + + nanotime = nanoTime(); + seconds = (int)( nanotime / 1000000000); + fractions = ((( nanotime % 1000000000) * (0xffffffffL)) / 1000000000); + + // transmit time-stamp + sendData[24] = (byte)((seconds >> 24) & 0xff); + sendData[25] = (byte)((seconds >> 16) & 0xff); + sendData[26] = (byte)((seconds >> 8) & 0xff); + sendData[27] = (byte)((seconds >> 0) & 0xff); + sendData[28] = (byte)((fractions >> 24) & 0xff); + sendData[29] = (byte)((fractions >> 16) & 0xff); + sendData[30] = (byte)((fractions >> 8) & 0xff); + sendData[31] = (byte)((fractions >> 0) & 0xff); + + // Send the Data + timingUDP.sendData(sendData); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void controlWorkerFunction() { + + try { + + IoTUDP controlUDP = new IoTUDP(controlAddress); + controlUDP.setSoTimeout(1); + byte[] sendData = new byte[20]; + boolean first = true; + + + while (didEnd.get() == false) { + + try { + byte[] receiveData = new byte[24]; + receiveData = controlUDP.recieveData(receiveData.length); + + // System.out.println("Control Packet Arrived"); + // String packetData = bytesToHex(receiveData); + // System.out.println(packetData); + + } catch (Exception e) { + // e.printStackTrace(); + } + + + long rtpTimestampCopy = rtpTimestamp; + long nanotime = nanoTime(); + int seconds = (int)( nanotime / 1000000000); + long fractions = (( nanotime % 1000000000) * (0xffffffffL)) / 1000000000; + + + if (first) { + sendData[0] = (byte)0x90; // Header bit field + first = false; + } else { + sendData[0] = (byte)0x80; // Header bit field + } + + + sendData[1] = (byte)0xd4; // mark bit and message payload number + sendData[2] = (byte)0x00; + sendData[3] = (byte)0x07; + + // time-stamp of packet + sendData[4] = (byte)((rtpTimestampCopy >> 24) & 0xFF); + sendData[5] = (byte)((rtpTimestampCopy >> 16) & 0xFF); + sendData[6] = (byte)((rtpTimestampCopy >> 8) & 0xFF); + sendData[7] = (byte)((rtpTimestampCopy >> 0) & 0xFF); + + // ntp time-stamp + sendData[8] = (byte)((seconds >> 24) & 0xff); + sendData[9] = (byte)((seconds >> 16) & 0xff); + sendData[10] = (byte)((seconds >> 8) & 0xff); + sendData[11] = (byte)((seconds >> 0) & 0xff); + + sendData[12] = (byte)((fractions >> 24) & 0xff); + sendData[13] = (byte)((fractions >> 16) & 0xff); + sendData[14] = (byte)((fractions >> 8) & 0xff); + sendData[15] = (byte)((fractions >> 0) & 0xff); + + rtpTimestampCopy += 88200; + sendData[16] = (byte)((rtpTimestampCopy >> 24) & 0xFF); + sendData[17] = (byte)((rtpTimestampCopy >> 16) & 0xFF); + sendData[18] = (byte)((rtpTimestampCopy >> 8) & 0xFF); + sendData[19] = (byte)((rtpTimestampCopy >> 0) & 0xFF); + + // send the data + controlUDP.sendData(sendData); + + // System.out.println("---------------------------------------------"); + // System.out.println("Sending Control Sync"); + // System.out.println("---------------------------------------------"); + + Thread.sleep(1000); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void audioWorkerFunction() { + try { + + IoTUDP serverUDP = new IoTUDP(serverAddress); + + // current frame being played + long frameCounter = 0; + + // used for bit packing for audio stream + short[] array = null; + int offset = 0; + + int noAudioCount = 0; + + while (didEnd.get() == false) { + + byte[] sendData = new byte[352 * 4 + 19]; + + sendData[0] = (byte)0x80; + + if (frameCounter == 0) { + sendData[1] = (byte)0xe0; + // frameCounter = 1; + } else { + sendData[1] = (byte)0x60; + } + + sendData[2] = (byte)((sequenceNumber >> 8) & 0xFF); + sendData[3] = (byte)((sequenceNumber >> 0) & 0xFF); + + long rtpTmp = rtpTimestamp; + + sendData[4] = (byte)((rtpTmp >> 24) & 0xFF); + sendData[5] = (byte)((rtpTmp >> 16) & 0xFF); + sendData[6] = (byte)((rtpTmp >> 8) & 0xFF); + sendData[7] = (byte)((rtpTmp >> 0) & 0xFF); + + sendData[8] = (byte)((SEQUENCE_ID >> 24) & 0xFF); + sendData[9] = (byte)((SEQUENCE_ID >> 16) & 0xFF); + sendData[10] = (byte)((SEQUENCE_ID >> 8) & 0xFF); + sendData[11] = (byte)((SEQUENCE_ID >> 0) & 0xFF); + + sendData[12] = (byte) 0x20; + sendData[13] = (byte) 0x00; + sendData[14] = (byte) 0x12; + sendData[15] = (byte) 0x00; + sendData[16] = (byte) 0x00; + sendData[17] = (byte) 0x02; + sendData[18] = (byte) 0xc0; + + for (int i = 19; i < sendData.length; i += 4) { + if (array != null && (offset + 1) >= array.length) { + array = null; + } + + if (array == null) { + offset = 0; + + synchronized (audioLinkedList) { + array = (short[])audioLinkedList.poll(); + } + } + + if (array != null) { + + long time1 = 0; + long time2 = 0; + + try { + desiredPlaybackTimeMutex.acquire(); + time1 = desiredPlaybackTime; + } catch (Exception e) { + e.printStackTrace(); + } + + desiredPlaybackTimeMutex.release(); + + + try { + currentPlaybackTimeMutex.acquire(); + time2 = currentPlaybackTime; + } catch (Exception e) { + e.printStackTrace(); + } + currentPlaybackTimeMutex.release(); + + + while ((time2 < time1)) { + offset++; + + try { + currentPlaybackTimeMutex.acquire(); + currentPlaybackTime++; + } catch (Exception e) { + e.printStackTrace(); + } + currentPlaybackTimeMutex.release(); + + + if ((offset + 1) >= array.length) { + offset = 0; + synchronized (audioLinkedList) { + array = (short[])audioLinkedList.poll(); + } + + if (array == null) { + break; + } + } + } + } + + short l = 0; + short r = 0; + + if (array != null) { + l = array[offset++]; + r = array[offset++]; + + try { + currentPlaybackTimeMutex.acquire(); + currentPlaybackTime++; + } catch (Exception e) { + e.printStackTrace(); + } + currentPlaybackTimeMutex.release(); + + + try { + desiredPlaybackTimeMutex.acquire(); + desiredPlaybackTime++; + } catch (Exception e) { + e.printStackTrace(); + } + + desiredPlaybackTimeMutex.release(); + + noAudioCount = 0; + } else { + noAudioCount++; + + if (noAudioCount > 10) { + noAudioCount = 0; + if (playbackFileIsDone.get() == false) { + playbackFileIsDone.set(true); + } + } + } + + sendData[i - 1] |= (byte)((l >> 15) & 1); + sendData[i] = (byte)((l >> 7) & 0xff); + sendData[i + 1] = (byte)(((l << 1) & 0xfe) | ((r >> 15) & 1)); + sendData[i + 2] = (byte)((r >> 7) & 0xff); + sendData[i + 3] = (byte)((r << 1) & 0xfe); + } + + + sequenceNumber++; + sequenceNumber = sequenceNumber % SEQUENCE_NUMBER_WRAP_AROUND; + rtpTimestamp += RTP_TIMESTAMP_INCREMENT_VALUE; + + frameCounter++; + serverUDP.sendData(sendData); + + + // need to sleep for a bit + if ((frameCounter % 2) == 0) { + Thread.sleep(7); + } else { + Thread.sleep(6); + } + + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void monitorThreadWorker() { + while (driverIsShuttingDown.get() == false) { + if (playbackFileIsDone.get()) { + stopPlayback(); + playbackFileIsDone.set(false); + + for (SpeakerSmartCallback c : callbackList) { + try { + //c.speakerDone(this); + c.speakerDone(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } + + private void endDriver() { + stopPlayback(); + + driverIsShuttingDown.set(true); + try { + monitorThread.join(); + } catch (Exception e) { + e.printStackTrace(); + } + + didClose = true; + } + + /** + * close() called by the garbage collector right before trashing object + */ + public void finalize() { + if (!didClose) { + endDriver(); + } + } + + private static long nanoTime() { + long nanotime = System.nanoTime(); + return nanotime; + } +} + + + + diff --git a/benchmarks/drivers/Makefile b/benchmarks/drivers/Makefile index 342d3fb..5e6706b 100644 --- a/benchmarks/drivers/Makefile +++ b/benchmarks/drivers/Makefile @@ -10,7 +10,7 @@ JFLAGS = -d $(BIN_DIR) -cp $(BIN_DIR):$(PHONEJARS):$(BOOFJARS):$(JLAYERJARS) JARFLAGS = cf INTFACE_DIR = iotcode/interfaces -all: light camera labroom greenlawn sprinkler moisture weathergateway +all: light camera labroom greenlawn sprinkler moisture weathergateway audioroom gpsgateway ihome # Compile # @@ -56,4 +56,22 @@ weathergateway: cp WeatherPhoneGateway/WeatherPhoneGateway.config $(BIN_DIR)/iotcode/WeatherPhoneGateway cd $(BIN_DIR)/iotcode/WeatherPhoneGateway; $(JAR) $(JARFLAGS) WeatherPhoneGateway.jar ../../iotcode/WeatherPhoneGateway/*.class ../../iotcode/interfaces/WeatherGateway*.class +PHONY += audioroom +audioroom: + $(JAVAC) $(JFLAGS) AudioRoom/*.java + cp AudioRoom/AudioRoom.config $(BIN_DIR)/iotcode/AudioRoom + cd $(BIN_DIR)/iotcode/AudioRoom; $(JAR) $(JARFLAGS) AudioRoom.jar ../../iotcode/AudioRoom/*.class ../../iotcode/interfaces/Room*.class + +PHONY += gpsgateway +gpsgateway: + $(JAVAC) $(JFLAGS) GPSPhoneGateway/*.java + cp GPSPhoneGateway/GPSPhoneGateway.config $(BIN_DIR)/iotcode/GPSPhoneGateway + cd $(BIN_DIR)/iotcode/GPSPhoneGateway; $(JAR) $(JARFLAGS) GPSPhoneGateway.jar ../../iotcode/GPSPhoneGateway/*.class ../../iotcode/interfaces/GPSGateway*.class + +PHONY += ihome +ihome: + $(JAVAC) $(JFLAGS) IHome/*.java + cp IHome/IHome.config $(BIN_DIR)/iotcode/IHome + cd $(BIN_DIR)/iotcode/IHome; $(JAR) $(JARFLAGS) IHome.jar ../../iotcode/IHome/*.class ../../iotcode/interfaces/Speaker*.class + .PHONY: $(PHONY) diff --git a/benchmarks/interfaces/GPSGateway.java b/benchmarks/interfaces/GPSGateway.java new file mode 100644 index 0000000..243ae87 --- /dev/null +++ b/benchmarks/interfaces/GPSGateway.java @@ -0,0 +1,15 @@ +package iotcode.interfaces; + +import java.util.List; +import java.util.ArrayList; + +public interface GPSGateway { + public void init(); + public void start(); + public void stop(); + public int getRoomID(); + public boolean getRingStatus(); + public void setNewRoomIDAvailable(boolean bValue); + public void setNewRingStatusAvailable(boolean bValue); + public void registerCallback(GPSGatewaySmartCallback _callbackTo); +} diff --git a/benchmarks/interfaces/GPSGatewayCallback.java b/benchmarks/interfaces/GPSGatewayCallback.java new file mode 100644 index 0000000..c07b893 --- /dev/null +++ b/benchmarks/interfaces/GPSGatewayCallback.java @@ -0,0 +1,9 @@ +package iotcode.interfaces; + +import java.util.List; +import java.util.ArrayList; + +public interface GPSGatewayCallback { + public void newRoomIDRetrieved(int _roomIdentifier); + public void newRingStatusRetrieved(boolean _ringStatus); +} diff --git a/benchmarks/interfaces/GPSGatewaySmart.java b/benchmarks/interfaces/GPSGatewaySmart.java new file mode 100644 index 0000000..542ae43 --- /dev/null +++ b/benchmarks/interfaces/GPSGatewaySmart.java @@ -0,0 +1,16 @@ +package iotcode.interfaces; + +import java.util.List; +import java.util.ArrayList; + +public interface GPSGatewaySmart { + + public void setNewRoomIDAvailable(boolean bValue); + public void setNewRingStatusAvailable(boolean bValue); + public void stop(); + public void start(); + public void init(); + public int getRoomID(); + public void registerCallback(GPSGatewayCallback _callbackTo); + public boolean getRingStatus(); +} diff --git a/benchmarks/interfaces/GPSGatewaySmartCallback.java b/benchmarks/interfaces/GPSGatewaySmartCallback.java new file mode 100644 index 0000000..2bfed5f --- /dev/null +++ b/benchmarks/interfaces/GPSGatewaySmartCallback.java @@ -0,0 +1,10 @@ +package iotcode.interfaces; + +import java.util.List; +import java.util.ArrayList; + +public interface GPSGatewaySmartCallback { + + public void newRoomIDRetrieved(int _roomIdentifier); + public void newRingStatusRetrieved(boolean _ringStatus); +} diff --git a/benchmarks/interfaces/Speaker.java b/benchmarks/interfaces/Speaker.java new file mode 100644 index 0000000..c6406f0 --- /dev/null +++ b/benchmarks/interfaces/Speaker.java @@ -0,0 +1,18 @@ +package iotcode.interfaces; + +import java.util.List; +import java.util.ArrayList; + +public interface Speaker { + public void init(); + public boolean startPlayback(); + public boolean stopPlayback(); + public boolean getPlaybackState(); + public boolean setVolume(float _percent); + public float getVolume(); + public int getPosition(); + public void setPosition(int _mSec); + public void loadData(short _samples[], int _offs, int _len); + public void clearData(); + public void registerCallback(SpeakerSmartCallback _cb); +} diff --git a/benchmarks/interfaces/SpeakerCallback.java b/benchmarks/interfaces/SpeakerCallback.java new file mode 100644 index 0000000..0b3e343 --- /dev/null +++ b/benchmarks/interfaces/SpeakerCallback.java @@ -0,0 +1,8 @@ +package iotcode.interfaces; + +import java.util.List; +import java.util.ArrayList; + +public interface SpeakerCallback { + public void speakerDone(); +} diff --git a/benchmarks/interfaces/SpeakerSmart.java b/benchmarks/interfaces/SpeakerSmart.java new file mode 100644 index 0000000..336ce8c --- /dev/null +++ b/benchmarks/interfaces/SpeakerSmart.java @@ -0,0 +1,19 @@ +package iotcode.interfaces; + +import java.util.List; +import java.util.ArrayList; + +public interface SpeakerSmart { + + public int getPosition(); + public boolean stopPlayback(); + public void clearData(); + public boolean startPlayback(); + public boolean getPlaybackState(); + public boolean setVolume(float _percent); + public float getVolume(); + public void setPosition(int _mSec); + public void loadData(short _samples[], int _offs, int _len); + public void init(); + public void registerCallback(SpeakerCallback _cb); +} diff --git a/benchmarks/interfaces/SpeakerSmartCallback.java b/benchmarks/interfaces/SpeakerSmartCallback.java new file mode 100644 index 0000000..a2213bb --- /dev/null +++ b/benchmarks/interfaces/SpeakerSmartCallback.java @@ -0,0 +1,9 @@ +package iotcode.interfaces; + +import java.util.List; +import java.util.ArrayList; + +public interface SpeakerSmartCallback { + + public void speakerDone(); +} diff --git a/iotjava/Makefile b/iotjava/Makefile index dd425ca..f996ce5 100644 --- a/iotjava/Makefile +++ b/iotjava/Makefile @@ -76,6 +76,25 @@ run-compiler-moist: cp ../localconfig/iotpolicy/SpruceSensor/*.req $(BIN_DIR)/iotpolicy/ cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler sprucesensor.pol smartsensor.req moisturesensorcallback.pol moisturesensorcallback.req -java Java +# SpeakerController +PHONY += run-compiler-audiorm +run-compiler-audiorm: + cp ../localconfig/iotpolicy/AudioRoom/*.pol $(BIN_DIR)/iotpolicy/ + cp ../localconfig/iotpolicy/AudioRoom/*.req $(BIN_DIR)/iotpolicy/ + cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler audioroom.pol roomsmart.req -java Java + +PHONY += run-compiler-spkr +run-compiler-spkr: + cp ../localconfig/iotpolicy/IHome/*.pol $(BIN_DIR)/iotpolicy/ + cp ../localconfig/iotpolicy/IHome/*.req $(BIN_DIR)/iotpolicy/ + cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler ihome.pol smartspeaker.req speakercallback.pol smartspeakercallback.req -java Java + +PHONY += run-compiler-ggw +run-compiler-ggw: + cp ../localconfig/iotpolicy/GPSPhoneGateway/*.pol $(BIN_DIR)/iotpolicy/ + cp ../localconfig/iotpolicy/GPSPhoneGateway/*.req $(BIN_DIR)/iotpolicy/ + cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler gpsphonegateway.pol smartgpsgateway.req gpsgatewaycallback.pol smartgpsgatewaycallback.req -java Java + # TODO: Can remove this later - just to test-compile the resulted files from the compiler PHONY += compile compile: diff --git a/localconfig/iotpolicy/AudioRoom/audioroom.pol b/localconfig/iotpolicy/AudioRoom/audioroom.pol new file mode 100644 index 0000000..17f3bbd --- /dev/null +++ b/localconfig/iotpolicy/AudioRoom/audioroom.pol @@ -0,0 +1,11 @@ +public interface Room { + + public int getRoomID(); + + capability Basic { + description = "Get room ID"; + method = "getRoomID()"; + } +} + + diff --git a/localconfig/iotpolicy/AudioRoom/roomsmart.req b/localconfig/iotpolicy/AudioRoom/roomsmart.req new file mode 100644 index 0000000..71de3c9 --- /dev/null +++ b/localconfig/iotpolicy/AudioRoom/roomsmart.req @@ -0,0 +1,3 @@ + +requires Room with Basic as interface RoomSmart; + diff --git a/localconfig/iotpolicy/GPSPhoneGateway/gpsgatewaycallback.pol b/localconfig/iotpolicy/GPSPhoneGateway/gpsgatewaycallback.pol new file mode 100644 index 0000000..984c39a --- /dev/null +++ b/localconfig/iotpolicy/GPSPhoneGateway/gpsgatewaycallback.pol @@ -0,0 +1,13 @@ +public interface GPSGatewayCallback { + + public void newRoomIDRetrieved(int _roomIdentifier); + public void newRingStatusRetrieved(boolean _ringStatus); + + capability Callback { + description = "Callback methods"; + method = "newRoomIDRetrieved(int _roomIdentifier)"; + method = "newRingStatusRetrieved(boolean _ringStatus)"; + } +} + + diff --git a/localconfig/iotpolicy/GPSPhoneGateway/gpsphonegateway.pol b/localconfig/iotpolicy/GPSPhoneGateway/gpsphonegateway.pol new file mode 100644 index 0000000..5a1e769 --- /dev/null +++ b/localconfig/iotpolicy/GPSPhoneGateway/gpsphonegateway.pol @@ -0,0 +1,29 @@ +public interface GPSGateway { + + public void init(); + public void start(); + public void stop(); + public int getRoomID(); + public boolean getRingStatus(); + public void setNewRoomIDAvailable(boolean bValue); + public void setNewRingStatusAvailable(boolean bValue); + public void registerCallback(GPSGatewayCallback _callbackTo); + + capability Initialize { + description = "Initialize object"; + method = "init()"; + method = "start()"; + method = "stop()"; + method = "registerCallback(GPSGatewayCallback _callbackTo)"; + } + + capability GPSUpdate { + description = "Manage GPS data update"; + method = "getRoomID()"; + method = "getRingStatus()"; + method = "setNewRoomIDAvailable(boolean bValue)"; + method = "setNewRingStatusAvailable(boolean bValue)"; + } +} + + diff --git a/localconfig/iotpolicy/GPSPhoneGateway/smartgpsgateway.req b/localconfig/iotpolicy/GPSPhoneGateway/smartgpsgateway.req new file mode 100644 index 0000000..d2811b0 --- /dev/null +++ b/localconfig/iotpolicy/GPSPhoneGateway/smartgpsgateway.req @@ -0,0 +1,3 @@ + +requires GPSGateway with Initialize, GPSUpdate as interface GPSGatewaySmart; + diff --git a/localconfig/iotpolicy/GPSPhoneGateway/smartgpsgatewaycallback.req b/localconfig/iotpolicy/GPSPhoneGateway/smartgpsgatewaycallback.req new file mode 100644 index 0000000..b9e8ddf --- /dev/null +++ b/localconfig/iotpolicy/GPSPhoneGateway/smartgpsgatewaycallback.req @@ -0,0 +1,3 @@ + +requires GPSGatewayCallback with Callback as interface GPSGatewaySmartCallback; + diff --git a/localconfig/iotpolicy/IHome/ihome.pol b/localconfig/iotpolicy/IHome/ihome.pol new file mode 100644 index 0000000..520c974 --- /dev/null +++ b/localconfig/iotpolicy/IHome/ihome.pol @@ -0,0 +1,47 @@ +public interface Speaker { + + public void init(); + public boolean startPlayback(); + public boolean stopPlayback(); + public boolean getPlaybackState(); + public boolean setVolume(float _percent); + public float getVolume(); + public int getPosition(); + public void setPosition(int _mSec); + public void loadData(short _samples[], int _offs, int _len); + public void clearData(); + public void registerCallback(SpeakerCallback _cb); + + capability Initialize { + description = "Initialize object"; + method = "init()"; + method = "registerCallback(SpeakerCallback _cb)"; + } + + capability Playback { + description = "Manage playback"; + method = "startPlayback()"; + method = "stopPlayback()"; + method = "getPlaybackState()"; + } + + capability Volume { + description = "Manage volume"; + method = "setVolume(float _percent)"; + method = "getVolume()"; + } + + capability Position { + description = "Manage position in the song"; + method = "getPosition()"; + method = "setPosition(int _mSec)"; + } + + capability Data { + description = "Manage song data"; + method = "loadData(short _samples[], int _offs, int _len)"; + method = "clearData()"; + } +} + + diff --git a/localconfig/iotpolicy/IHome/smartspeaker.req b/localconfig/iotpolicy/IHome/smartspeaker.req new file mode 100644 index 0000000..a569383 --- /dev/null +++ b/localconfig/iotpolicy/IHome/smartspeaker.req @@ -0,0 +1,3 @@ + +requires Speaker with Initialize, Playback, Volume, Position, Data as interface SpeakerSmart; + diff --git a/localconfig/iotpolicy/IHome/smartspeakercallback.req b/localconfig/iotpolicy/IHome/smartspeakercallback.req new file mode 100644 index 0000000..23ad981 --- /dev/null +++ b/localconfig/iotpolicy/IHome/smartspeakercallback.req @@ -0,0 +1,3 @@ + +requires SpeakerCallback with Callback as interface SpeakerSmartCallback; + diff --git a/localconfig/iotpolicy/IHome/speakercallback.pol b/localconfig/iotpolicy/IHome/speakercallback.pol new file mode 100644 index 0000000..8a2fb15 --- /dev/null +++ b/localconfig/iotpolicy/IHome/speakercallback.pol @@ -0,0 +1,11 @@ +public interface SpeakerCallback { + + public void speakerDone(); + + capability Callback { + description = "Callback method"; + method = "speakerDone()"; + } +} + + -- 2.34.1