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
include $(BASE)/common.mk
-all: interfaces annotation drivers Lifxtest SmartLights Irrigation
+all: interfaces annotation drivers Lifxtest SmartLights Irrigation Speaker
PHONY += interfaces
interfaces:
--- /dev/null
+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!");
+ }
+ }
+
+}
--- /dev/null
+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<GPSGatewayCallback> listCallbackObj;
+ private int objIdCnt = 0;
+ private final static int object0Id = 0; //GPSGatewaySmartCallback
+ private static Integer[] object0Permission = { 0, 1 };
+ private static List<Integer> 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<Integer>(Arrays.asList(object0Permission));
+ listCallbackObj = new ArrayList<GPSGatewayCallback>();
+ 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;
+ }
+
+}
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
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+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!");
+ }
+ }
+
+}
// IoT driver packages
import iotcode.interfaces.*;
-//import iotcode.annotation.*;
+import iotcode.annotation.*;
// Standard Java packages
import java.rmi.server.UnicastRemoteObject;
// Checker annotations
-import iotchecker.qual.*;
+//import iotchecker.qual.*;
/** Class SpeakerController for the smart home application benchmark
* <p>
/**
* 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);
/** 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);
/** 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);
/** 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);
}
}
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)) {
// 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);
}
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ //} catch (RemoteException e) {
+ // e.printStackTrace();
+ //}
}
if (currPosCount != 0) {
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();
+ //}
}
}
- } else {
+ } /*else {
// Room status is "off"
// used to get the average of the speakers position
// 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
if (currPosCount != 0) {
currentPosition = (int)(currPosTotal / currPosCount);
}
- }
+ }*/
}
// a speaker has finished playing and so we should change all the audio buffers
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
// 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) {
roomSpeakersOnOffStatus.put(room, false);
}
- } catch (RemoteException ex) {
- ex.printStackTrace();
- }
+ //} catch (RemoteException ex) {
+ // ex.printStackTrace();
+ //}
}
}
// Finish processing data - put this back to false
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()) {
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);
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();
}
--- /dev/null
+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<SpeakerCallback> listCallbackObj;
+ private int objIdCnt = 0;
+ private final static int object0Id = 0; //SpeakerSmartCallback
+ private static Integer[] object0Permission = { 0 };
+ private static List<Integer> 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<Integer>(Arrays.asList(object0Permission));
+ listCallbackObj = new ArrayList<SpeakerCallback>();
+ 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);
+ }
+
+}
--- /dev/null
+INTERFACE_CLASS=Room
--- /dev/null
+package iotcode.AudioRoom;
+
+import iotcode.interfaces.Room;
+
+/** AudioRoom holds room ID that tells which room it is
+ * in association with speakers
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @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;
+ }
+}
--- /dev/null
+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<Integer> set0Allowed;
+
+
+ public Room_Skeleton(Room _mainObj, String _callbackAddress, int _port) throws Exception {
+ mainObj = _mainObj;
+ callbackAddress = _callbackAddress;
+ rmiObj = new IoTRMIObject(_port);
+ set0Allowed = new ArrayList<Integer>(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!");
+ }
+ }
+ }
+
+}
--- /dev/null
+INTERFACE_CLASS=GPSGateway
--- /dev/null
+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 <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2016-04-27
+ */
+public class GPSPhoneGateway implements GPSGateway {
+
+ /**
+ * PhoneGateway class properties
+ */
+ private PhoneInfo phoneInfo;
+ private IoTRemoteCall iotRemCall;
+ private List<GPSGatewaySmartCallback> listPGWCallback;
+ private AtomicBoolean doEnd;
+ private Thread callbackThread;
+ private Thread workerThread;
+ private IoTDeviceAddress iotDevAdd;
+
+ @config private IoTSet<IoTDeviceAddress> 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<GPSGatewaySmartCallback>();
+ 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();
+ }*/
+}
--- /dev/null
+package iotcode.GPSPhoneGateway;
+
+/** PhoneInfo that implements PhoneInfoInterface
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @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;
+ }
+}
--- /dev/null
+package iotcode.GPSPhoneGateway;
+
+/** PhoneInfoInterface interface to be implemented by a real class
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @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);
+}
--- /dev/null
+INTERFACE_CLASS=Speaker
\ No newline at end of file
--- /dev/null
+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<IoTDeviceAddress> 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<String, Integer> addrCount = new HashMap<String, Integer>();
+
+
+ // 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;
+ }
+}
+
+
+
+
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
#
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)
--- /dev/null
+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);
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface GPSGatewayCallback {
+ public void newRoomIDRetrieved(int _roomIdentifier);
+ public void newRingStatusRetrieved(boolean _ringStatus);
+}
--- /dev/null
+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();
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface GPSGatewaySmartCallback {
+
+ public void newRoomIDRetrieved(int _roomIdentifier);
+ public void newRingStatusRetrieved(boolean _ringStatus);
+}
--- /dev/null
+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);
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface SpeakerCallback {
+ public void speakerDone();
+}
--- /dev/null
+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);
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface SpeakerSmartCallback {
+
+ public void speakerDone();
+}
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:
--- /dev/null
+public interface Room {
+
+ public int getRoomID();
+
+ capability Basic {
+ description = "Get room ID";
+ method = "getRoomID()";
+ }
+}
+
+
--- /dev/null
+
+requires Room with Basic as interface RoomSmart;
+
--- /dev/null
+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)";
+ }
+}
+
+
--- /dev/null
+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)";
+ }
+}
+
+
--- /dev/null
+
+requires GPSGateway with Initialize, GPSUpdate as interface GPSGatewaySmart;
+
--- /dev/null
+
+requires GPSGatewayCallback with Callback as interface GPSGatewaySmartCallback;
+
--- /dev/null
+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()";
+ }
+}
+
+
--- /dev/null
+
+requires Speaker with Initialize, Playback, Volume, Position, Data as interface SpeakerSmart;
+
--- /dev/null
+
+requires SpeakerCallback with Callback as interface SpeakerSmartCallback;
+
--- /dev/null
+public interface SpeakerCallback {
+
+ public void speakerDone();
+
+ capability Callback {
+ description = "Callback method";
+ method = "speakerDone()";
+ }
+}
+
+