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