From: rtrimana Date: Wed, 22 Nov 2017 00:55:42 +0000 (-0800) Subject: Adding backup for AmcrestCamera firmware; porting BlossomSprinkler driver from the... X-Git-Url: http://plrg.eecs.uci.edu/git/?p=iot2.git;a=commitdiff_plain;h=612e0a2208677f14c86063d7354e5aa9eaea2099;hp=3c845e58955c3ba9f53e1a6ce0b454feff56c22d Adding backup for AmcrestCamera firmware; porting BlossomSprinkler driver from the old iot project location; preparing/adjusting drivers --- diff --git a/benchmarks/Java/Lifxtest/Makefile b/benchmarks/Java/Lifxtest/Makefile old mode 100755 new mode 100644 diff --git a/benchmarks/drivers/Java/BlossomSprinkler/BlossomSprinkler.config b/benchmarks/drivers/Java/BlossomSprinkler/BlossomSprinkler.config new file mode 100644 index 0000000..1fe5d04 --- /dev/null +++ b/benchmarks/drivers/Java/BlossomSprinkler/BlossomSprinkler.config @@ -0,0 +1,7 @@ +# Skeleton/original interface +INTERFACE_CLASS=Sprinkler +# Stub +INTERFACE_STUB_CLASS=SprinklerSmart + +# Language +LANGUAGE=Java diff --git a/benchmarks/drivers/Java/BlossomSprinkler/BlossomSprinkler.java b/benchmarks/drivers/Java/BlossomSprinkler/BlossomSprinkler.java new file mode 100644 index 0000000..cf04828 --- /dev/null +++ b/benchmarks/drivers/Java/BlossomSprinkler/BlossomSprinkler.java @@ -0,0 +1,436 @@ +package iotcode.BlossomSprinkler; + +// Java Standard Packages +import java.util.concurrent.Semaphore; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.PrintWriter; +import java.io.ByteArrayInputStream; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Date; +import java.util.Calendar; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.concurrent.atomic.AtomicBoolean; + +// import java.util.HashSet; +// import java.util.Set; + +// IoT Packages +import iotruntime.IoTTCP; +import iotruntime.IoTServerSocket; +import iotruntime.slave.IoTDeviceAddress; +import iotruntime.slave.IoTSet; +import iotcode.annotation.*; +import iotcode.interfaces.ZoneState; +import iotcode.interfaces.Sprinkler; + +//import iotchecker.qual.*; + +/** Class BlossomSprinkler for the Blossom Sprinkler. + * + * @author Ali Younis + * @version 1.0 + * @since 2016-05-2 + */ +public class BlossomSprinkler implements Sprinkler { + + /******************************************************************************************************************************************* + ** Constants + *******************************************************************************************************************************************/ + public static final int NUMBER_OF_ZONES = 12; + + @config IoTSet blossomSprAddressSet; + @config IoTSet localAddressSet; + + private IoTDeviceAddress deviceAddress = null; + private IoTDeviceAddress localAddress = null; + private String channelId = ""; + private Semaphore zoneStateMutex = new Semaphore(1); + private List zoneStates = new ArrayList(); + private AtomicBoolean didEnd = new AtomicBoolean(); + private boolean didClose = false; + private AtomicBoolean didInit = new AtomicBoolean(false); + + + /******************************************************************************************************************************************* + ** Threads + *******************************************************************************************************************************************/ + private Thread workerThread = null; + private Thread httpMonitorThread = null; + + + public BlossomSprinkler(String _channelId) { + channelId = _channelId; + } + + public void init() { + if (didInit.compareAndSet(false, true) == false) { + return; // already init + } + + // Get the address from the IoTSet + Iterator itr = blossomSprAddressSet.iterator(); + deviceAddress = (IoTDeviceAddress)itr.next(); + System.out.println("Device address: " + deviceAddress.getAddress() + ":" + deviceAddress.getSourcePortNumber() + ":" + + deviceAddress.getDestinationPortNumber()); + + itr = localAddressSet.iterator(); + localAddress = (IoTDeviceAddress)itr.next(); + System.out.println("Local address: " + localAddress.getAddress() + ":" + localAddress.getSourcePortNumber() + ":" + + localAddress.getDestinationPortNumber()); + + + // create the correct number of zones for this controller + for (int i = 0; i < NUMBER_OF_ZONES; i++) { + //zoneStates.add(new ZoneState(i, false, 0)); + ZoneState zTmp = new ZoneState(); + zTmp.zoneNumber = i; + zTmp.onOffState = false; + zTmp.duration = 0; + zoneStates.add(zTmp); + } + + // Launch the worker function in a separate thread. + workerThread = new Thread(new Runnable() { + public void run() { + workerMethod(); + } + }); + workerThread.start(); + + + // Launch the http monitor function in a separate thread. + httpMonitorThread = new Thread(new Runnable() { + public void run() { + httpMonitorMethod(); + } + }); + httpMonitorThread.start(); + } + + public void setZone(int _zone, boolean _onOff, int _onDurationSeconds) { + try { + zoneStateMutex.acquire(); + for (ZoneState z : zoneStates) { + { + // We replaced methods with fields + //z.zoneNumber, z.onOffState z.duration + //if (z.getZoneNumber() == _zone) { + if (z.zoneNumber == _zone) { + + // turn on or off the valve + if (z.onOffState != _onOff) { + z.onOffState = _onOff; + + if (_onOff) { + openValue(_zone); + } else { + closeValue(_zone); + } + } + + // update the duration if needed + if (z.duration != _onDurationSeconds) { + z.duration = _onDurationSeconds; + } + + // we found our sprinkler + break; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + // never forget to unlock + zoneStateMutex.release(); + } + + public List getZoneStates() { + + // make a copy so that they cannot mess with our list + List retList = new ArrayList(); + + try { + zoneStateMutex.acquire(); + for (ZoneState z : zoneStates) { + ZoneState n = new ZoneState(); + n.zoneNumber = z.zoneNumber; + n.onOffState = z.onOffState; + n.duration = z.duration; + retList.add(n); + } + } catch (Exception e) { + e.printStackTrace(); + } + + // Never forget to release! + zoneStateMutex.release(); + return retList; + } + + + public int getNumberOfZones() { + return NUMBER_OF_ZONES; + } + + public boolean doesHaveZoneTimers() { + return true; + } + + public void finalize() { + if (!didClose) { + endDriver(); + } + } + + /******************************************************************************************************************************************* + ** + ** Helper Methods + ** + *******************************************************************************************************************************************/ + + private void workerMethod() { + while (didEnd.get() == false) { + + try { + zoneStateMutex.acquire(); + for (ZoneState z : zoneStates) { + if (z.onOffState) { + + // if on and time has expired then turn off + if (z.duration == 0) { + + // turn off and reset the zone to the off state parameters + closeValue(z.zoneNumber); + z.onOffState = false; + z.duration = 0; + } else if (z.duration > 0) { + + // decrement the time + z.duration = z.duration - 1; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + zoneStateMutex.release(); + + + + try { + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + + private void httpMonitorMethod() { + + try { + + // setup server socket + IoTServerSocket serverSock = new IoTServerSocket(localAddress); + serverSock.setReuseAddress(true); + + + while (didEnd.get() == false) { + + // wait for someone to connect + IoTTCP recSock = serverSock.accept(); + recSock.setReuseAddress(true); + System.out.println("got new connection"); + + // open in and out streams + BufferedReader tcpIn = new BufferedReader(new InputStreamReader(recSock.getInputStream())); + PrintWriter tcpOut = new PrintWriter(recSock.getOutputStream()); + + + + + System.out.println("Waiting For Data"); + // wait for data to be ready + while (!tcpIn.ready()) { + } + + // wait a bit longer to get the whole packet + Thread.sleep(10); + + // put all the lines read into a list so we can read them 1 at a time + List sList = new ArrayList(); + while (tcpIn.ready()) { + String s = tcpIn.readLine(); + sList.add(s); + } + + // System.out.println("---------------------------------------------------------------------"); + // System.out.println("---------------------------------------------------------------------"); + // for (String s : sList) { + // System.out.println(s); + // } + + + // get first line and check that it is a GET request + String line = sList.get(0); + if (line.startsWith("GET")) { + + if (!line.contains("firmware-check")) { + // this is an important request to take care of + + // get the date formatters + DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd"); + DateFormat df2 = new SimpleDateFormat("HH:mm:ss"); + + // make the date + Date today = Calendar.getInstance().getTime(); + String reportDate = df1.format(today); + reportDate += "T"; + reportDate += df2.format(today); + + String body = ""; + + // parse the packet and build the body + if (line.contains("/device/v1/server/")) { + body = "{\"stats_freq\": 3600, \"pn_keepalive\": 1, \"uap_debug\": 1, \"wave_boost\": 1, \"ota_freq\": 3600, \"current_time\":\"" + reportDate + "\", \"build\": 1042, \"opn_trip\": 40}"; + } else if (line.contains("api") && line.contains("device") && line.contains(channelId)) { + body = "{\"channel\": \"channel_" + channelId + "\", \"current_time\": \"" + reportDate + "\", \"tz_offset\": -8.0, \"tz_seconds\": -28800, \"sch_load_time\": 24900, \"fetch_lead\": 3600}"; + } + + // make the header and send + String response = "HTTP/1.1 200 OK\r\n"; + response += "Allow: GET, HEAD, OPTIONS\r\n"; + response += "Content-Type: application/json\r\n"; + response += "Date: Sun, 08 May 2016 04:20:35 GMT\r\n"; + response += "Server: nginx/1.4.6 (Ubuntu)\r\n"; + response += "Vary: Accept, Cookie\r\n"; + response += "Content-Length: " + body.length() + "\r\n"; + // response += "Connection: keep-alive\r\n"; + response += "Connection: Close\r\n"; + response += "\r\n"; + response += body; + tcpOut.print(response); + tcpOut.flush(); + + // System.out.println(response); + + } else { + // not a request we want to take care of + + // send 404 error + String response = "HTTP/1.1 404 Not Found\r\n\r\n"; + tcpOut.print(response); + tcpOut.flush(); + } + } + + // close the connection + recSock.close(); + } + + // close the socket + serverSock.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void openValue(int _valveNum) { + + try { + String body = "{\"valve\":" + Integer.toString(_valveNum) + ",\"inverter\":1}"; + String postMessage = "POST /bloom/valve HTTP/1.1\r\n"; + postMessage += "Content-Type: application/json; charset=utf-8\r\n"; + postMessage += "Content-Length: " + Integer.toString(body.length()) + "\r\n"; + postMessage += "\r\n"; + postMessage += body; + + IoTTCP connection = new IoTTCP(deviceAddress); + connection.setReuseAddress(true); + + // Get in and out communication + PrintWriter tcpOut = new PrintWriter(connection.getOutputStream(), true); + BufferedReader tcpIn = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + tcpOut.print(postMessage); + tcpOut.flush(); + + // wait for data + while (!tcpIn.ready()) { + } + + // Wait a bit longer for data + Thread.sleep(10); + + // get the response + while (tcpIn.ready()) { + String answer = tcpIn.readLine(); + System.out.println(answer); + } + + connection.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void closeValue(int _valveNum) { + + try { + String body = "{\"valve\":" + Integer.toString(_valveNum) + ",\"inverter\":0}"; + String postMessage = "POST /bloom/valve HTTP/1.1\r\n"; + postMessage += "Content-Type: application/json; charset=utf-8\r\n"; + postMessage += "Content-Length: " + Integer.toString(body.length()) + "\r\n"; + postMessage += "\r\n"; + postMessage += body; + + + IoTTCP connection = new IoTTCP(deviceAddress); + connection.setReuseAddress(true); + + // Get in and out communication + PrintWriter tcpOut = new PrintWriter(connection.getOutputStream(), true); + BufferedReader tcpIn = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + tcpOut.print(postMessage); + tcpOut.flush(); + + // wait for data + while (!tcpIn.ready()) { + } + + // Wait a bit longer for data + Thread.sleep(10); + + // get the response + while (tcpIn.ready()) { + String answer = tcpIn.readLine(); + System.out.println(answer); + } + + connection.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void endDriver() { + didClose = true; + didEnd.set(true); + + try { + workerThread.join(); + httpMonitorThread.join(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} + + diff --git a/benchmarks/drivers/Java/BlossomSprinkler/Sprinkler_Skeleton.java b/benchmarks/drivers/Java/BlossomSprinkler/Sprinkler_Skeleton.java new file mode 100644 index 0000000..60bf821 --- /dev/null +++ b/benchmarks/drivers/Java/BlossomSprinkler/Sprinkler_Skeleton.java @@ -0,0 +1,225 @@ +package iotcode.BlossomSprinkler; + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; +import java.util.HashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import iotrmi.Java.IoTRMIComm; +import iotrmi.Java.IoTRMICommClient; +import iotrmi.Java.IoTRMICommServer; +import iotrmi.Java.IoTRMIUtil; + +import iotcode.interfaces.*; + +public class Sprinkler_Skeleton implements Sprinkler { + + private Sprinkler mainObj; + private int objectId = 6; + // Communications and synchronizations + private IoTRMIComm rmiComm; + private AtomicBoolean didAlreadyInitWaitInvoke; + private AtomicBoolean methodReceived; + private byte[] methodBytes = null; + // Permissions + private static Integer[] object2Permission = { 4, 2, 0, 1, 3 }; + private static List set2Allowed; + + + public Sprinkler_Skeleton(Sprinkler _mainObj, int _portSend, int _portRecv) throws Exception { + mainObj = _mainObj; + rmiComm = new IoTRMICommServer(_portSend, _portRecv); + set2Allowed = new ArrayList(Arrays.asList(object2Permission)); + IoTRMIUtil.mapSkel.put(_mainObj, this); + IoTRMIUtil.mapSkelId.put(_mainObj, objectId); + didAlreadyInitWaitInvoke = new AtomicBoolean(false); + methodReceived = new AtomicBoolean(false); + rmiComm.registerSkeleton(objectId, methodReceived); + Thread thread1 = new Thread() { + public void run() { + try { + ___waitRequestInvokeMethod(); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + }; + thread1.start(); + } + + public Sprinkler_Skeleton(Sprinkler _mainObj, IoTRMIComm _rmiComm, int _objectId) throws Exception { + mainObj = _mainObj; + rmiComm = _rmiComm; + objectId = _objectId; + set2Allowed = new ArrayList(Arrays.asList(object2Permission)); + didAlreadyInitWaitInvoke = new AtomicBoolean(false); + methodReceived = new AtomicBoolean(false); + rmiComm.registerSkeleton(objectId, methodReceived); + } + + public boolean didAlreadyInitWaitInvoke() { + return didAlreadyInitWaitInvoke.get(); + } + + public void init() { + mainObj.init(); + } + + public void setZone(int _zone, boolean _onOff, int _onDurationSeconds) { + mainObj.setZone(_zone, _onOff, _onDurationSeconds); + } + + public List getZoneStates() { + return mainObj.getZoneStates(); + } + + public int getNumberOfZones() { + return mainObj.getNumberOfZones(); + } + + public boolean doesHaveZoneTimers() { + return mainObj.doesHaveZoneTimers(); + } + + public void ___init() { + byte[] localMethodBytes = methodBytes; + rmiComm.setGetMethodBytes(); + Object[] paramObj = rmiComm.getMethodParams(new Class[] { }, new Class[] { }, localMethodBytes); + init(); + } + + public void ___setZone() { + byte[] localMethodBytes = methodBytes; + rmiComm.setGetMethodBytes(); + Object[] paramObj = rmiComm.getMethodParams(new Class[] { int.class, boolean.class, int.class }, new Class[] { null, null, null }, localMethodBytes); + setZone((int) paramObj[0], (boolean) paramObj[1], (int) paramObj[2]); + } + + public void ___getZoneStates() throws IOException { + byte[] localMethodBytes = methodBytes; + rmiComm.setGetMethodBytes(); + Object[] paramObj = rmiComm.getMethodParams(new Class[] { }, new Class[] { }, localMethodBytes); + List retStruct = getZoneStates(); + int retLen = retStruct.size(); + Object retLenObj = retLen; + rmiComm.sendReturnObj(retLenObj, localMethodBytes); + Class[] retCls = new Class[3*retLen]; + Object[] retObj = new Object[3*retLen]; + int retPos = 0; + for(int i = 0; i < retLen; i++) { + retCls[retPos] = int.class; + retObj[retPos++] = retStruct.get(i).zoneNumber; + retCls[retPos] = boolean.class; + retObj[retPos++] = retStruct.get(i).onOffState; + retCls[retPos] = int.class; + retObj[retPos++] = retStruct.get(i).duration; + } + rmiComm.sendReturnObj(retCls, retObj, localMethodBytes); + } + + public void ___getNumberOfZones() throws IOException { + byte[] localMethodBytes = methodBytes; + rmiComm.setGetMethodBytes(); + Object[] paramObj = rmiComm.getMethodParams(new Class[] { }, new Class[] { }, localMethodBytes); + Object retObj = getNumberOfZones(); + rmiComm.sendReturnObj(retObj, localMethodBytes); + } + + public void ___doesHaveZoneTimers() throws IOException { + byte[] localMethodBytes = methodBytes; + rmiComm.setGetMethodBytes(); + Object[] paramObj = rmiComm.getMethodParams(new Class[] { }, new Class[] { }, localMethodBytes); + Object retObj = doesHaveZoneTimers(); + rmiComm.sendReturnObj(retObj, localMethodBytes); + } + + public void ___waitRequestInvokeMethod() throws IOException { + didAlreadyInitWaitInvoke.compareAndSet(false, true); + while (true) { + if (!methodReceived.get()) { + continue; + } + methodBytes = rmiComm.getMethodBytes(); + methodReceived.set(false); + int _objectId = IoTRMIComm.getObjectId(methodBytes); + int methodId = IoTRMIComm.getMethodId(methodBytes); + if (_objectId == objectId) { + if (!set2Allowed.contains(methodId)) { + throw new Error("Object with object Id: " + _objectId + " is not allowed to access method: " + methodId); + } + } + else { + continue; + } + switch (methodId) { + case 0: + new Thread() { + public void run() { + try { + ___init(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + }.start(); + break; + case 1: + new Thread() { + public void run() { + try { + ___setZone(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + }.start(); + break; + case 2: + new Thread() { + public void run() { + try { + ___getZoneStates(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + }.start(); + break; + case 3: + new Thread() { + public void run() { + try { + ___getNumberOfZones(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + }.start(); + break; + case 4: + new Thread() { + public void run() { + try { + ___doesHaveZoneTimers(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + }.start(); + break; + default: + throw new Error("Method Id " + methodId + " not recognized!"); + } + } + } + +} diff --git a/benchmarks/drivers/Java/Makefile b/benchmarks/drivers/Java/Makefile index ce21238..480ace0 100644 --- a/benchmarks/drivers/Java/Makefile +++ b/benchmarks/drivers/Java/Makefile @@ -50,6 +50,12 @@ sprinkler: $(JAVAC) $(JFLAGS) EspSprinkler/*.java cp EspSprinkler/EspSprinkler.config $(BIN_DIR)/iotcode/EspSprinkler cd $(BIN_DIR)/iotcode/EspSprinkler; $(JAR) $(JARFLAGS) EspSprinkler.jar ../../iotcode/EspSprinkler/*.class ../../iotcode/interfaces/Sprinkler*.class ../../iotcode/interfaces/ZoneState*.class + +PHONY += blossomsprinkler +blossomsprinkler: + $(JAVAC) $(JFLAGS) BlossomSprinkler/*.java + cp BlossomSprinkler/BlossomSprinkler.config $(BIN_DIR)/iotcode/BlossomSprinkler + cd $(BIN_DIR)/iotcode/BlossomSprinkler; $(JAR) $(JARFLAGS) BlossomSprinkler.jar ../../iotcode/BlossomSprinkler/*.class ../../iotcode/interfaces/Sprinkler*.class ../../iotcode/interfaces/ZoneState*.class PHONY += moisture moisture: @@ -158,6 +164,12 @@ check-sprinkler: $(JAVAC) $(JFLAGS) $(CHECKER_OPT) $(ASTUBS) EspSprinkler/*.java cp EspSprinkler/EspSprinkler.config $(BIN_DIR)/iotcode/EspSprinkler cd $(BIN_DIR)/iotcode/EspSprinkler; $(JAR) $(JARFLAGS) EspSprinkler.jar ../../iotcode/EspSprinkler/*.class ../../iotcode/interfaces/Sprinkler*.class ../../iotcode/interfaces/ZoneState*.class + +PHONY += check-blossomsprinkler +check-blossomsprinkler: + $(JAVAC) $(JFLAGS) $(CHECKER_OPT) $(ASTUBS) BlossomSprinkler/*.java + cp BlossomSprinkler/BlossomSprinkler.config $(BIN_DIR)/iotcode/BlossomSprinkler + cd $(BIN_DIR)/iotcode/BlossomSprinkler; $(JAR) $(JARFLAGS) BlossomSprinkler.jar ../../iotcode/BlossomSprinkler/*.class ../../iotcode/interfaces/Sprinkler*.class ../../iotcode/interfaces/ZoneState*.class PHONY += check-moisture check-moisture: diff --git a/benchmarks/other/AmcrestFirmware/Amcrest_IPC-AWXX_Eng_N_P2P_V2.420.AC00.11.R.20160106.bin b/benchmarks/other/AmcrestFirmware/Amcrest_IPC-AWXX_Eng_N_P2P_V2.420.AC00.11.R.20160106.bin new file mode 100644 index 0000000..c05a7f4 Binary files /dev/null and b/benchmarks/other/AmcrestFirmware/Amcrest_IPC-AWXX_Eng_N_P2P_V2.420.AC00.11.R.20160106.bin differ diff --git a/iotjava/iotruntime/master/IoTMaster.java b/iotjava/iotruntime/master/IoTMaster.java index 6643eee..7dc41d7 100644 --- a/iotjava/iotruntime/master/IoTMaster.java +++ b/iotjava/iotruntime/master/IoTMaster.java @@ -416,6 +416,7 @@ public final class IoTMaster { // Get information from the set List listObject = objAddInitHand.getFields(strFieldIdentifier); + RuntimeOutput.print("IoTMaster: DEBUG: Getting into instrumentIoTSetDevice!", BOOL_VERBOSE); // Create a new IoTSet if(strLanguage.equals(STR_JAVA)) { Message msgCrtIoTSet = new MessageCreateSetRelation(IoTCommCode.CREATE_NEW_IOTSET, strFieldName); @@ -1085,6 +1086,7 @@ public final class IoTMaster { if(setInstrumenter.getObjTableName().equals(STR_IOT_DEV_ADD_CLS)) { // Instrument the normal IoTDeviceAddress synchronized(this) { + //RuntimeOutput.print("IoTMaster: DEBUG: Processing " + STR_IOT_DEV_ADD_CLS + "!", BOOL_VERBOSE); instrumentIoTSetDevice(strFieldIdentifier, strObjName, strFieldName, strIoTSlaveObjectHostAdd, inStream, outStream, strLanguageDriver); } } else if(setInstrumenter.getObjTableName().equals(STR_IOT_ZB_ADD_CLS)) { diff --git a/others/Mysql/IoTMain.gz b/others/Mysql/IoTMain.gz index 4b9fe78..5f0d373 100644 Binary files a/others/Mysql/IoTMain.gz and b/others/Mysql/IoTMain.gz differ