3 import java.io.IOException;
4 import java.nio.ByteBuffer;
5 import java.util.Arrays;
6 import java.util.ArrayList;
7 import java.util.HashMap;
11 import java.lang.reflect.*;
13 import java.util.concurrent.*;
14 import java.util.concurrent.atomic.AtomicBoolean;
17 /** Class IoTRMICommClient is a class that extends IoTRMIComm
19 * This is a version of IoTRMIComm that sits on the main stub.
21 * @author Rahmadi Trimananda <rtrimana @ uci.edu>
25 public final class IoTRMICommClient extends IoTRMIComm {
30 private IoTSocketClient rmiClientSend;
31 private IoTSocketClient rmiClientRecv;
35 * Constructor (for stub) - send and recv from the perspective of RMI socket servers
37 public IoTRMICommClient(int _localPortSend, int _localPortRecv, int _portSend, int _portRecv, String _address, int _rev) throws
38 ClassNotFoundException, InstantiationException,
39 IllegalAccessException, IOException {
42 rmiClientRecv = new IoTSocketClient(_localPortSend, _portSend, _address, _rev);
43 rmiClientSend = new IoTSocketClient(_localPortRecv, _portRecv, _address, _rev);
44 waitForPacketsOnClient();
49 * Constructor (for stub) - only destination port numbers
51 public IoTRMICommClient(int _portSend, int _portRecv, String _address, int _rev) throws
52 ClassNotFoundException, InstantiationException,
53 IllegalAccessException, IOException {
56 rmiClientRecv = new IoTSocketClient(_portSend, _address, _rev);
57 rmiClientSend = new IoTSocketClient(_portRecv, _address, _rev);
58 waitForPacketsOnClient();
63 * waitForPacketsOnClient() starts a thread that waits for packet bytes on client side
65 public void waitForPacketsOnClient() {
67 Thread thread = new Thread() {
69 byte[] packetBytes = null;
72 packetBytes = rmiClientRecv.receiveBytes(packetBytes);
73 if (packetBytes != null) {
74 int packetType = IoTRMIComm.getPacketType(packetBytes);
75 if (packetType == IoTRMIUtil.METHOD_TYPE) {
76 //System.out.println("Method packet: " + Arrays.toString(packetBytes));
77 methodQueue.offer(packetBytes);
78 } else if (packetType == IoTRMIUtil.RET_VAL_TYPE) {
79 //System.out.println("Return value packet: " + Arrays.toString(packetBytes));
80 returnQueue.offer(packetBytes);
82 throw new Error("IoTRMICommClient: Packet type is unknown: " + packetType);
86 } catch (Exception ex) {
88 throw new Error("IoTRMICommClient: Error receiving return value bytes on client!");
98 * sendReturnObj() for non-struct objects (client side)
100 public synchronized void sendReturnObj(Object retObj, byte[] methodBytes) {
102 // Send back return value
103 //byte[] retObjBytes = IoTRMIUtil.getObjectBytes(retObj);
104 byte[] retObjBytes = null;
105 if (retObj != null) // Handle nullness
106 retObjBytes = IoTRMIUtil.getObjectBytes(retObj);
107 // Send return value together with OBJECT_ID and METHOD_ID for arbitration
108 int objMethIdLen = IoTRMIUtil.OBJECT_ID_LEN + IoTRMIUtil.METHOD_ID_LEN;
109 int headerLen = objMethIdLen + IoTRMIUtil.PACKET_TYPE_LEN;
110 //byte[] retAllBytes = new byte[headerLen + retObjBytes.length];
111 byte[] retAllBytes = null;
112 if (retObj == null) // Handle nullness
113 retAllBytes = new byte[headerLen];
115 retAllBytes = new byte[headerLen + retObjBytes.length];
116 // Copy OBJECT_ID and METHOD_ID
117 System.arraycopy(methodBytes, 0, retAllBytes, 0, objMethIdLen);
118 int packetType = IoTRMIUtil.RET_VAL_TYPE; // This is a return value
119 byte[] packetTypeBytes = IoTRMIUtil.intToByteArray(packetType);
120 System.arraycopy(packetTypeBytes, 0, retAllBytes, objMethIdLen, IoTRMIUtil.PACKET_TYPE_LEN);
121 // Copy array of bytes (return object)
123 System.arraycopy(retObjBytes, 0, retAllBytes, headerLen, retObjBytes.length);
125 rmiClientSend.sendBytes(retAllBytes);
126 } catch (IOException ex) {
127 ex.printStackTrace();
128 throw new Error("IoTRMICommClient: Error sending bytes in sendReturnObj()!");
134 * sendReturnObj() overloaded to send multiple return objects for structs (client side)
136 public synchronized void sendReturnObj(Class<?>[] retCls, Object[] retObj, byte[] methodBytes) {
138 // Send back return value
139 byte[] retObjBytes = returnToBytes(retCls, retObj);
140 // Send return value together with OBJECT_ID and METHOD_ID for arbitration
141 int objMethIdLen = IoTRMIUtil.OBJECT_ID_LEN + IoTRMIUtil.METHOD_ID_LEN;
142 int headerLen = objMethIdLen + IoTRMIUtil.PACKET_TYPE_LEN;
143 byte[] retAllBytes = new byte[headerLen + retObjBytes.length];
144 // Copy OBJECT_ID and METHOD_ID
145 System.arraycopy(methodBytes, 0, retAllBytes, 0, objMethIdLen);
146 int packetType = IoTRMIUtil.RET_VAL_TYPE; // This is a return value
147 byte[] packetTypeBytes = IoTRMIUtil.intToByteArray(packetType);
148 System.arraycopy(packetTypeBytes, 0, retAllBytes, objMethIdLen, IoTRMIUtil.PACKET_TYPE_LEN);
149 // Copy array of bytes (return object)
151 rmiClientSend.sendBytes(retAllBytes);
152 } catch (IOException ex) {
153 ex.printStackTrace();
154 throw new Error("IoTRMICommClient: Error sending bytes in sendReturnObj()!");
160 * remoteCall() calls a method remotely by passing in parameters (client side)
162 public synchronized void remoteCall(int objectId, int methodId, Class<?>[] paramCls, Object[] paramObj) {
165 byte[] methodBytes = methodToBytes(objectId, methodId, paramCls, paramObj);
167 rmiClientSend.sendBytes(methodBytes);
168 } catch (IOException ex) {
169 ex.printStackTrace();
170 throw new Error("IoTRMICommClient: Error when sending bytes in remoteCall()!");