Source Code Cross Referenced for L2CAPNotifierImpl.java in  » 6.0-JDK-Modules » j2me » com » sun » midp » io » j2me » btl2cap » 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.io.j2me.btl2cap 
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:
027:        package com.sun.midp.io.j2me.btl2cap;
028:
029:        import java.io.IOException;
030:        import java.io.InterruptedIOException;
031:        import com.sun.midp.io.BluetoothUrl;
032:        import javax.bluetooth.*;
033:        import java.util.Enumeration;
034:        import com.sun.midp.midlet.MIDletStateHandler;
035:        import com.sun.midp.midlet.MIDletSuite;
036:        import com.sun.midp.jsr082.bluetooth.BluetoothPush;
037:        import com.sun.kvem.jsr082.bluetooth.SDDB;
038:        import com.sun.kvem.jsr082.bluetooth.BCC;
039:        import com.sun.kvem.jsr082.bluetooth.ServiceRecordImpl;
040:        import com.sun.kvem.jsr082.bluetooth.BluetoothNotifier;
041:        import com.sun.kvem.jsr082.bluetooth.SDP;
042:
043:        /**
044:         * Implementation of <code>L2CAPConnectionNotifier</code>.
045:         * An instance is created when
046:         * <code>Connector.open("btltcap://localhost...") </code>
047:         * is called from server application.
048:         */
049:        public class L2CAPNotifierImpl extends BluetoothNotifier implements 
050:                L2CAPConnectionNotifier {
051:
052:            /** Static initializer. */
053:            static {
054:                initialize();
055:            }
056:
057:            /**
058:             * Native static class initializer.
059:             */
060:            private native static void initialize();
061:
062:            /**
063:             * Native finalizer.
064:             * Releases all native resources used by this connection.
065:             */
066:            private native void finalize();
067:
068:            /**
069:             * Identidies this connection at native layer,
070:             * <code>-1<code> if connection is not open.
071:             */
072:            private int handle = -1;
073:
074:            // IMPL_NOTE make it back private when moving emulation
075:            // below porting layer completed
076:            /**
077:             * Temporary stores peer's native handle for accepted connection.
078:             * Used by <code>doAccept</code> method.
079:             */
080:            int peerHandle = -1;
081:
082:            /**
083:             * Temporary stores remote device address for accepted connection.
084:             */
085:            byte[] peerAddress = new byte[6];
086:
087:            /** Indicates whether notifier is listening for incoming connections. */
088:            private boolean isListenMode = false;
089:
090:            /**
091:             * Negotiated ReceiveMTU and TransmitMTU.
092:             * 16 high bits is ReceiveMTU, 16 low bits is TransmitMTU.
093:             *
094:             * This packeted value is returned by accept0 method and copied to
095:             * L2CAPConnectionImpl by it's constructor.
096:             */
097:            int mtus = (((-1) << 16) & 0xFFFF0000) & ((-1) & 0xFFFF);
098:
099:            /** Keeps PSM value for service record validation. */
100:            private DataElement PSM;
101:
102:            /** Keeps L2CAP UUID for service record validation. */
103:            static final DataElement L2CAP_UUID = new DataElement(
104:                    DataElement.UUID, new UUID(0x0100));
105:
106:            /** Bluetooth PushRegistry handle, used in native methods only. */
107:            private int pushHandle = 0;
108:
109:            /**
110:             * Creates instance of <code>L2CAPNotifierImpl</code>.
111:             *
112:             * @param url <code>BluetoothUrl</code> that represents server
113:             *        connection string to create notifier for
114:             * @param mode I/O access mode
115:             * @throws IOException if an I/O error occurs
116:             */
117:            L2CAPNotifierImpl(BluetoothUrl url, int mode) throws IOException {
118:                super (url, mode);
119:
120:                MIDletSuite suite = MIDletStateHandler.getMidletStateHandler()
121:                        .getMIDletSuite();
122:
123:                int suiteId = (suite != null) ? suite.getID()
124:                        : MIDletSuite.UNUSED_SUITE_ID;
125:                String connUrl = "btl2cap:" + url.caseSensitiveUrl;
126:
127:                // check whether suiteId is valid.
128:                // for example, it can be null if L2CAPNotifier is created as SDP server
129:                // in PushRegistry inbound connection watcher thread that can be started
130:                // before MIDlet start.
131:                if (suiteId != MIDletSuite.UNUSED_SUITE_ID
132:                        && pushCheckout(connUrl, suiteId)) {
133:                    serviceRec = BluetoothPush.getServiceRecord(this , connUrl);
134:                    checkServiceRecord();
135:                } else {
136:                    serviceRec = createServiceRecord(this , url, doCreate(url));
137:                }
138:            }
139:
140:            /**
141:             * Checks out (takes ownership of) an active server connection maintained
142:             * by push subsystem.
143:             *
144:             * @param url URL used during registration of the push entry
145:             * @param suiteId suite id
146:             * @return true if the operation succeeds, false otherwise
147:             */
148:            private native boolean pushCheckout(String url, int suiteId);
149:
150:            /**
151:             * Creates an empty service record for the given URL and PSM value.
152:             *
153:             * @param notifier L2CAP notifier object to be associated with the record
154:             * @param url URL from which a new record is constructed
155:             * @param psm PSM value assigned to the notifier
156:             * @return a new service record instance
157:             */
158:            public static ServiceRecordImpl createServiceRecord(
159:                    L2CAPNotifierImpl notifier, BluetoothUrl url, int psm) {
160:                DataElement serviceList = new DataElement(DataElement.DATSEQ);
161:                serviceList.addElement(new DataElement(DataElement.UUID,
162:                        new UUID(url.uuid, false)));
163:                DataElement protocolList = new DataElement(DataElement.DATSEQ);
164:                DataElement protocol = new DataElement(DataElement.DATSEQ);
165:                protocol.addElement(L2CAP_UUID);
166:                if (notifier != null) {
167:                    notifier.PSM = new DataElement(DataElement.U_INT_2, psm);
168:                    protocol.addElement(notifier.PSM);
169:                } else {
170:                    protocol.addElement(new DataElement(DataElement.U_INT_2,
171:                            psm));
172:                }
173:                protocolList.addElement(protocol);
174:                int[] attrIDs;
175:                DataElement[] attrVals;
176:                if (url.name != null) {
177:                    DataElement name = new DataElement(DataElement.STRING,
178:                            url.name);
179:                    attrIDs = new int[] {
180:                            ServiceRecordImpl.SERVICE_CLASS_ATTR_ID,
181:                            ServiceRecordImpl.PROTOCOL_DESCRIPTOR_LIST,
182:                            ServiceRecordImpl.NAME_ATTR_ID };
183:                    attrVals = new DataElement[] { serviceList, protocolList,
184:                            name };
185:                } else {
186:                    attrIDs = new int[] {
187:                            ServiceRecordImpl.SERVICE_CLASS_ATTR_ID,
188:                            ServiceRecordImpl.PROTOCOL_DESCRIPTOR_LIST };
189:                    attrVals = new DataElement[] { serviceList, protocolList };
190:                }
191:                return new ServiceRecordImpl(notifier, attrIDs, attrVals);
192:            }
193:
194:            /**
195:             * Creates an empty service record for the given URL.
196:             *
197:             * @param url URL from which a new record is constructed
198:             * @return a new service record instance
199:             */
200:            public static ServiceRecordImpl createServiceRecord(String url) {
201:                return createServiceRecord(null, new BluetoothUrl(url), 0);
202:            }
203:
204:            /**
205:             * Ensures that the service record is valid.
206:             *
207:             * @throws ServiceRegistrationException if the structure of the
208:             *         <code>srvRecord</code> is  missing any mandatory service
209:             *         attributes, or if an attempt has been made to change any of the
210:             *         values described as fixed
211:             */
212:            protected void checkServiceRecord()
213:                    throws ServiceRegistrationException {
214:                synchronized (serviceRec) {
215:                    // check if the ServiceClassIDList is not missing
216:                    if (serviceRec
217:                            .getAttributeValue(ServiceRecordImpl.SERVICE_CLASS_ATTR_ID) == null) {
218:                        throw new ServiceRegistrationException(
219:                                "ServiceClassIDList is missing.");
220:                    }
221:                    // check the ProtocolList is not missed
222:                    DataElement protocolList = serviceRec
223:                            .getAttributeValue(ServiceRecordImpl.PROTOCOL_DESCRIPTOR_LIST);
224:                    if (protocolList == null) {
225:                        throw new ServiceRegistrationException(
226:                                "ProtocolDescriptorList is missing.");
227:                    }
228:                    Enumeration protocolListEnum = (Enumeration) protocolList
229:                            .getValue();
230:                    while (protocolListEnum.hasMoreElements()) {
231:                        Enumeration protocolEnum = (Enumeration) ((DataElement) protocolListEnum
232:                                .nextElement()).getValue();
233:                        // check that the L2CAP UUID is not missing, check the PSM
234:                        // is not missing and the value has not changed
235:                        if (protocolEnum.hasMoreElements()) {
236:                            if (compareDataElements((DataElement) protocolEnum
237:                                    .nextElement(), L2CAP_UUID)) {
238:                                if (!protocolEnum.hasMoreElements()) {
239:                                    throw new ServiceRegistrationException(
240:                                            "PSM value is missing.");
241:                                }
242:                                if (PSM == null) {
243:                                    PSM = new DataElement(DataElement.U_INT_2,
244:                                            ((DataElement) protocolEnum
245:                                                    .nextElement()).getLong());
246:                                    return;
247:                                }
248:                                if (!compareDataElements(
249:                                        (DataElement) protocolEnum
250:                                                .nextElement(), PSM)) {
251:                                    throw new ServiceRegistrationException(
252:                                            "PSM value has changed.");
253:                                }
254:                                return;
255:                            }
256:                        }
257:                    }
258:                }
259:                throw new ServiceRegistrationException("L2CAP UUID is missing.");
260:            }
261:
262:            /**
263:             * Ensures that this notifier can accept connections.
264:             *
265:             * @throws IOException if notifier is closed, device is not
266:             *         in connectable mode, or service record is invalid
267:             */
268:            private void ensureConnectable() throws IOException {
269:                if (isClosed) {
270:                    throw new BluetoothConnectionException(
271:                            BluetoothConnectionException.FAILED_NOINFO,
272:                            "Notifier is closed.");
273:                }
274:                if (!BCC.getInstance().isConnectable()) {
275:                    throw new BluetoothStateException(
276:                            "The device is not connectable.");
277:                }
278:                checkServiceRecord();
279:            }
280:
281:            /**
282:             * Accepts connections blocking until incoming client connection appears. 
283:             *
284:             * @return connection to a client just accepted. 
285:             *
286:             * @throws IOException if notifier is closed or device is not
287:             * in connectable mode.
288:             */
289:            public L2CAPConnection acceptAndOpen() throws IOException {
290:                ensureConnectable();
291:
292:                // switch on listen mode if it has not been done yet
293:                doListen();
294:
295:                // adds the service record if it is not yet in SDDB
296:                SDDB.getInstance().updateServiceRecord(serviceRec);
297:
298:                L2CAPConnection client;
299:                do {
300:                    ensureConnectable();
301:
302:                    // accept incoming connections if any
303:                    client = doAccept();
304:                } while (client == null);
305:
306:                return client;
307:            }
308:
309:            /**
310:             * Closes this notifier making corresponding service record inaccessible.
311:             * updates the information on the communication server.
312:             *
313:             * @exception IOException if an error occured lower in Bluetooth stack.
314:             */
315:            public void close() throws IOException {
316:                if (isClosed) {
317:                    return;
318:                }
319:                isClosed = true;
320:
321:                SDDB.getInstance().removeServiceRecord(serviceRec);
322:
323:                doClose();
324:            }
325:
326:            /**
327:             * Force listen mode by calling underlying stack methods.
328:             *
329:             * @throws IOException if an error occured
330:             */
331:            private void doListen() throws IOException {
332:                // force listening if it had not been done yet
333:                if (!isListenMode) {
334:                    listen0();
335:
336:                    isListenMode = true;
337:                }
338:            }
339:
340:            /**
341:             * Force Bluetooth stack to listen for incoming client connections.
342:             *
343:             * Note: the method gets native connection handle directly from
344:             * <code>handle<code> field of <code>L2CAPNotifierImpl</code> object.
345:             *
346:             * @throws IOException if an I/O error occurs
347:             */
348:            private native void listen0() throws IOException;
349:
350:            /**
351:             * Advertises acception by calling underlying stack methods.
352:             *
353:             * @return L2CAPConnectionImpl instance to work with accepted client
354:             */
355:            private L2CAPConnection doAccept() throws IOException {
356:                if (!isListenMode) {
357:                    throw new BluetoothStateException(
358:                            "Device is not in listen mode");
359:                }
360:
361:                /*
362:                 * Note: native handle is set to peerHandleID field directly by accept0
363:                 * method and retrieved by L2CAPConnectionImpl constructor.
364:                 */
365:                mtus = accept0();
366:
367:                return new L2CAPConnectionImpl(url, mode, this );
368:            }
369:
370:            /**
371:             * Accepts incoming client connection request.
372:             *
373:             * Note: the method gets native connection handle directly from
374:             * <code>handle<code> field of <code>L2CAPNotifierImpl</code> object.
375:             *
376:             * Note: new native connection handle to work with accepted incoming
377:             * client connection is setted directly to <code>handle</code> field of
378:             * appropriate <code>L2CAPConnectionImpl</code> object.
379:             *
380:             * @return   Negotiated ReceiveMTU and TransmitMTU.
381:             *                 16 high bits is ReceiveMTU, 16 low bits is TransmitMTU.
382:             * @throws IOException if an I/O error occurs
383:             */
384:            private native int accept0() throws IOException;
385:
386:            /**
387:             * Closes this notifier at native layer.
388:             */
389:            private void doClose() throws IOException {
390:                close0();
391:            }
392:
393:            /**
394:             * Closes this server connection.
395:             * Releases all native resources (such as sockets) owned by this notifier.
396:             *
397:             * Note: the method gets native connection handle directly from
398:             * <code>handle<code> field of <code>L2CAPNotifierImpl</code> object.
399:             *
400:             * @throws IOException IOException if an I/O error occurs
401:             */
402:            private native void close0() throws IOException;
403:
404:            /**
405:             * Creates an instanse of server connection at native layer.
406:             *
407:             * @param url <code>BluetoothUrl</code> that represents server
408:             *        connection string to create notifier for
409:             * @return selected psm value to listen for incoming connections on
410:             */
411:            private int doCreate(BluetoothUrl url) throws IOException {
412:                return create0(url.receiveMTU, url.transmitMTU,
413:                        url.authenticate, url.authorize, url.encrypt,
414:                        url.master);
415:            }
416:
417:            /**
418:             * Creates a server connection.
419:             *
420:             * Note: the method sets native connection handle directly to
421:             * <code>handle<code> field of <code>L2CAPNotifierImpl</code> object.
422:             *
423:             * @param imtu receive MTU or <code>-1</code> if not specified
424:             * @param omtu transmit MTU or <code>-1</code> if not specified
425:             * @param auth   <code>true</code> if authication is required
426:             * @param authz  <code>true</code> if authorization is required
427:             * @param enc    <code>true</code> indicates
428:             *                what connection must be encrypted
429:             * @param master <code>true</code> if client requires to be
430:             *               a connection's master
431:             * @return selected psm value to listen for incoming connections on
432:             * @throws IOException IOException if an I/O error occurs
433:             */
434:            private native int create0(int imtu, int omtu, boolean auth,
435:                    boolean authz, boolean enc, boolean master)
436:                    throws IOException;
437:
438:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.