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;
028:
029: import com.sun.cldc.io.ConnectionBaseInterface;
030: import java.io.IOException;
031: import java.io.InterruptedIOException;
032: import javax.microedition.io.Connection;
033: import javax.microedition.io.Connector;
034: import javax.bluetooth.L2CAPConnection;
035: import javax.bluetooth.BluetoothConnectionException;
036:
037: import com.sun.midp.io.BluetoothUrl;
038: import com.sun.midp.midlet.MIDletStateHandler;
039: import com.sun.midp.midlet.MIDletSuite;
040: import com.sun.midp.security.Permissions;
041: import com.sun.midp.security.SecurityToken;
042: import com.sun.midp.main.Configuration;
043:
044: /**
045: * Provides abstract base for bluetooth protocols.
046: */
047: public abstract class BluetoothProtocol implements
048: ConnectionBaseInterface {
049: /** Particular protocol type. */
050: private int protocol;
051:
052: /** Keeps set of fields specified by URL. */
053: protected BluetoothUrl url = null;
054:
055: /**
056: * Constructs an instance.
057: * @param protocol specifies particular protocol, must be one of <code>
058: * BluetoothUrl.L2CAP, BluetoothUrl.RFCOMM, BluetoothUrl.OBEX </code>
059: */
060: protected BluetoothProtocol(int protocol) {
061: this .protocol = protocol;
062: }
063:
064: /**
065: * Implements the <code>openPrim()</code> of
066: * <code>ConnectionBaseInerface</code> and allows to get
067: * connection by means of <code>Connector.open()</code>
068: * call.
069: *
070: * @param name the target for the connection
071: * @param mode I/O access mode
072: * @param timeouts ignored
073: *
074: * @return L2CAP connection open.
075: * @exception IOException if opening connection fails.
076: */
077: public Connection openPrim(String name, int mode, boolean timeouts)
078: throws IOException {
079: return openPrim(null, name, mode, timeouts);
080: }
081:
082: /**
083: * Checks permissions and opens requested connection.
084: *
085: * @param token security token of the calling class
086: * @param name the URL without protocol name and colon.
087: * @param mode connector.READ_WRITE or connector.READ or connector.WRITE
088: * @param timeouts ignored.
089: *
090: * @return a notifier in case of server connection string, open connection
091: * in case of client one.
092: *
093: * @exception IOException if opening connection fails.
094: */
095: public Connection openPrim(Object token, String name, int mode,
096: boolean timeouts) throws IOException {
097:
098: return openPrimImpl(token, new BluetoothUrl(protocol, name),
099: mode);
100: }
101:
102: /**
103: * Checks permissions and opens requested connection.
104: *
105: * @param token security token passed by calling class
106: * @param url <code>BluetoothUrl</code> instance that defines required
107: * connection stringname the URL without protocol name and colon
108: * @param mode connector.READ_WRITE or connector.READ or connector.WRITE
109: *
110: * @return a notifier in case of server connection string, open connection
111: * in case of client one.
112: *
113: * @exception IOException if opening connection fails.
114: */
115: protected Connection openPrimImpl(Object token, BluetoothUrl url,
116: int mode) throws IOException {
117: checkOpenMode(mode);
118: checkUrl(url);
119: this .url = url;
120:
121: return url.isServer ? serverConnection((SecurityToken) token,
122: mode) : clientConnection((SecurityToken) token, mode);
123: }
124:
125: /**
126: * Ensures open mode requested is READ_WRITE or READ or WRITE
127: *
128: * @param mode open mode to be checked
129: * @exception IllegalArgumentException if mode given is invalid
130: *
131: * IMPL_NOTE check if other modes are needed
132: */
133: private void checkOpenMode(int mode)
134: throws IllegalArgumentException {
135: if (mode != Connector.READ_WRITE && mode != Connector.READ
136: && mode != Connector.WRITE) {
137: throw new IllegalArgumentException("Unsupported mode: "
138: + mode);
139: }
140: }
141:
142: /**
143: * Ensures URL parameters have valid values. This implementation contains
144: * common checks and is called from subclasses before making protocol
145: * specific ones.
146: *
147: * @param url URL to check
148: * @exception IllegalArgumentException if invalid url parameters found
149: * @exception BluetoothConnectionException if url parameters are not
150: * acceptable due to Bluetooth stack limitations
151: */
152: protected void checkUrl(BluetoothUrl url)
153: throws IllegalArgumentException,
154: BluetoothConnectionException {
155:
156: /*
157: * IMPL_NOTE: revisit this code if TCK changes.
158: * IllegalArgumentException seems to be right one here, not
159: * BluetoothConnectionException. However TCK expects the latter
160: * in several cases. Once IllegalArgumentException becomes
161: * preferable this check can be placed to BluetoothUrl.
162: * Questionable TCK tests:
163: * bluetooth.Connector.Security.openClientTests,
164: * bluetooth.Connector.Security.openServerTests
165: */
166: if ((url.encrypt || url.authorize) && !url.authenticate) {
167: throw new BluetoothConnectionException(
168: BluetoothConnectionException.UNACCEPTABLE_PARAMS,
169: "Invalid Authenticate parameter");
170: }
171: }
172:
173: /**
174: * Ensures that permissions are proper and creates client side connection.
175: * @param token security token if passed by caller, or <code>null</code>
176: * client side connection.
177: * @param mode I/O access mode
178: * @return connection created, defined in subclasses
179: * @exception IOException if opening connection fails.
180: */
181: protected abstract Connection clientConnection(SecurityToken token,
182: int mode) throws IOException;
183:
184: /**
185: * Ensures that permissions are proper and creates required notifier at
186: * server side.
187: * @param token security token if passed by caller, or <code>null</code>
188: * @param mode I/O access mode
189: * @return server notifier, defined in subclasses
190: * @exception IOException if opening connection fails.
191: */
192: protected abstract Connection serverConnection(SecurityToken token,
193: int mode) throws IOException;
194:
195: /**
196: * Makes sure caller has the com.sun.midp permission set to "allowed".
197: *
198: * @param token security token of the calling class, may be null
199: * @param permission requested permission ID
200: *
201: * @exception IOInterruptedException if another thread interrupts the
202: * calling thread while this method is waiting to preempt the
203: * display.
204: */
205: protected void checkForPermission(SecurityToken token,
206: int permission) throws InterruptedIOException {
207:
208: if (token != null) {
209: token.checkIfPermissionAllowed(permission);
210: } else {
211:
212: MIDletSuite midletSuite = MIDletStateHandler
213: .getMidletStateHandler().getMIDletSuite();
214:
215: if (midletSuite != null) {
216: try {
217: midletSuite.checkForPermission(permission, url
218: .getResourceName());
219: } catch (InterruptedException ie) {
220: throw new InterruptedIOException(
221: "Interrupted while trying to ask the user permission");
222: }
223: }
224: }
225: }
226: }
|