1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package net.sf.bluecove;
26
27 import java.util.Enumeration;
28 import java.util.Random;
29 import java.util.Vector;
30
31 import javax.bluetooth.BluetoothStateException;
32 import javax.bluetooth.DiscoveryAgent;
33 import javax.bluetooth.LocalDevice;
34
35 import org.bluecove.tester.log.Logger;
36 import org.bluecove.tester.util.RuntimeDetect;
37
38 import net.sf.bluecove.util.BluetoothTypesInfo;
39 import net.sf.bluecove.util.CollectionUtils;
40
41 public class Switcher implements Runnable {
42
43 public static TestResponderClient client;
44
45 private static Vector runningClients = new Vector();
46
47 public static TestResponderServer server;
48
49 private static Vector runningServers = new Vector();
50
51 public static int clientStartCount = 0;
52
53 public static int serverStartCount = 0;
54
55 private boolean stoped = false;
56
57 public Thread thread;
58
59 boolean isRunning = false;
60
61 private static Switcher instance;
62
63 Random random = new Random();
64
65 static Thread tckRFCOMMThread;
66
67 static Thread tckL2CALthread;
68
69 static Thread tckGOEPThread;
70
71 static Thread tckOBEXThread;
72
73 public Switcher() {
74 instance = this;
75 }
76
77 public static synchronized void clear() {
78 clientStartCount = 0;
79 serverStartCount = 0;
80 }
81
82 public static void yield(TestResponderClient client) {
83 if (instance != null) {
84 clientShutdown();
85 synchronized (instance) {
86 instance.notifyAll();
87 }
88 }
89 }
90
91 public static void yield(TestResponderServer server) {
92 if (instance != null) {
93 while (server.hasRunningConnections()) {
94 try {
95 Thread.sleep(2000);
96 } catch (Exception e) {
97 break;
98 }
99 }
100 serverShutdown();
101 }
102 }
103
104 public static boolean isRunning() {
105 return (instance != null) && instance.isRunning;
106 }
107
108 public static boolean isRunningClient() {
109 return ((client != null) && client.isRunning) || (!runningClients.isEmpty());
110 }
111
112 public static boolean isRunningServer() {
113 return isTCKRunning() || ((server != null) && server.isRunning());
114 }
115
116 public static boolean isRunningServerClients() {
117 return ((server != null) && (server.countClientConnections() > 0));
118 }
119
120 public void run() {
121 Logger.debug("Switcher started...");
122 isRunning = true;
123 try {
124 if (!isRunningClient()) {
125 startClient();
126 }
127 while (!stoped) {
128 synchronized (this) {
129 try {
130 wait();
131 } catch (InterruptedException e) {
132 break;
133 }
134 }
135 if (stoped) {
136 break;
137 }
138 try {
139 Thread.sleep(2000);
140 } catch (Exception e) {
141 break;
142 }
143 if (stoped) {
144 break;
145 }
146 startServer();
147 if (stoped) {
148 break;
149 }
150 try {
151 int sec = randomTTL(30, Configuration.serverMAXTimeSec);
152 Logger.info("switch to client in " + sec + " sec");
153 Thread.sleep(sec * 1000);
154 } catch (Exception e) {
155 break;
156 }
157
158 yield(server);
159 if (stoped) {
160 break;
161 }
162 try {
163 Thread.sleep(2000);
164 } catch (Exception e) {
165 break;
166 }
167 if (stoped) {
168 break;
169 }
170 startClient();
171
172 }
173 } finally {
174 isRunning = false;
175 Logger.info("Switcher finished!");
176 }
177 }
178
179 public int randomTTL(int min, int max) {
180 int d = random.nextInt() % (max - min);
181 if (d < 0) {
182 d = -d;
183 }
184 return min + d;
185 }
186
187 public void shutdown() {
188 Logger.info("shutdownSwitcher");
189 stoped = true;
190 interruptThread(thread);
191 synchronized (this) {
192 notifyAll();
193 }
194 instance = null;
195 }
196
197 public static void clientStarted(CanShutdown t) {
198 runningClients.addElement(t);
199 }
200
201 public static void clientEnds(CanShutdown t) {
202 runningClients.removeElement(t);
203 }
204
205 public static void interruptThread(Thread thread) {
206 if (RuntimeDetect.cldcStub != null) {
207 RuntimeDetect.cldcStub.interruptThread(thread);
208 }
209 }
210
211 public static Thread createThreadByName(String className) {
212 try {
213 Class c = Class.forName(className);
214 return (Thread) c.newInstance();
215 } catch (Throwable e) {
216 Logger.debug(className, e);
217 return null;
218 }
219 }
220
221 public static void startTCKAgent() {
222 try {
223 LocalDevice localDevice = LocalDevice.getLocalDevice();
224 Logger.info("address:" + localDevice.getBluetoothAddress());
225 Logger.info("name:" + localDevice.getFriendlyName());
226 Logger.info("class:" + BluetoothTypesInfo.toString(localDevice.getDeviceClass()));
227 localDevice.setDiscoverable(DiscoveryAgent.GIAC);
228 } catch (BluetoothStateException e) {
229 Logger.error("start", e);
230 return;
231 }
232
233 if (Configuration.likedTCKAgent) {
234 try {
235 SwitcherTck.startTCKAgent();
236 } catch (Throwable e) {
237 Logger.error("Error", e);
238 }
239 }
240 }
241
242 public static boolean isTCKRunning() {
243 return (tckRFCOMMThread != null) || (tckL2CALthread != null) || (tckGOEPThread != null)
244 || (tckOBEXThread != null);
245 }
246
247 static void stopTCK() {
248 interruptThread(tckRFCOMMThread);
249 tckRFCOMMThread = null;
250
251 interruptThread(tckL2CALthread);
252 tckL2CALthread = null;
253
254 interruptThread(tckGOEPThread);
255 tckGOEPThread = null;
256
257 interruptThread(tckOBEXThread);
258 tckOBEXThread = null;
259 }
260
261 public static TestResponderClient createClient() {
262 return createClient(false);
263 }
264
265 public static TestResponderClient createClient(boolean force) {
266 try {
267 TestResponderClient c;
268 if ((client == null) || (force)) {
269 c = new TestResponderClient(!force);
270 client = c;
271 } else {
272 c = client;
273 }
274 if (!c.isRunning) {
275 c.config.logID = "";
276 c.configured = false;
277 c.config.discoveryOnce = false;
278 c.config.connectDevice = null;
279 c.config.searchServiceRetry = true;
280 c.config.useDiscoveredDevices = false;
281 c.config.searchOnlyBluecoveUuid = Configuration.searchOnlyBluecoveUuid;
282 String name = "Client" + clientStartCount++;
283 c.thread = RuntimeDetect.cldcStub.createNamedThread(c, name);
284 c.thread.start();
285 return c;
286 } else {
287 if (RuntimeDetect.isJ2ME) {
288 BlueCoveTestMIDlet.message("Warn", "Client is already Running");
289 } else {
290 Logger.warn("Client is already Running");
291 }
292 return null;
293 }
294 } catch (Throwable e) {
295 Logger.error("start error ", e);
296 return null;
297 }
298 }
299
300 public static void startTwoClients() {
301 try {
302 client = new TestResponderClient();
303 client.configured = false;
304 client.config.discoveryOnce = false;
305 client.config.useDiscoveredDevices = false;
306 client.config.searchOnlyBluecoveUuid = Configuration.searchOnlyBluecoveUuid;
307 client.thread = new Thread(client);
308 client.configured();
309
310 TestResponderClient client2 = new TestResponderClient();
311 client2.configured = false;
312 client2.config.discoveryOnce = false;
313 client2.config.useDiscoveredDevices = false;
314 client2.config.searchOnlyBluecoveUuid = Configuration.searchOnlyBluecoveUuid;
315 client2.thread = new Thread(client2);
316 client2.configured();
317
318 client.thread.start();
319 client2.thread.start();
320 } catch (Throwable e) {
321 Logger.error("start error ", e);
322 }
323 }
324
325 public static void startDiscovery() {
326 TestResponderClient client = createClient();
327 if (client != null) {
328 client.config.discoveryOnce = true;
329 client.config.useDiscoveredDevices = false;
330 client.config.searchOnlyBluecoveUuid = Configuration.discoverySearchOnlyBluecoveUuid;
331 client.configured();
332 }
333 }
334
335 public static void startServicesSearch() {
336 TestResponderClient client = createClient();
337 if (client != null) {
338 client.config.discoveryOnce = true;
339 client.config.useDiscoveredDevices = true;
340 client.config.searchOnlyBluecoveUuid = Configuration.discoverySearchOnlyBluecoveUuid;
341 client.configured();
342 }
343 }
344
345 public static void startClient() {
346 try {
347 createClient();
348 if (client != null) {
349 client.configured();
350 }
351 } catch (Throwable e) {
352 Logger.error("startClient", e);
353 }
354 }
355
356 public static int runClient() {
357 createClient();
358 if (client != null) {
359 client.config.connectOnce = true;
360 client.configured();
361 try {
362 client.thread.join();
363 } catch (InterruptedException e) {
364 return 2;
365 }
366 if (TestResponderClient.failure.countFailure > 0) {
367 return 2;
368 } else if (TestResponderClient.countSuccess == 0) {
369 return 3;
370 }
371 return 1;
372 } else {
373 return 2;
374 }
375 }
376
377 public static void startClientStress() {
378 if ((client != null) && client.isRunning) {
379 Logger.warn("Client is already Running");
380 return;
381 }
382 createClient();
383 if (client != null) {
384 client.runStressTest = true;
385 client.configured();
386 }
387 }
388
389 public static void startClientLastURl() {
390 if (Configuration.storage == null) {
391 Logger.warn("no storage");
392 return;
393 }
394 if ((client != null) && client.isRunning) {
395 Logger.warn("Client is already Running");
396 return;
397 }
398 String lastURL = Configuration.getLastServerURL();
399 if (lastURL != null) {
400 createClient();
401 if (client != null) {
402 client.config.connectURL = lastURL;
403 client.configured();
404 }
405 } else {
406 Logger.warn("no recent Connections");
407 }
408 }
409
410 public static void startClientSelectService() {
411 if ((client != null) && client.isRunning) {
412 Logger.warn("Client is already Running");
413 return;
414 }
415 createClient();
416 if (client != null) {
417 client.config.connectURL = "";
418 client.configured();
419 }
420 }
421
422 public static void startClientLastDevice() {
423 if (Configuration.storage == null) {
424 Logger.warn("no storage");
425 return;
426 }
427 if ((client != null) && client.isRunning) {
428 Logger.warn("Client is already Running");
429 return;
430 }
431 String lastURL = Configuration.getLastServerURL();
432 if (lastURL != null) {
433 createClient();
434 if (client != null) {
435 client.config.connectDevice = BluetoothTypesInfo.extractBluetoothAddress(lastURL);
436 client.configured();
437 }
438 } else {
439 Logger.warn("no recent Connections");
440 }
441 }
442
443 public static void clientShutdown() {
444 if (client != null) {
445 client.shutdown();
446 client = null;
447 }
448 Vector runningClientsCopy = CollectionUtils.copy(runningClients);
449 for (Enumeration iter = runningClientsCopy.elements(); iter.hasMoreElements();) {
450 CanShutdown t = (CanShutdown) iter.nextElement();
451 t.shutdown();
452 }
453 }
454
455 public static void startServer() {
456 try {
457 if (server == null) {
458 server = new TestResponderServer();
459 }
460 if (!server.isRunning()) {
461 String name = "Server" + serverStartCount++;
462 server.thread = RuntimeDetect.cldcStub.createNamedThread(server, name);
463 server.thread.start();
464 } else {
465 if (Configuration.canCloseServer) {
466 if (RuntimeDetect.isJ2ME) {
467 BlueCoveTestMIDlet.message("Warn", "Server is already running");
468 } else {
469 Logger.warn("Server is already running");
470 }
471 } else {
472 serverStartCount++;
473 server.updateServiceRecord();
474 TestResponderServer.setDiscoverable();
475 }
476 }
477 } catch (Throwable e) {
478 Logger.error("start error ", e);
479 }
480 }
481
482 public static void serverShutdown() {
483 if (Configuration.canCloseServer) {
484 serverShutdownForce();
485 } else {
486 TestResponderServer.setNotDiscoverable();
487 }
488 stopTCK();
489 }
490
491 public static void serverShutdownOnExit() {
492 serverShutdownForce();
493 }
494
495 public static void serverShutdownForce() {
496 if (server != null) {
497 server.shutdown();
498 server = null;
499 }
500 }
501
502 public static void closeServerClientConnections() {
503 if (server != null) {
504 server.closeServerClientConnections();
505 }
506 }
507
508 }