/*
*
*
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package com.sun.jsr082.bluetooth;
import com.sun.j2me.io.ConnectionBaseInterface;
import com.sun.j2me.security.BluetoothPermission;
import java.io.IOException;
import java.io.InterruptedIOException;
import javax.microedition.io.Connection;
import javax.microedition.io.Connector;
import javax.bluetooth.L2CAPConnection;
import javax.bluetooth.BluetoothConnectionException;
import com.sun.j2me.app.AppPackage;
import com.sun.j2me.main.Configuration;
/*
* Provides abstract base for bluetooth protocols.
*/
public abstract class BluetoothProtocol implements ConnectionBaseInterface {
/* Particular protocol type. */
private int protocol;
/* Keeps set of fields specified by URL. */
protected BluetoothUrl url = null;
/*
* Constructs an instance.
* @param protocol specifies particular protocol, must be one of <code>
* BluetoothUrl.L2CAP, BluetoothUrl.RFCOMM, BluetoothUrl.OBEX </code>
*/
protected BluetoothProtocol(int protocol) {
this.protocol = protocol;
}
/*
* Implements the <code>openPrim()</code> of
* <code>ConnectionBaseInerface</code> and allows to get
* connection by means of <code>Connector.open()</code>
* call.
*
* @param name the target for the connection
* @param mode I/O access mode
* @param timeouts ignored
*
* @return L2CAP connection open.
* @exception IOException if opening connection fails.
*/
public Connection openPrim(String name, int mode, boolean timeouts)
throws IOException {
return openPrimImpl(new BluetoothUrl(protocol, name), mode);
}
/*
* Checks permissions and opens requested connection.
*
* @param token security token passed by calling class
* @param url <code>BluetoothUrl</code> instance that defines required
* connection stringname the URL without protocol name and colon
* @param mode connector.READ_WRITE or connector.READ or connector.WRITE
*
* @return a notifier in case of server connection string, open connection
* in case of client one.
*
* @exception IOException if opening connection fails.
*/
protected Connection openPrimImpl(BluetoothUrl url, int mode)
throws IOException {
checkOpenMode(mode);
checkUrl(url);
this.url = url;
return url.isServer?
serverConnection(mode):
clientConnection(mode);
}
/*
* Ensures open mode requested is READ_WRITE or READ or WRITE
*
* @param mode open mode to be checked
* @exception IllegalArgumentException if mode given is invalid
*
* IMPL_NOTE check if other modes are needed
*/
private void checkOpenMode(int mode) throws IllegalArgumentException {
if (mode != Connector.READ_WRITE &&
mode != Connector.READ &&
mode != Connector.WRITE) {
throw new IllegalArgumentException("Unsupported mode: " + mode);
}
}
/*
* Ensures URL parameters have valid values. This implementation contains
* common checks and is called from subclasses before making protocol
* specific ones.
*
* @param url URL to check
* @exception IllegalArgumentException if invalid url parameters found
* @exception BluetoothConnectionException if url parameters are not
* acceptable due to Bluetooth stack limitations
*/
protected void checkUrl(BluetoothUrl url)
throws IllegalArgumentException, BluetoothConnectionException {
/*
* IMPL_NOTE: revisit this code if TCK changes.
* IllegalArgumentException seems to be right one here, not
* BluetoothConnectionException. However TCK expects the latter
* in several cases. Once IllegalArgumentException becomes
* preferable this check can be placed to BluetoothUrl.
* Questionable TCK tests:
* bluetooth.Connector.Security.openClientTests,
* bluetooth.Connector.Security.openServerTests
*/
if ((url.encrypt || url.authorize) && !url.authenticate) {
throw new BluetoothConnectionException(
BluetoothConnectionException.UNACCEPTABLE_PARAMS,
"Invalid Authenticate parameter");
}
}
/*
* Ensures that permissions are proper and creates client side connection.
* @param token security token if passed by caller, or <code>null</code>
* client side connection.
* @param mode I/O access mode
* @return connection created, defined in subclasses
* @exception IOException if opening connection fails.
*/
protected abstract Connection clientConnection(int mode)
throws IOException;
/*
* Ensures that permissions are proper and creates required notifier at
* server side.
* @param token security token if passed by caller, or <code>null</code>
* @param mode I/O access mode
* @return server notifier, defined in subclasses
* @exception IOException if opening connection fails.
*/
protected abstract Connection serverConnection(int mode)
throws IOException;
/*
* Makes sure caller has the com.sun.midp permission set to "allowed".
*
* @param token security token of the calling class, may be null
* @param permission requested permission ID
*
* @exception IOInterruptedException if another thread interrupts the
* calling thread while this method is waiting to preempt the
* display.
*/
protected void checkForPermission(BluetoothPermission permission)
throws InterruptedIOException {
AppPackage app = AppPackage.getInstance();
try {
app.checkForPermission(new BluetoothPermission(
permission.getName(), url.getResourceName()));
} catch (InterruptedException ie) {
throw new InterruptedIOException(
"Interrupted while trying to ask the user permission");
}
}
}