Source Code Cross Referenced for EmulationServer.java in  » 6.0-JDK-Modules » j2me » com » sun » midp » jsr82emul » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » com.sun.midp.jsr82emul 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *   
003:         *
004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006:         * 
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License version
009:         * 2 only, as published by the Free Software Foundation.
010:         * 
011:         * This program is distributed in the hope that it will be useful, but
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014:         * General Public License version 2 for more details (a copy is
015:         * included at /legal/license.txt).
016:         * 
017:         * You should have received a copy of the GNU General Public License
018:         * version 2 along with this work; if not, write to the Free Software
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA
021:         * 
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023:         * Clara, CA 95054 or visit www.sun.com if you need additional
024:         * information or have any questions.
025:         */
026:        package com.sun.midp.jsr82emul;
027:
028:        import java.io.IOException;
029:        import java.util.Hashtable;
030:        import java.util.Enumeration;
031:
032:        import javax.microedition.io.SocketConnection;
033:
034:        import com.sun.midp.security.SecurityToken;
035:        import com.sun.midp.security.ImplicitlyTrustedClass;
036:        import com.sun.midp.io.j2me.serversocket.Socket;
037:        import com.sun.midp.main.Configuration;
038:        import com.sun.midp.jsr082.BluetoothUtils;
039:        import com.sun.midp.jsr082.SecurityInitializer;
040:
041:        import javax.bluetooth.BluetoothConnectionException;
042:
043:        /**
044:         * Represents an emulation server used for JSR 82 emulation environment. 
045:         * It is not a part of JSR 82 implementation and is only used within 
046:         * JSR 82 emulation mode. The emulation mode allows running tests without
047:         * real native Bluetooth libraries or hardware.
048:         * 
049:         * In the emulation mode the server runs in a sepate thread or as a 
050:         * standalone application. It emulates Bluetooth ether, i.e. keeps 
051:         * information on services being advertised and "devices" that present.
052:         *
053:         * Actually it keeps TCP socket connections to clients.
054:         */
055:        public class EmulationServer implements  Runnable {
056:            /** Shows if emulation server is already running. */
057:            private static boolean launched = false;
058:
059:            /** The only instance of <code>EmulationServer</code>. */
060:            private static EmulationServer instance = null;
061:
062:            /**
063:             * Inner class to request security token from SecurityInitializer.
064:             * SecurityInitializer should be able to check this inner class name.
065:             */
066:            static private class SecurityTrusted implements 
067:                    ImplicitlyTrustedClass {
068:            };
069:
070:            /** This class has a different security domain than the MIDlet suite. */
071:            private static SecurityToken internalSecurityToken = SecurityInitializer
072:                    .requestToken(new SecurityTrusted());
073:
074:            /** Server socket that accepts TCP clients connections. */
075:            private static Socket serverSocket;
076:
077:            // IMPL_NOTE: make it configurable.
078:            /** Port to open server socket at. */
079:            private static final int SOCKET_PORT = 1234;
080:
081:            /** 
082:             * Duration of a delay that is applied prior to start inquiry in 
083:             * order to let all emulated devices update their device classes.
084:             */
085:            private static final int INQUIRY_DELAY = 2000;
086:
087:            /** Keeps services being advertised in the ether. */
088:            private Hashtable services = new Hashtable();
089:
090:            /** Keeps devices that present in the ether. */
091:            private Hashtable devices = new Hashtable();
092:
093:            /** Default Bluetooth address wrapped by DeviceKey objects. */
094:            private static final DeviceKey[] defaultAddr = {
095:                    new DeviceKey(
096:                            BluetoothUtils
097:                                    .getAddressBytes(Configuration
098:                                            .getProperty("com.sun.midp.jsr82emul.localBluetoothAddress"))),
099:                    new DeviceKey(
100:                            BluetoothUtils
101:                                    .getAddressBytes(Configuration
102:                                            .getProperty("com.sun.midp.jsr82emul.localBluetoothAddress2"))) };
103:            /** Amount of default addresses. */
104:            static final int ADDR_COUNT = 2;
105:
106:            /** Value used to generate unique Bluetooth addresses. */
107:            int nextAddr = 1;
108:
109:            /**
110:             * Launches the server in a standalone manner.
111:             * @param args command line arguments
112:             */
113:            public static void main(String[] args) {
114:                launch();
115:            }
116:
117:            /**
118:             * Launches the server if not yet running.
119:             */
120:            public static synchronized void launch() {
121:                if (launched) {
122:                    return;
123:                }
124:
125:                try {
126:                    serverSocket = new Socket();
127:                    serverSocket.open(SOCKET_PORT, internalSecurityToken);
128:
129:                    instance = new EmulationServer();
130:                    Thread thread = new Thread(instance);
131:                    thread.start();
132:                } catch (IOException e) {
133:                    // server is already running within another isolate or under
134:                    // another VM control - nothing to do
135:                } finally {
136:                    launched = true;
137:                }
138:            }
139:
140:            /** 
141:             * Retrns the only instance if the server. 
142:             * @return the singleton instance of <code>EmulationServer</code>.
143:             */
144:            public static EmulationServer getInstance() {
145:                launch();
146:                return instance;
147:            }
148:
149:            /**
150:             * The Runnable interface implementation.
151:             */
152:            public void run() {
153:                while (true) {
154:                    try {
155:                        new ClientHandler((SocketConnection) serverSocket
156:                                .acceptAndOpen());
157:                    } catch (Throwable e) {
158:                        // ignoring
159:                    }
160:                }
161:            }
162:
163:            /** 
164:             * Registers new device in the ether.
165:             *
166:             * @param deviceState state of device that defines its current discoverable
167:             * mode and class of device
168:             * @return Bluetooth addres for the registered device that identifies it 
169:             * in the emulated ether. 
170:             */
171:            public synchronized byte[] registerDevice(DeviceState deviceState) {
172:                DeviceKey key = null;
173:                int i;
174:
175:                for (i = 0; i < ADDR_COUNT; i++) {
176:                    if (!devices.containsKey(defaultAddr[i])) {
177:                        key = defaultAddr[i];
178:                        break;
179:                    }
180:                }
181:
182:                if (i == ADDR_COUNT) {
183:                    byte[] btaddr = new byte[Const.BTADDR_SIZE];
184:                    for (i = 0; i < 4; i++) {
185:                        btaddr[i] = (byte) (nextAddr >> (8 * i));
186:                    }
187:                    key = new DeviceKey(btaddr);
188:                    nextAddr = nextAddr % (Integer.MAX_VALUE - 1) + 1;
189:                }
190:
191:                devices.put(key, deviceState);
192:                return key.getAddrBytes();
193:            }
194:
195:            /**
196:             * Unregisters device from the emulated ether.
197:             *
198:             * @param btaddr Bluetooth address of the device to be unregistered
199:             */
200:            public synchronized void unregisterDevice(byte[] btaddr) {
201:                devices.remove(new DeviceKey(btaddr));
202:            }
203:
204:            /**
205:             * Performs inquiry (devices discovery).
206:             * @param discoverable discoverable mode to search devices with
207:             * @param btaddr Bluetooth address of device that performs inquiry - it
208:             *        should not discover itself.
209:             * @return <code>InquiryResults</code> instance that represents inquiry
210:             *        results
211:             */
212:            public InquiryResults runInquiry(int discoverable, byte[] btaddr) {
213:                try {
214:                    // Syncronizing classes of devices for the scenario like this:
215:                    //     - make an action that should update class of device1;
216:                    //     - start inquiry on device2 expecting updated class of device1.
217:                    // In this case class of device1 changes immediately locally but
218:                    // it takes time to update it on the emulation server and affect all
219:                    // inquiry operations. Waiting here to let class of device1 to become
220:                    // up-to-date. 
221:                    Thread.sleep(INQUIRY_DELAY);
222:                } catch (InterruptedException e) {
223:                }
224:
225:                InquiryResults res = new InquiryResults();
226:                Enumeration addresses = devices.keys();
227:                Enumeration states = devices.elements();
228:
229:                while (addresses.hasMoreElements()) {
230:                    DeviceKey addr = (DeviceKey) addresses.nextElement();
231:                    DeviceState state = (DeviceState) states.nextElement();
232:
233:                    if (state.getDiscoverable() == discoverable
234:                            && !addr.equals(btaddr)) {
235:                        res.add(addr.getAddrBytes(), state.getCoD());
236:                    }
237:                }
238:
239:                return res;
240:            }
241:
242:            /** 
243:             * Registers a service in Bluetooth ether, i.e. starts advertising it.
244:             *
245:             * @param service service connection data provided by service holder
246:             * @param btaddr Bluetooth address of service holder
247:             * @return service key that identifies the service at emulation server,
248:             *        if registration succeeded, <code>null</code> otherwize
249:             */
250:            public ServiceKey registerService(ServiceConnectionData service,
251:                    byte[] btaddr) {
252:
253:                ServiceKey key = new ServiceKey(btaddr, service.protocol,
254:                        service.port);
255:
256:                Log.log("SERVER: registreing service " + key);
257:
258:                ServiceConnectionData registered = (ServiceConnectionData) services
259:                        .get(key);
260:
261:                if (registered != null) {
262:                    registered.setAccepting();
263:                } else {
264:                    services.put(key, service);
265:                }
266:
267:                return key;
268:            }
269:
270:            /** 
271:             * Stops advertising the service represented by given record.
272:             * @param key service key that represents the service to be unregistered
273:             */
274:            public void unregisterService(ServiceKey key) {
275:                Log.log("SERVER: unregistreing service " + key);
276:                services.remove(key);
277:            }
278:
279:            /** 
280:             * Retrieves emulation (TCP) connection URL for connecting to the
281:             * service represented by given JSR 82 client connection string.
282:             *
283:             * @param client client connection parameters
284:             * @return <code>ServiceConnectionData</code> instance that either
285:             *         contains connection properties or error code
286:             */
287:            public ServiceConnectionData connectToService(
288:                    ServiceConnectionData client) {
289:
290:                ServiceKey key = new ServiceKey(client.address,
291:                        client.protocol, client.port);
292:                ServiceConnectionData service = (ServiceConnectionData) services
293:                        .get(key);
294:
295:                // Log.log("SERVER: requested connection to service " + key);
296:
297:                if (service == null) {
298:                    // indicates error
299:                    client.error = BluetoothConnectionException.FAILED_NOINFO;
300:                    // Log.log("SERVER: service not found " + key);
301:                } else {
302:                    // either accepts or sets error value
303:                    service.accept(client);
304:                }
305:
306:                return client;
307:            }
308:        }
309:
310:        /**
311:         * Represetnts key for services registry. A service is identified by
312:         * Bluetooth address of host device, protocol type and PSM or channel
313:         * id.
314:         */
315:        class ServiceKey {
316:            /** Bluetooth address of the advertising server. */
317:            DeviceKey btaddr;
318:            /** 
319:             * Protocol this service is connectable thru. Is one of 
320:             * <code>BluetoothUrl.L2CAP, BluetoothUrl.RFCOMM</code
321:             */
322:            int protocol;
323:            /** Channel in case of RFCOMM or PSM in case of L2CAP. */
324:            int channelOrPsm;
325:
326:            /** 
327:             * Constructs a key.
328:             * @param btaddr value for <code>bluetoothAddress</code>
329:             * @param protocol value for <code>protocol</code>
330:             * @param channelOrPsm value for <code>channelOrPsm</code> 
331:             */
332:            ServiceKey(byte[] btaddr, int protocol, int channelOrPsm) {
333:                this .btaddr = new DeviceKey(btaddr);
334:                this .protocol = protocol;
335:                this .channelOrPsm = channelOrPsm;
336:            }
337:
338:            /** 
339:             * Checks if this key is equivalent to given one.
340:             * @param obj a <code>ServiceKey</code> instance to be compared
341:             *        to this one
342:             * @return true if this key is equal to the given one,
343:             *        false otherwise.
344:             */
345:            public boolean equals(Object obj) {
346:                ServiceKey rec = (ServiceKey) obj;
347:
348:                return btaddr.equals(rec.btaddr) && protocol == rec.protocol
349:                        && channelOrPsm == rec.channelOrPsm;
350:            }
351:
352:            /** 
353:             * Returns a proper hash code for using in Hashtable.
354:             * @return hash code value for this instance
355:             */
356:            public int hashCode() {
357:                return channelOrPsm;
358:            }
359:        }
360:
361:        /** 
362:         * Wrapper for bluetooth address bytes that allows keeping 
363:         * and comparing Bluetooth addresses. Used as a device key
364:         * in Hashtable.
365:         */
366:        class DeviceKey {
367:            /** Bluetooth addres. */
368:            private final byte[] addr = new byte[Const.BTADDR_SIZE];
369:
370:            /**
371:             * Creates instance with given addres. 
372:             * @param addr Bluetooth address
373:             */
374:            public DeviceKey(byte[] addr) {
375:                System.arraycopy(addr, 0, this .addr, 0, Const.BTADDR_SIZE);
376:            }
377:
378:            /** 
379:             * Returns a proper hash code for using in Hashtable.
380:             * @return hash code value for this instance
381:             */
382:            public int hashCode() {
383:                return addr[0];
384:            }
385:
386:            /** 
387:             * Checks if this instance and given one wrap the same address. 
388:             * @param obj object to check for equity
389:             * @return true if given object represents the same address,
390:             *        false otherwise
391:             */
392:            public boolean equals(Object obj) {
393:                return equals(((DeviceKey) obj).addr);
394:            }
395:
396:            /** 
397:             * Checks if this instance wraps the same address as given one. 
398:             * @param addr Bluetooth address to check for equity
399:             * @return true if addresses are equal, false otherwise
400:             */
401:            public boolean equals(byte[] addr) {
402:                for (int i = 0; i < Const.BTADDR_SIZE; i++) {
403:                    if (addr[i] != this .addr[i]) {
404:                        return false;
405:                    }
406:                }
407:
408:                return true;
409:            }
410:
411:            /** 
412:             * Returns bytes representation of wrapped Bluetooth address. 
413:             * @return Bluetooth address bytes
414:             */
415:            public byte[] getAddrBytes() {
416:                return addr;
417:            }
418:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.