Adding stub and skeleton for Lifxtest and LifxLightBulb; Creating build flow for...
[iot2.git] / iotjava / iotruntime / cpp / iotslave / IoTSlave.java
1 import java.util.*;
2 import java.io.*;
3 import java.net.*;
4 import java.nio.*;
5
6 public class IoTSlave {
7
8         private ServerSocket serverSocket;
9         private Socket socket;
10         private BufferedInputStream input;
11         private BufferedOutputStream output;
12
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)
19
20
21         public IoTSlave() {
22
23                 serverSocket = null;
24                 socket = null;
25                 input = null;
26                 output = null;
27         }
28
29
30         /**
31          * Prepare server socket connection with C++ IoTSlave
32          */
33         public void setServerSocketCpp(int iPort) {
34
35                 try {
36                         serverSocket = new ServerSocket(iPort);
37                 }
38                 catch ( IOException e ) {
39                         e.printStackTrace();
40                 }
41         }
42
43
44         /**
45          * sendInteger() sends an integer in bytes
46          */
47         public void sendInteger(int intSend) throws IOException {
48
49                 // Transform integer into bytes
50                 ByteBuffer bb = ByteBuffer.allocate(INT_SIZE);
51                 bb.putInt(intSend);
52                 // Send the byte array
53                 output.write(bb.array(), 0, INT_SIZE);
54                 output.flush();
55         }
56
57
58         /**
59          * recvInteger() receives integer in bytes
60          */
61         public int recvInteger() throws IOException {
62
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();
69
70                 return retVal;
71         }
72
73
74         /**
75          * recvString() receives String in bytes
76          */
77         public String recvString() throws IOException {
78
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);
86
87                 return retVal;
88         }
89
90
91         /**
92          * sendString() sends a String in bytes
93          */
94         public void sendString(String strSend) throws IOException {
95
96                 // Transform String into bytes
97                 byte[] strSendBytes = strSend.getBytes();
98                 int strLen = strSend.length();
99                 // Send the string length first
100                 sendInteger(strLen);
101                 // Send the byte array
102                 output.write(strSendBytes, 0, strLen);
103                 output.flush();
104         }
105
106
107         /**
108          * Establish connection with C++ IoTSlave
109          */
110         public void connectCpp() throws IOException     {
111
112                 socket = serverSocket.accept();
113                 input = new BufferedInputStream(socket.getInputStream());
114                 output = new BufferedOutputStream(socket.getOutputStream());
115         }
116
117
118         /**
119          * Construct a SSH command to run C++ program
120          */
121         public static String constructCommand(String serverAddress, int serverPort, String strObjName) {
122
123                 String strCommand = STR_IOTSLAVE_CPP + " " + serverAddress + " " + serverPort + " " + strObjName;
124                 return strCommand;
125         }
126
127
128         /**
129          * Create a new thread to start a new C++ process
130          */
131         public static void createCppThread(String strCmd) {
132
133                 Thread thread = new Thread(new Runnable() {
134                         public void run() {
135                                 try {
136                                         Runtime runtime = Runtime.getRuntime();
137                                         Process process = runtime.exec(strCmd);
138                                 } catch(IOException ex) {
139                                         ex.printStackTrace();
140                                 }
141                         }
142                 });
143                 thread.start();
144                 //RuntimeOutput.print("IoTSlave: Executing: " + strCmd, BOOL_VERBOSE);
145                 System.out.println("IoTSlave: Executing: " + strCmd);
146         }
147
148
149         /**
150          * Convert integer to enum
151          */
152         public IoTCommCode getCode(int intCode) throws IOException {
153
154                 IoTCommCode[] commCode = IoTCommCode.values();
155                 IoTCommCode retCode = commCode[intCode];
156                 return retCode;
157
158         }
159
160
161         /**
162          * Receive ACK
163          */
164         public boolean recvAck() throws IOException {
165
166                 int intAck = recvInteger();
167                 IoTCommCode codeAck = getCode(intAck);
168                 if (codeAck == IoTCommCode.ACKNOWLEDGED)
169                         return true;
170                 return false;
171
172         }
173
174
175         /**
176          * Send END
177          */
178         public void sendEndTransfer() throws IOException {
179
180                 int endCode = IoTCommCode.END_TRANSFER.ordinal();
181                 sendInteger(endCode);
182         }
183
184
185         /**
186          * Create a driver object for C++
187          */
188         public void createObjectCpp() throws IOException {
189
190                 IoTCommCode commCode = null;
191                 int intCode = 0;
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();
223                 }
224                 System.out.println("IoTSlave: Send constructor argument classes!");
225                 for(String str : arrCppArgClasses) {
226                         sendString(str); recvAck();
227                 }
228         }
229
230
231         /**
232          * Send object fields
233          */
234         private void sendFieldsCpp() throws IOException {
235
236                 
237         }
238
239
240         /**
241          * Send object field types
242          */
243         private void sendFieldTypesCpp() throws IOException {
244
245                 
246         }
247
248
249         /**
250          * End session for C++
251          */
252         public void endSessionCpp() throws IOException {
253
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!");
260         }
261
262
263         public static void main(String[] args) throws IOException, InterruptedException {
264
265                 /*int iPort = 12345;
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);*/
278
279                 int iPort =12345;
280                 String strAddress = "localhost";
281                 String strObjName = "Lifxtest";
282
283                 IoTSlave iotSlave = new IoTSlave();
284                 iotSlave.setServerSocketCpp(iPort);
285
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());
294
295                 iotSlave.createObjectCpp();
296
297
298                 iotSlave.endSessionCpp();
299
300
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);*/
309
310                 //Thread.sleep(1000);
311
312         }
313 }