/* * 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; public class SDPClientReceiver implements Runnable { private static Hashtable receivers = new Hashtable(); private static int instanceCount = 0; private JavaSDPClient client = null; private static final boolean DEBUG= false; /* * Identifies if receiving thread is running (false) or not (true). */ private Thread receiverThread = null; protected SDPClientReceiver(JavaSDPClient client) { this.client = client; receiverThread = new Thread(this); receiverThread.start(); if (DEBUG) { System.out.println("# Receiver internal thread started"); } } public static synchronized void start(JavaSDPClient client) { SDPClientReceiver receiver = (SDPClientReceiver)receivers.get(client); if (receiver == null) { receiver = new SDPClientReceiver(client); receivers.put(client, receiver); instanceCount = 1; } else { instanceCount++; } if (DEBUG) { System.out.println("# Receiver[" + instanceCount + "] started"); } } public static synchronized void stop(JavaSDPClient client) { SDPClientReceiver receiver = (SDPClientReceiver)receivers.get(client); if (receiver == null) { return; } if (DEBUG) { System.out.println("# Receiver[" + instanceCount + "] stopped"); } if (--instanceCount > 0) { return; } else { receiver.finish(client.getConnection()); receivers.remove(client); } } /* Cancels receiving responses. */ public static synchronized void cancel() { Enumeration clientRefs = receivers.keys(); while( clientRefs.hasMoreElements() ) { Object ref = clientRefs.nextElement(); if (ref != null) { SDPClientReceiver rvr = (SDPClientReceiver)receivers.get(ref); Thread tmp = rvr.receiverThread; rvr.finish(((JavaSDPClient)ref).getConnection()); try { tmp.join(); } catch (InterruptedException ie) { } if (DEBUG) { System.out.println("# Receiver internal thread stopped"); } } } receivers.clear(); if (DEBUG) { System.out.println("# Receiver[all] canceled"); } } protected synchronized void finish(SDPClientConnection conn) { if (receiverThread != null) { Thread tmp = receiverThread; receiverThread = null; if (conn != null) { conn.release(); if (DEBUG) { System.out.println("# Receiver: Connection released"); } } } } /* * The <code>run()</code> method. * * @see java.lang.Runnable */ public void run() { Thread current = Thread.currentThread(); while (client != null && client.getConnection() != null && current == receiverThread ) { try { byte pduID = client.getConnection().getReaderWriter().readByte(); short transID = client.getConnection().getReaderWriter().readShort(); short length = client.getConnection().getReaderWriter().readShort(); SDPClientTransaction trans = SDPClientTransaction.findTransaction(transID); if (trans != null) { if (DEBUG) { System.out.println( "# Receiver processResponse:" + trans.getID() ); } trans.processResponse(pduID, length); } else { if (DEBUG) { System.out.println("#Receiver transaction: " + transID + " not found"); } // transaction we are not aware of; skip this pdu client.getConnection().getReaderWriter().readBytes(length); if (current == receiverThread) { throw new IOException("Invalid transaction id: " + transID); } } } catch (IOException ioe) { if (current == receiverThread) { SDPClientTransaction.cancelAll(SDPResponseListener.IO_ERROR); } } } receiverThread = null; if (DEBUG) { System.out.println( "# Receiver internal thread exit" ); } } }