1 package org.opentrafficsim.imb.connector;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import org.opentrafficsim.imb.IMBException;
7 import org.opentrafficsim.imb.transceiver.Transceiver;
8
9 import nl.tno.imb.TByteBuffer;
10 import nl.tno.imb.TConnection;
11 import nl.tno.imb.TEventEntry;
12 import nl.tudelft.simulation.language.Throw;
13
14
15
16
17
18
19
20
21
22
23
24
25 public class IMBConnector implements Connector
26 {
27
28 private final TConnection connection;
29
30
31 protected Map<String, Transceiver> imbTransceiverMap = new HashMap<>();
32
33
34
35
36
37
38
39
40
41
42 public IMBConnector(final String host, final int port, final String modelName, final int modelId, final String federation)
43 throws IMBException
44 {
45 Throw.whenNull(host, "host cannot be null");
46 Throw.whenNull(modelName, "modelName cannot be null");
47 Throw.whenNull(modelId, "modelId cannot be null");
48 Throw.whenNull(federation, "federation cannot be null");
49 Throw.when(port <= 0 || port > 65535, IMBException.class, "port should be beween 1 and 65535");
50
51 this.connection = new TConnection(host, port, modelName, modelId, federation);
52 Throw.when(!this.connection.isConnected(), IMBException.class, "No connection to IMB hub on " + host + ":" + port);
53 }
54
55
56
57
58
59
60 public IMBConnector(final TConnection connection) throws IMBException
61 {
62 Throw.whenNull(connection, "conneciton cannot be null");
63
64 this.connection = connection;
65 Throw.when(!this.connection.isConnected(), IMBException.class, "No connection to IMB hub");
66 }
67
68
69 @Override
70 public void register(final String imbEventName, final Transceiver transceiver) throws IMBException
71 {
72 Throw.whenNull(imbEventName, "imbEventName cannot be null");
73 Throw.whenNull(transceiver, "transceiver cannot be null");
74
75
76 if (this.imbTransceiverMap.containsKey(imbEventName))
77 {
78 Throw.when(!this.imbTransceiverMap.get(imbEventName).equals(transceiver), IMBException.class,
79 "Cannot switch transceiver for imbEventName " + imbEventName);
80 return;
81 }
82
83 this.imbTransceiverMap.put(imbEventName, transceiver);
84
85
86 TEventEntry messageEvent = this.connection.subscribe(imbEventName);
87 messageEvent.onNormalEvent = new TEventEntry.TOnNormalEvent()
88 {
89 @Override
90 public void dispatch(TEventEntry aEvent, TByteBuffer aPayload)
91 {
92 String shortIMBEventName = aEvent.getEventName().substring(aEvent.getEventName().indexOf('.') + 1);
93 if (!IMBConnector.this.imbTransceiverMap.containsKey(shortIMBEventName))
94 {
95
96 System.err.println("Could not find imbEventName " + shortIMBEventName + " in imbTransceiverMap");
97 }
98 try
99 {
100
101 IMBConnector.this.imbTransceiverMap.get(shortIMBEventName).handleMessageFromIMB(shortIMBEventName,
102 aPayload);
103 }
104 catch (IMBException exception)
105 {
106
107 exception.printStackTrace();
108 }
109 }
110 };
111
112 }
113
114
115 @Override
116 public final boolean postIMBMessage(final String eventName, final IMBEventType imbEventType, final Object[] args)
117 throws IMBException
118 {
119 TByteBuffer payload = new TByteBuffer();
120 payload.writeStart(0);
121 payload.write(imbEventType.getEventEntry());
122 for (Object o : args)
123 {
124 Class<?> objectClass = o.getClass();
125 if (objectClass.equals(String.class))
126 payload.write((String) o);
127 else if (objectClass.equals(Double.class))
128 payload.write(((Double) o).doubleValue());
129 else if (objectClass.equals(Float.class))
130 payload.write(((Float) o).floatValue());
131 else if (objectClass.equals(Integer.class))
132 payload.write(((Integer) o).intValue());
133 else if (objectClass.equals(Long.class))
134 payload.write(((Long) o).longValue());
135 else if (objectClass.equals(Byte.class))
136 payload.write(((Byte) o).byteValue());
137 else if (objectClass.equals(Character.class))
138 payload.write(((Character) o).charValue());
139 else if (objectClass.equals(Boolean.class))
140 payload.write(((Boolean) o).booleanValue());
141 else if (objectClass.equals(byte[].class))
142 payload.write(new TByteBuffer((byte[]) o));
143 else
144 throw new IMBException("cannot pack object of type " + objectClass.toString() + " in payload");
145 }
146 int result = this.connection.signalEvent(eventName, TEventEntry.EK_NORMAL_EVENT, payload);
147 if (result < 0)
148 {
149 throw new IMBException("IMB error in signalEvent code " + result);
150 }
151 return result >= 0;
152 }
153
154
155 @Override
156 public final String getHost()
157 {
158 return this.connection.getRemoteHost();
159 }
160
161
162 @Override
163 public final int getPort()
164 {
165 return this.connection.getRemotePort();
166 }
167
168
169 @Override
170 public final String getModelName()
171 {
172 return this.connection.getOwnerName();
173 }
174
175
176 @Override
177 public final int getModelId()
178 {
179 return this.connection.getOwnerID();
180 }
181
182
183 @Override
184 public final String getFederation()
185 {
186 return this.connection.getFederation();
187 }
188
189
190 @Override
191 public final String toString()
192 {
193 return "IMBConnector [connection=" + this.connection + "]";
194 }
195
196 }