/*
*
*
* 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 java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.bluetooth.DataElement;
import javax.bluetooth.L2CAPConnection;
import javax.bluetooth.UUID;
public class SDPClientConnection {
/* L2CAP URL starting string. */
private static final String SDP_L2CAP_URL_BEGIN = "//";
/* L2CAP URL trailing string. */
private static final String SDP_L2CAP_URL_END = ":0001";
private static Hashtable connections = new Hashtable();
/* Bluetooth address of the server. */
private String address;
/*
* Reference counter keeps the number of SDP connections which
* use this transport. When this value reaches zero, the L2CAP
* connection is closed and the transport is removed from the global
* SDPClient.transportStorage hashtable.
*/
private int refCount = 0;
/* The L2CAP (logical link) connection. */
private L2CAPConnection connection;
/*
* Object that performs reading from and writing to L2CAP connection.
*/
private DataL2CAPReaderWriter rw;
/* Lock for synchronizing reading from connection. */
public Object readLock = new Object();
/* Lock for synchronizing writing to connection. */
public Object writeLock = new Object();
/*
* Constructs <code>SDPClientConnection</code> instance that reflects transport
* connections to the specified server.
*
* @param bluetoothAddress bluetooth address of the server
*/
protected SDPClientConnection(String bluetoothAddress) throws IOException {
address = bluetoothAddress;
connection = (L2CAPConnection)SDP.getL2CAPConnection(
SDP_L2CAP_URL_BEGIN + bluetoothAddress + SDP_L2CAP_URL_END);
rw = new DataL2CAPReaderWriter(connection);
}
public static SDPClientConnection getSDPClientConnection( String bluetoothAddress ) throws IOException {
SDPClientConnection result = null;
synchronized (connections) {
result = (SDPClientConnection)connections.get(bluetoothAddress);
if( result == null ) {
result = new SDPClientConnection( bluetoothAddress );
connections.put(bluetoothAddress, result);
result.addRef();
}
}
return result;
}
public static void closeAll() {
synchronized (connections) {
Enumeration addrs = connections.keys();
while ( addrs.hasMoreElements() ) {
String addr = (String)addrs.nextElement();
if (addr != null) {
SDPClientConnection conn = (SDPClientConnection)connections.get(addr);
if (conn != null) {
conn.release();
}
}
}
connections.clear();
}
}
/*
* Increases reference counter. This object and the underlying L2CAP
* connection will live while the counter is positive.
*/
protected synchronized void addRef() {
refCount++;
}
/*
* Decreases reference counter. If the counter becomes equal to zero,
* L2CAP connection is closed and the transport is removed from the
* global SDPClient.transportStorage hashtable.
*/
public synchronized void release() {
refCount--;
if (refCount <= 0) {
try {
connection.close();
} catch (IOException e) {
// just ignore it, we're done with this object anyway
}
synchronized (connections) {
connections.remove(this.address);
}
}
}
public DataL2CAPReaderWriter getReaderWriter() {
return rw;
}
public L2CAPConnection getL2CAPConnection() {
return connection;
}
}