/* * * * 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"); } } }