6 public class IoTSlave {
8 private ServerSocket serverSocket;
10 private BufferedInputStream input;
11 private BufferedOutputStream output;
13 private static final String STR_LOCALHOST = "localhost";
14 private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o";
15 private static final String STR_ACK = "ACK";
16 private static final String STR_END = "END";
17 //private static final String STR_LOG_FILE_PATH = "./";
18 private static int INT_SIZE = 4; // send length in the size of integer (4 bytes)
31 * Prepare server socket connection with C++ IoTSlave
33 public void setServerSocketCpp(int iPort) {
36 serverSocket = new ServerSocket(iPort);
38 catch ( IOException e ) {
45 * sendInteger() sends an integer in bytes
47 public void sendInteger(int intSend) throws IOException {
49 // Transform integer into bytes
50 ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
52 // Send the byte array
53 output.write(bb.array(), 0, INT_SIZE);
59 * recvInteger() receives integer in bytes
61 public int recvInteger() throws IOException {
63 // Wait until input is available
64 while(input.available() == 0);
65 // Read integer - 4 bytes
66 byte[] recvInt = new byte[INT_SIZE];
67 input.read(recvInt, 0, INT_SIZE);
68 int retVal = ByteBuffer.wrap(recvInt).getInt();
75 * recvString() receives String in bytes
77 public String recvString() throws IOException {
79 int strLen = recvInteger();
80 // Wait until input is available
81 while(input.available() == 0);
82 // Read String per strLen
83 byte[] recvStr = new byte[strLen];
84 input.read(recvStr, 0, strLen);
85 String retVal = new String(recvStr);
92 * sendString() sends a String in bytes
94 public void sendString(String strSend) throws IOException {
96 // Transform String into bytes
97 byte[] strSendBytes = strSend.getBytes();
98 int strLen = strSend.length();
99 // Send the string length first
101 // Send the byte array
102 output.write(strSendBytes, 0, strLen);
108 * Establish connection with C++ IoTSlave
110 public void connectCpp() throws IOException {
112 socket = serverSocket.accept();
113 input = new BufferedInputStream(socket.getInputStream());
114 output = new BufferedOutputStream(socket.getOutputStream());
119 * Construct a SSH command to run C++ program
121 public static String constructCommand(String serverAddress, int serverPort, String strObjName) {
123 String strCommand = STR_IOTSLAVE_CPP + " " + serverAddress + " " + serverPort + " " + strObjName;
129 * Create a new thread to start a new C++ process
131 public static void createCppThread(String strCmd) {
133 Thread thread = new Thread(new Runnable() {
136 Runtime runtime = Runtime.getRuntime();
137 Process process = runtime.exec(strCmd);
138 } catch(IOException ex) {
139 ex.printStackTrace();
144 //RuntimeOutput.print("IoTSlave: Executing: " + strCmd, BOOL_VERBOSE);
145 System.out.println("IoTSlave: Executing: " + strCmd);
150 * Convert integer to enum
152 public IoTCommCode getCode(int intCode) throws IOException {
154 IoTCommCode[] commCode = IoTCommCode.values();
155 IoTCommCode retCode = commCode[intCode];
164 public boolean recvAck() throws IOException {
166 int intAck = recvInteger();
167 IoTCommCode codeAck = getCode(intAck);
168 if (codeAck == IoTCommCode.ACKNOWLEDGED)
178 public void sendEndTransfer() throws IOException {
180 int endCode = IoTCommCode.END_TRANSFER.ordinal();
181 sendInteger(endCode);
186 * Create a driver object for C++
188 public void createObjectCpp() throws IOException {
190 IoTCommCode commCode = null;
192 commCode = IoTCommCode.CREATE_OBJECT;
193 intCode = commCode.ordinal();
194 sendInteger(intCode); recvAck();
195 String strDrvObjName = "LifxLightBulbLB2";
196 String strDrvObjClsName = "LifxLightBulb";
197 String strDrvObjIntfaceClsName = "LightBulb";
198 String strDrvObjSkelClsName = "LightBulb_Skeleton";
199 int iRegPort = 30313;
200 int iStubPort = 55179;
201 // TODO: On the actual slave we need to do conversion back to string before we send everything to C++ IoTSlave
202 // TODO: Make it as array of string
203 String[] arrCppArgs = { "D073D5128E300000" };
204 String[] arrCppArgClasses = { "string" };
205 System.out.println("IoTSlave: Send request to create a driver object... ");
206 System.out.println("IoTSlave: Driver object name: " + strDrvObjName);
207 sendString(strDrvObjName); recvAck();
208 System.out.println("IoTSlave: Driver object class name: " + strDrvObjClsName);
209 sendString(strDrvObjClsName); recvAck();
210 System.out.println("IoTSlave: Driver object interface name: " + strDrvObjIntfaceClsName);
211 sendString(strDrvObjIntfaceClsName); recvAck();
212 System.out.println("IoTSlave: Driver object skeleton class name: " + strDrvObjSkelClsName);
213 sendString(strDrvObjSkelClsName); recvAck();
214 System.out.println("IoTSlave: Driver object registry port: " + iRegPort);
215 sendInteger(iRegPort); recvAck();
216 System.out.println("IoTSlave: Driver object stub port: " + iStubPort);
217 sendInteger(iStubPort); recvAck();
218 int numOfArgs = arrCppArgs.length;
219 System.out.println("IoTSlave: Send constructor arguments! Number of arguments: " + numOfArgs);
220 sendInteger(numOfArgs); recvAck();
221 for(String str : arrCppArgs) {
222 sendString(str); recvAck();
224 System.out.println("IoTSlave: Send constructor argument classes!");
225 for(String str : arrCppArgClasses) {
226 sendString(str); recvAck();
234 private void sendFieldsCpp() throws IOException {
241 * Send object field types
243 private void sendFieldTypesCpp() throws IOException {
250 * End session for C++
252 public void endSessionCpp() throws IOException {
254 // Send message to end session
255 IoTCommCode endSessionCode = IoTCommCode.END_SESSION;
256 int intCode = endSessionCode.ordinal();
257 sendInteger(intCode);
258 //RuntimeOutput.print("IoTSlave: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
259 System.out.println("IoTSlave: Send request to end session!");
263 public static void main(String[] args) throws IOException, InterruptedException {
266 IoTSlave iotSlave = new IoTSlave();
267 iotSlave.setServerSocketCpp(iPort);
268 iotSlave.connectCpp();
269 System.out.println("Connection established with client!");
270 iotSlave.sendInteger(1234);
271 System.out.println("Integer sent!");
272 System.out.println("Integer received: " + iotSlave.recvInteger());
273 String strRecv = iotSlave.recvString();
274 System.out.println("Received string: " + strRecv);
275 strRecv = strRecv + " - ACKNOWLEDGED!";
276 System.out.println("Sending back string: " + strRecv);
277 iotSlave.sendString(strRecv);*/
280 String strAddress = "localhost";
281 String strObjName = "Lifxtest";
283 IoTSlave iotSlave = new IoTSlave();
284 iotSlave.setServerSocketCpp(iPort);
286 // Run thread to spawn C++ IoTSlave
287 String strCmd = IoTSlave.constructCommand(strAddress, 12345, strObjName);
288 IoTSlave.createCppThread(strCmd);
289 iotSlave.connectCpp();
290 //RuntimeOutput.print("IoTSlave: Connection established!", BOOL_VERBOSE);
291 System.out.println("IoTSlave: Connection established!");
292 // First contact with C++ IoTSlave
293 System.out.println("IoTSlave: IoTSlave.o is ready: " + iotSlave.recvAck());
295 iotSlave.createObjectCpp();
298 iotSlave.endSessionCpp();
301 // Send message to create a main object
302 /*commCode = IoTCommCode.CREATE_MAIN_OBJECT;
303 intCode = commCode.ordinal();
304 iotSlave.sendInteger(intCode);
305 //RuntimeOutput.print("IoTSlave: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
306 System.out.println("IoTSlave: Send request to create a main object: " + strObjName);
307 //RuntimeOutput.print("IoTSlave: IoTSlave.o is ready: " + strAck, BOOL_VERBOSE);
308 System.out.println("IoTSlave: IoTSlave.o is ready: " + strAck);*/
310 //Thread.sleep(1000);