5 import static java.lang.Math.toIntExact;
7 public class IoTSlave {
9 private ServerSocket serverSocket;
10 private Socket socket;
11 private BufferedInputStream input;
12 private BufferedOutputStream output;
14 private static final String STR_LOCALHOST = "localhost";
15 private static final String STR_IOTSLAVE_CPP = "./IoTSlave.o";
16 private static final String STR_IOTSLAVE_PATH = "~/tmp/iot2/iotjava/iotruntime/cpp/iotslave/";
18 //private static final String STR_LOG_FILE_PATH = "./";
19 private static int INT_SIZE = 4; // send length in the size of integer (4 bytes)
32 * Prepare server socket connection with C++ IoTSlave
34 public void setServerSocketCpp(int iPort) {
37 serverSocket = new ServerSocket(iPort);
39 catch ( IOException e ) {
46 * A method to send files from IoTMaster
48 * @param filesocket File socket object
49 * @param sFileName File name
50 * @param lFLength File length
53 private void sendFile(Socket filesocket, String sFileName, long lFLength) throws IOException {
55 File file = new File(sFileName);
56 byte[] bytFile = new byte[toIntExact(lFLength)];
57 InputStream inFileStream = new FileInputStream(file);
59 OutputStream outFileStream = filesocket.getOutputStream();
61 while ((iCount = inFileStream.read(bytFile)) > 0) {
62 outFileStream.write(bytFile, 0, iCount);
68 private void sendFile(String sFilePath, String sFileName) throws IOException {
70 sendCommCode(IoTCommCode.TRANSFER_FILE);
72 sendString(sFileName); recvAck();
73 File file = new File(sFilePath + sFileName);
74 int iFileLen = toIntExact(file.length());
75 System.out.println("IoTSlave: Sending file " + sFileName + " with length " + iFileLen + " bytes...");
77 sendInteger(iFileLen); recvAck();
78 byte[] bytFile = new byte[iFileLen];
79 InputStream inFileStream = new FileInputStream(file);
81 OutputStream outFileStream = socket.getOutputStream();
83 while ((iCount = inFileStream.read(bytFile)) > 0) {
84 outFileStream.write(bytFile, 0, iCount);
86 System.out.println("IoTSlave: File sent!");
91 * sendInteger() sends an integer in bytes
93 public void sendInteger(int intSend) throws IOException {
95 // Transform integer into bytes
96 ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
98 // Send the byte array
99 output.write(bb.array(), 0, INT_SIZE);
105 * recvInteger() receives integer in bytes
107 public int recvInteger() throws IOException {
109 // Wait until input is available
110 while(input.available() == 0);
111 // Read integer - 4 bytes
112 byte[] recvInt = new byte[INT_SIZE];
113 input.read(recvInt, 0, INT_SIZE);
114 int retVal = ByteBuffer.wrap(recvInt).getInt();
121 * recvString() receives String in bytes
123 public String recvString() throws IOException {
125 int strLen = recvInteger();
126 // Wait until input is available
127 while(input.available() == 0);
128 // Read String per strLen
129 byte[] recvStr = new byte[strLen];
130 input.read(recvStr, 0, strLen);
131 String retVal = new String(recvStr);
138 * sendString() sends a String in bytes
140 public void sendString(String strSend) throws IOException {
142 // Transform String into bytes
143 byte[] strSendBytes = strSend.getBytes();
144 int strLen = strSend.length();
145 // Send the string length first
147 // Send the byte array
148 output.write(strSendBytes, 0, strLen);
154 * Establish connection with C++ IoTSlave
156 public void connectCpp() throws IOException {
158 socket = serverSocket.accept();
159 input = new BufferedInputStream(socket.getInputStream());
160 output = new BufferedOutputStream(socket.getOutputStream());
165 * Construct a SSH command to run C++ program
167 public static String constructCommand(String serverAddress, int serverPort, String strObjName) {
169 String strCommand = "ssh rtrimana@localhost cd " + STR_IOTSLAVE_PATH + "; " +
170 STR_IOTSLAVE_CPP + " " + serverAddress + " " + serverPort + " " + strObjName;
176 * Create a new thread to start a new C++ process
178 public static void createCppThread(String strCmd) {
180 Thread thread = new Thread(new Runnable() {
183 Runtime runtime = Runtime.getRuntime();
184 Process process = runtime.exec(strCmd);
185 } catch(IOException ex) {
186 ex.printStackTrace();
191 //RuntimeOutput.print("IoTSlave: Executing: " + strCmd, BOOL_VERBOSE);
192 System.out.println("IoTSlave: Executing: " + strCmd);
197 * Convert integer to enum
199 public IoTCommCode getCode(int intCode) throws IOException {
201 IoTCommCode[] commCode = IoTCommCode.values();
202 IoTCommCode retCode = commCode[intCode];
211 public boolean recvAck() throws IOException {
213 int intAck = recvInteger();
214 IoTCommCode codeAck = getCode(intAck);
215 if (codeAck == IoTCommCode.ACKNOWLEDGED)
225 public void sendEndTransfer() throws IOException {
227 int endCode = IoTCommCode.END_TRANSFER.ordinal();
228 sendInteger(endCode);
233 * Send communication code to C++
235 public void sendCommCode(IoTCommCode inpCommCode) throws IOException {
238 IoTCommCode commCode = inpCommCode;
239 int intCode = commCode.ordinal();
240 sendInteger(intCode); recvAck();
245 * Create a main controller object for C++
247 public void createMainObjectCpp() throws IOException {
249 sendCommCode(IoTCommCode.CREATE_MAIN_OBJECT);
250 String strMainObjName = "Lifxtest";
251 sendString(strMainObjName); recvAck();
252 System.out.println("IoTSlave: Create a main object: " + strMainObjName);
257 * Create a driver object for C++
259 public void createObjectCpp() throws IOException {
261 sendCommCode(IoTCommCode.CREATE_OBJECT);
262 String strDrvObjName = "LifxLightBulbLB2";
263 String strDrvObjClsName = "LifxLightBulb";
264 String strDrvObjIntfaceClsName = "LightBulb";
265 String strDrvObjSkelClsName = "LightBulb_Skeleton";
266 int iRegPort = 30313;
267 int iStubPort = 55179;
268 // TODO: On the actual slave we need to do conversion back to string before we send everything to C++ IoTSlave
269 // TODO: Make it as array of string
270 //String[] arrCppArgs = { "D073D50241DA0000" };
271 String[] arrCppArgs = { "D073D5128E300000" };
272 String[] arrCppArgClasses = { "string" };
273 System.out.println("IoTSlave: Send request to create a driver object... ");
274 System.out.println("IoTSlave: Driver object name: " + strDrvObjName);
275 sendString(strDrvObjName); recvAck();
276 System.out.println("IoTSlave: Driver object class name: " + strDrvObjClsName);
277 sendString(strDrvObjClsName); recvAck();
278 System.out.println("IoTSlave: Driver object interface name: " + strDrvObjIntfaceClsName);
279 sendString(strDrvObjIntfaceClsName); recvAck();
280 System.out.println("IoTSlave: Driver object skeleton class name: " + strDrvObjSkelClsName);
281 sendString(strDrvObjSkelClsName); recvAck();
282 System.out.println("IoTSlave: Driver object registry port: " + iRegPort);
283 sendInteger(iRegPort); recvAck();
284 System.out.println("IoTSlave: Driver object stub port: " + iStubPort);
285 sendInteger(iStubPort); recvAck();
286 int numOfArgs = arrCppArgs.length;
287 System.out.println("IoTSlave: Send constructor arguments! Number of arguments: " + numOfArgs);
288 sendInteger(numOfArgs); recvAck();
289 for(String str : arrCppArgs) {
290 sendString(str); recvAck();
292 System.out.println("IoTSlave: Send constructor argument classes!");
293 for(String str : arrCppArgClasses) {
294 sendString(str); recvAck();
300 * Create new IoTSet for C++
302 //public void createNewIoTSetCpp() throws IOException {
303 public void createNewIoTSetCpp(String strObjFieldName) throws IOException {
305 sendCommCode(IoTCommCode.CREATE_NEW_IOTSET);
306 System.out.println("IoTSlave: Creating new IoTSet...");
307 //String strObjFieldName = "lb_addresses";
308 System.out.println("IoTSlave: Send object field name: " + strObjFieldName);
309 sendString(strObjFieldName); recvAck();
314 * Get a IoTDeviceAddress object for C++
316 public void getDeviceIoTSetObjectCpp() throws IOException {
318 sendCommCode(IoTCommCode.GET_DEVICE_IOTSET_OBJECT);
319 System.out.println("IoTSlave: Getting IoTDeviceAddress...");
320 //String strHostAddress = "192.168.2.232";
321 String strHostAddress = "192.168.2.126";
322 sendString(strHostAddress); recvAck();
323 int iSourcePort = 43583;
324 sendInteger(iSourcePort); recvAck();
325 int iDestPort = 56700;
326 sendInteger(iDestPort); recvAck();
327 boolean bSourceWildCard = false;
328 int iSourceWildCard = (bSourceWildCard ? 1 : 0);
329 sendInteger(iSourceWildCard); recvAck();
330 boolean bDestWildCard = false;
331 int iDestWildCard = (bDestWildCard ? 1 : 0);
332 sendInteger(iDestWildCard); recvAck();
333 System.out.println("IoTSlave: Send host address: " + strHostAddress);
338 * Get a IoTSet content object for C++
340 public void getIoTSetObjectCpp() throws IOException {
342 sendCommCode(IoTCommCode.GET_IOTSET_OBJECT);
343 System.out.println("IoTSlave: Getting IoTSet object content...");
344 String strHostAddress = "localhost";
345 String strDrvObjName = "LifxLightBulbLB2";
346 String strDrvObjClsName = "LifxLightBulb";
347 String strDrvObjIntfaceClsName = "LightBulb";
348 String strDrvObjStubClsName = "LightBulbTest_Stub"; // Send a complete name with "_Stub"
349 int iRegPort = 30313;
350 int iStubPort = 55179;
351 int[] callbackPorts = { 58551 };
353 System.out.println("IoTSlave: Send host address: " + strHostAddress);
354 sendString(strHostAddress); recvAck();
355 System.out.println("IoTSlave: Driver object name: " + strDrvObjName);
356 sendString(strDrvObjName); recvAck();
357 System.out.println("IoTSlave: Driver object class name: " + strDrvObjClsName);
358 sendString(strDrvObjClsName); recvAck();
359 System.out.println("IoTSlave: Driver object interface name: " + strDrvObjIntfaceClsName);
360 sendString(strDrvObjIntfaceClsName); recvAck();
361 System.out.println("IoTSlave: Driver object skeleton class name: " + strDrvObjStubClsName);
362 sendString(strDrvObjStubClsName); recvAck();
363 System.out.println("IoTSlave: Driver object registry port: " + iRegPort);
364 sendInteger(iRegPort); recvAck();
365 System.out.println("IoTSlave: Driver object stub port: " + iStubPort);
366 sendInteger(iStubPort); recvAck();
367 sendInteger(callbackPorts.length); recvAck();
368 for(int i : callbackPorts) {
369 sendInteger(i); recvAck();
376 * Reinitialize IoTSet field for C++
378 private void reinitializeIoTSetFieldCpp() throws IOException {
380 System.out.println("IoTSlave: About to Reinitialize IoTSet field!");
381 sendCommCode(IoTCommCode.REINITIALIZE_IOTSET_FIELD);
382 System.out.println("IoTSlave: Reinitialize IoTSet field!");
387 * Invoke init() for C++
389 private void invokeInitMethodCpp() throws IOException {
391 sendCommCode(IoTCommCode.INVOKE_INIT_METHOD);
392 System.out.println("IoTSlave: Invoke init method!");
397 * End session for C++
399 public void endSessionCpp() throws IOException {
401 // Send message to end session
402 IoTCommCode endSessionCode = IoTCommCode.END_SESSION;
403 int intCode = endSessionCode.ordinal();
404 sendInteger(intCode);
405 //RuntimeOutput.print("IoTSlave: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
406 System.out.println("IoTSlave: Send request to end session!");
410 public static void main(String[] args) throws IOException, InterruptedException {
413 IoTSlave iotSlave = new IoTSlave();
414 iotSlave.setServerSocketCpp(iPort);
415 iotSlave.connectCpp();
416 System.out.println("Connection established with client!");
417 iotSlave.sendInteger(1234);
418 System.out.println("Integer sent!");
419 System.out.println("Integer received: " + iotSlave.recvInteger());
420 String strRecv = iotSlave.recvString();
421 System.out.println("Received string: " + strRecv);
422 strRecv = strRecv + " - ACKNOWLEDGED!";
423 System.out.println("Sending back string: " + strRecv);
424 iotSlave.sendString(strRecv);*/
426 // =========================================
427 // Create IoTSlave for controller object!
428 int iPortMain =12346;
429 String strAddressMain = "localhost";
430 String strObjNameMain = "Lifxtest";
431 IoTSlave iotSlaveMain = new IoTSlave();
432 iotSlaveMain.setServerSocketCpp(iPortMain);
433 // Run thread to spawn C++ IoTSlave
434 String strCmdMain = iotSlaveMain.constructCommand(strAddressMain, iPortMain, strObjNameMain);
435 iotSlaveMain.createCppThread(strCmdMain);
436 iotSlaveMain.connectCpp();
437 System.out.println("IoTSlave: Connection established with main!");
438 // First contact with C++ IoTSlave
439 System.out.println("IoTSlave: IoTSlave.o main is ready: " + iotSlaveMain.recvAck());
440 //iotSlaveMain.sendFile("../", "Lifxtest.so");
441 //iotSlaveMain.sendFile("../", "LightBulbTest_Stub.so");
442 //iotSlaveMain.sendFile("../", "Lifxtest.zip");
443 //iotSlaveMain.sendFile("../resources/", "Lifxtest.jar");
444 //iotSlaveMain.sendFile("../", "unzip.zip");
447 // =========================================
448 // Create IoTSlave for driver object!
450 String strAddress = "localhost";
451 String strObjName = "LifxLightBulbLB2";
452 IoTSlave iotSlave = new IoTSlave();
453 iotSlave.setServerSocketCpp(iPort);
454 // Run thread to spawn C++ IoTSlave
455 String strCmd = IoTSlave.constructCommand(strAddress, iPort, strObjName);
456 IoTSlave.createCppThread(strCmd);
457 iotSlave.connectCpp();
458 //RuntimeOutput.print("IoTSlave: Connection established!", BOOL_VERBOSE);
459 System.out.println("IoTSlave: Connection established!");
460 // First contact with C++ IoTSlave
461 System.out.println("IoTSlave: IoTSlave.o is ready: " + iotSlave.recvAck());
462 //iotSlave.sendFile("../", "LifxLightBulb.so");
463 //iotSlave.sendFile("../", "LightBulb_Skeleton.so");
464 //iotSlave.sendFile("../", "LifxLightBulb.zip");
465 //iotSlave.sendFile("../", "unzip2.zip");
466 iotSlave.createObjectCpp();
467 //iotSlave.createNewIoTSetCpp();
468 iotSlave.createNewIoTSetCpp("lb_addresses");
469 iotSlave.getDeviceIoTSetObjectCpp();
470 iotSlave.reinitializeIoTSetFieldCpp();
471 //iotSlave.endSessionCpp();
473 // =========================================
474 // Continue with main object
475 iotSlaveMain.createMainObjectCpp();
476 iotSlaveMain.createNewIoTSetCpp("lifx_light_bulb");
477 iotSlaveMain.getIoTSetObjectCpp();
478 iotSlaveMain.reinitializeIoTSetFieldCpp();
479 iotSlaveMain.invokeInitMethodCpp();
480 iotSlaveMain.endSessionCpp();
482 // Send message to create a main object
483 /*commCode = IoTCommCode.CREATE_MAIN_OBJECT;
484 intCode = commCode.ordinal();
485 iotSlave.sendInteger(intCode);
486 //RuntimeOutput.print("IoTSlave: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
487 System.out.println("IoTSlave: Send request to create a main object: " + strObjName);
488 //RuntimeOutput.print("IoTSlave: IoTSlave.o is ready: " + strAck, BOOL_VERBOSE);
489 System.out.println("IoTSlave: IoTSlave.o is ready: " + strAck);*/
491 //Thread.sleep(1000);