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_IOTSLAVE_PATH = "~/tmp/iot2/iotjava/iotruntime/cpp/iotslave/";
16 private static final String STR_ACK = "ACK";
17 private static final String STR_END = "END";
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 * sendInteger() sends an integer in bytes
48 public void sendInteger(int intSend) throws IOException {
50 // Transform integer into bytes
51 ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
53 // Send the byte array
54 output.write(bb.array(), 0, INT_SIZE);
60 * recvInteger() receives integer in bytes
62 public int recvInteger() throws IOException {
64 // Wait until input is available
65 while(input.available() == 0);
66 // Read integer - 4 bytes
67 byte[] recvInt = new byte[INT_SIZE];
68 input.read(recvInt, 0, INT_SIZE);
69 int retVal = ByteBuffer.wrap(recvInt).getInt();
76 * recvString() receives String in bytes
78 public String recvString() throws IOException {
80 int strLen = recvInteger();
81 // Wait until input is available
82 while(input.available() == 0);
83 // Read String per strLen
84 byte[] recvStr = new byte[strLen];
85 input.read(recvStr, 0, strLen);
86 String retVal = new String(recvStr);
93 * sendString() sends a String in bytes
95 public void sendString(String strSend) throws IOException {
97 // Transform String into bytes
98 byte[] strSendBytes = strSend.getBytes();
99 int strLen = strSend.length();
100 // Send the string length first
102 // Send the byte array
103 output.write(strSendBytes, 0, strLen);
109 * Establish connection with C++ IoTSlave
111 public void connectCpp() throws IOException {
113 socket = serverSocket.accept();
114 input = new BufferedInputStream(socket.getInputStream());
115 output = new BufferedOutputStream(socket.getOutputStream());
120 * Construct a SSH command to run C++ program
122 public static String constructCommand(String serverAddress, int serverPort, String strObjName) {
124 String strCommand = "ssh rtrimana@localhost cd " + STR_IOTSLAVE_PATH + "; " +
125 STR_IOTSLAVE_CPP + " " + serverAddress + " " + serverPort + " " + strObjName;
131 * Create a new thread to start a new C++ process
133 public static void createCppThread(String strCmd) {
135 Thread thread = new Thread(new Runnable() {
138 Runtime runtime = Runtime.getRuntime();
139 Process process = runtime.exec(strCmd);
140 } catch(IOException ex) {
141 ex.printStackTrace();
146 //RuntimeOutput.print("IoTSlave: Executing: " + strCmd, BOOL_VERBOSE);
147 System.out.println("IoTSlave: Executing: " + strCmd);
152 * Convert integer to enum
154 public IoTCommCode getCode(int intCode) throws IOException {
156 IoTCommCode[] commCode = IoTCommCode.values();
157 IoTCommCode retCode = commCode[intCode];
166 public boolean recvAck() throws IOException {
168 int intAck = recvInteger();
169 IoTCommCode codeAck = getCode(intAck);
170 if (codeAck == IoTCommCode.ACKNOWLEDGED)
180 public void sendEndTransfer() throws IOException {
182 int endCode = IoTCommCode.END_TRANSFER.ordinal();
183 sendInteger(endCode);
188 * Send communication code to C++
190 public void sendCommCode(IoTCommCode inpCommCode) throws IOException {
193 IoTCommCode commCode = inpCommCode;
194 int intCode = commCode.ordinal();
195 sendInteger(intCode); recvAck();
200 * Create a main controller object for C++
202 public void createMainObjectCpp() throws IOException {
204 sendCommCode(IoTCommCode.CREATE_MAIN_OBJECT);
205 String strMainObjName = "Lifxtest";
206 sendString(strMainObjName); recvAck();
207 System.out.println("IoTSlave: Create a main object: " + strMainObjName);
212 * Create a driver object for C++
214 public void createObjectCpp() throws IOException {
216 sendCommCode(IoTCommCode.CREATE_OBJECT);
217 String strDrvObjName = "LifxLightBulbLB2";
218 String strDrvObjClsName = "LifxLightBulb";
219 String strDrvObjIntfaceClsName = "LightBulb";
220 String strDrvObjSkelClsName = "LightBulb_Skeleton";
221 int iRegPort = 30313;
222 int iStubPort = 55179;
223 // TODO: On the actual slave we need to do conversion back to string before we send everything to C++ IoTSlave
224 // TODO: Make it as array of string
225 //String[] arrCppArgs = { "D073D50241DA0000" };
226 String[] arrCppArgs = { "D073D5128E300000" };
227 String[] arrCppArgClasses = { "string" };
228 System.out.println("IoTSlave: Send request to create a driver object... ");
229 System.out.println("IoTSlave: Driver object name: " + strDrvObjName);
230 sendString(strDrvObjName); recvAck();
231 System.out.println("IoTSlave: Driver object class name: " + strDrvObjClsName);
232 sendString(strDrvObjClsName); recvAck();
233 System.out.println("IoTSlave: Driver object interface name: " + strDrvObjIntfaceClsName);
234 sendString(strDrvObjIntfaceClsName); recvAck();
235 System.out.println("IoTSlave: Driver object skeleton class name: " + strDrvObjSkelClsName);
236 sendString(strDrvObjSkelClsName); recvAck();
237 System.out.println("IoTSlave: Driver object registry port: " + iRegPort);
238 sendInteger(iRegPort); recvAck();
239 System.out.println("IoTSlave: Driver object stub port: " + iStubPort);
240 sendInteger(iStubPort); recvAck();
241 int numOfArgs = arrCppArgs.length;
242 System.out.println("IoTSlave: Send constructor arguments! Number of arguments: " + numOfArgs);
243 sendInteger(numOfArgs); recvAck();
244 for(String str : arrCppArgs) {
245 sendString(str); recvAck();
247 System.out.println("IoTSlave: Send constructor argument classes!");
248 for(String str : arrCppArgClasses) {
249 sendString(str); recvAck();
255 * Create new IoTSet for C++
257 //public void createNewIoTSetCpp() throws IOException {
258 public void createNewIoTSetCpp(String strObjFieldName) throws IOException {
260 sendCommCode(IoTCommCode.CREATE_NEW_IOTSET);
261 System.out.println("IoTSlave: Creating new IoTSet...");
262 //String strObjFieldName = "lb_addresses";
263 System.out.println("IoTSlave: Send object field name: " + strObjFieldName);
264 sendString(strObjFieldName); recvAck();
269 * Get a IoTDeviceAddress object for C++
271 public void getDeviceIoTSetObjectCpp() throws IOException {
273 sendCommCode(IoTCommCode.GET_DEVICE_IOTSET_OBJECT);
274 System.out.println("IoTSlave: Getting IoTDeviceAddress...");
275 //String strHostAddress = "192.168.2.232";
276 String strHostAddress = "192.168.2.126";
277 sendString(strHostAddress); recvAck();
278 int iSourcePort = 43583;
279 sendInteger(iSourcePort); recvAck();
280 int iDestPort = 56700;
281 sendInteger(iDestPort); recvAck();
282 boolean bSourceWildCard = false;
283 int iSourceWildCard = (bSourceWildCard ? 1 : 0);
284 sendInteger(iSourceWildCard); recvAck();
285 boolean bDestWildCard = false;
286 int iDestWildCard = (bDestWildCard ? 1 : 0);
287 sendInteger(iDestWildCard); recvAck();
288 System.out.println("IoTSlave: Send host address: " + strHostAddress);
293 * Get a IoTSet content object for C++
295 public void getIoTSetObjectCpp() throws IOException {
297 sendCommCode(IoTCommCode.GET_IOTSET_OBJECT);
298 System.out.println("IoTSlave: Getting IoTSet object content...");
299 String strHostAddress = "localhost";
300 String strDrvObjName = "LifxLightBulbLB2";
301 String strDrvObjClsName = "LifxLightBulb";
302 String strDrvObjIntfaceClsName = "LightBulb";
303 String strDrvObjStubClsName = "LightBulbTest_Stub"; // Send a complete name with "_Stub"
304 int iRegPort = 30313;
305 int iStubPort = 55179;
306 int[] callbackPorts = { 58551 };
308 System.out.println("IoTSlave: Send host address: " + strHostAddress);
309 sendString(strHostAddress); recvAck();
310 System.out.println("IoTSlave: Driver object name: " + strDrvObjName);
311 sendString(strDrvObjName); recvAck();
312 System.out.println("IoTSlave: Driver object class name: " + strDrvObjClsName);
313 sendString(strDrvObjClsName); recvAck();
314 System.out.println("IoTSlave: Driver object interface name: " + strDrvObjIntfaceClsName);
315 sendString(strDrvObjIntfaceClsName); recvAck();
316 System.out.println("IoTSlave: Driver object skeleton class name: " + strDrvObjStubClsName);
317 sendString(strDrvObjStubClsName); recvAck();
318 System.out.println("IoTSlave: Driver object registry port: " + iRegPort);
319 sendInteger(iRegPort); recvAck();
320 System.out.println("IoTSlave: Driver object stub port: " + iStubPort);
321 sendInteger(iStubPort); recvAck();
322 sendInteger(callbackPorts.length); recvAck();
323 for(int i : callbackPorts) {
324 sendInteger(i); recvAck();
331 * Reinitialize IoTSet field for C++
333 private void reinitializeIoTSetFieldCpp() throws IOException {
335 System.out.println("IoTSlave: About to Reinitialize IoTSet field!");
336 sendCommCode(IoTCommCode.REINITIALIZE_IOTSET_FIELD);
337 System.out.println("IoTSlave: Reinitialize IoTSet field!");
342 * Invoke init() for C++
344 private void invokeInitMethodCpp() throws IOException {
346 sendCommCode(IoTCommCode.INVOKE_INIT_METHOD);
347 System.out.println("IoTSlave: Invoke init method!");
352 * End session for C++
354 public void endSessionCpp() throws IOException {
356 // Send message to end session
357 IoTCommCode endSessionCode = IoTCommCode.END_SESSION;
358 int intCode = endSessionCode.ordinal();
359 sendInteger(intCode);
360 //RuntimeOutput.print("IoTSlave: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
361 System.out.println("IoTSlave: Send request to end session!");
365 public static void main(String[] args) throws IOException, InterruptedException {
368 IoTSlave iotSlave = new IoTSlave();
369 iotSlave.setServerSocketCpp(iPort);
370 iotSlave.connectCpp();
371 System.out.println("Connection established with client!");
372 iotSlave.sendInteger(1234);
373 System.out.println("Integer sent!");
374 System.out.println("Integer received: " + iotSlave.recvInteger());
375 String strRecv = iotSlave.recvString();
376 System.out.println("Received string: " + strRecv);
377 strRecv = strRecv + " - ACKNOWLEDGED!";
378 System.out.println("Sending back string: " + strRecv);
379 iotSlave.sendString(strRecv);*/
381 // =========================================
382 // Create IoTSlave for controller object!
383 int iPortMain =12346;
384 String strAddressMain = "localhost";
385 String strObjNameMain = "Lifxtest";
386 IoTSlave iotSlaveMain = new IoTSlave();
387 iotSlaveMain.setServerSocketCpp(iPortMain);
388 // Run thread to spawn C++ IoTSlave
389 String strCmdMain = iotSlaveMain.constructCommand(strAddressMain, iPortMain, strObjNameMain);
390 iotSlaveMain.createCppThread(strCmdMain);
391 iotSlaveMain.connectCpp();
392 System.out.println("IoTSlave: Connection established with main!");
393 // First contact with C++ IoTSlave
394 System.out.println("IoTSlave: IoTSlave.o main is ready: " + iotSlaveMain.recvAck());
396 // =========================================
397 // Create IoTSlave for driver object!
399 String strAddress = "localhost";
400 String strObjName = "LifxLightBulbLB2";
401 IoTSlave iotSlave = new IoTSlave();
402 iotSlave.setServerSocketCpp(iPort);
403 // Run thread to spawn C++ IoTSlave
404 String strCmd = IoTSlave.constructCommand(strAddress, iPort, strObjName);
405 IoTSlave.createCppThread(strCmd);
406 iotSlave.connectCpp();
407 //RuntimeOutput.print("IoTSlave: Connection established!", BOOL_VERBOSE);
408 System.out.println("IoTSlave: Connection established!");
409 // First contact with C++ IoTSlave
410 System.out.println("IoTSlave: IoTSlave.o is ready: " + iotSlave.recvAck());
411 iotSlave.createObjectCpp();
412 //iotSlave.createNewIoTSetCpp();
413 iotSlave.createNewIoTSetCpp("lb_addresses");
414 iotSlave.getDeviceIoTSetObjectCpp();
415 iotSlave.reinitializeIoTSetFieldCpp();
416 //iotSlave.endSessionCpp();
418 // =========================================
419 // Continue with main object
420 iotSlaveMain.createMainObjectCpp();
421 iotSlaveMain.createNewIoTSetCpp("lifx_light_bulb");
422 iotSlaveMain.getIoTSetObjectCpp();
423 iotSlaveMain.reinitializeIoTSetFieldCpp();
424 iotSlaveMain.invokeInitMethodCpp();
425 iotSlaveMain.endSessionCpp();
427 // Send message to create a main object
428 /*commCode = IoTCommCode.CREATE_MAIN_OBJECT;
429 intCode = commCode.ordinal();
430 iotSlave.sendInteger(intCode);
431 //RuntimeOutput.print("IoTSlave: Send request to create a main object: " + strObjName, BOOL_VERBOSE);
432 System.out.println("IoTSlave: Send request to create a main object: " + strObjName);
433 //RuntimeOutput.print("IoTSlave: IoTSlave.o is ready: " + strAck, BOOL_VERBOSE);
434 System.out.println("IoTSlave: IoTSlave.o is ready: " + strAck);*/
436 //Thread.sleep(1000);