📄 backgammonbtconnection.java
字号:
// Copyright (c) 2005 Sony Ericsson Mobile Communications AB
//
// This software is provided "AS IS," without a warranty of any kind.
// ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
// INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
//
// THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se)
package bluegammon.io;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import javax.bluetooth.RemoteDevice;
import javax.microedition.io.StreamConnection;
/**
* Implementation of the interface <code>BackgammonConnection</code> for
* bluetooth bearer.
* @author Peter Andersson
*/
public class BackgammonBTConnection implements BackgammonConnection
{
/** The service number of the game */
protected static final String SERVICE_NBR = "1a88760401bac57a8806abc1ca900010";
/** Bluetooth facade instance */
protected static final BluetoothFacade BTFACADE = new BluetoothFacade();
/** Flag indicating if server is actually awaiting a client */
protected static boolean m_awaitingClient = false;
/** Flag indicating if server denies connection once it gets a client */
protected static boolean m_fakeServerClosed = false;
/** Global server/client connection closed flag */
protected static boolean m_closed = false;
/** The server/client StreamConnection */
protected volatile static StreamConnection m_connection;
/** The server/client input stream */
protected volatile static DataInputStream m_input;
/** The server/client output stream */
protected volatile static DataOutputStream m_output;
/**
* <p>
* Waits for a client, the method blocks until client arrives
* or IOException is thrown. The BT server cannot be interrupted -
* call <code>pretendServerClose</code> to emulate this. Any client
* that connects after a call to <code>pretendServerClose</code> will
* immediately be shutdown.
* </p><p>
* Disable this state by calling <code>waitForClient</code> again, which
* will make the client accepted when it connects. Any call to
* <code>waitForClient</code> during an already active client wait will
* just set flags and return directly, as there must be another thread still
* waiting a client generated by the first call to <code>waitForClient</code>.
* <p>
*/
public void waitForClient() throws IOException
{
synchronized(this)
{
if (m_awaitingClient && m_fakeServerClosed)
{
// Some other thread is still awaiting client,
// just set flags and return from this call
m_fakeServerClosed = false;
return;
}
m_awaitingClient = true;
m_fakeServerClosed = false;
}
try
{
// Start listening for client
m_closed = false;
m_connection = BTFACADE.waitForClient(SERVICE_NBR);
m_input = m_connection.openDataInputStream();
m_output = m_connection.openDataOutputStream();
}
catch (IOException ioe)
{
synchronized(this)
{
if (!m_closed && !m_fakeServerClosed)
{
// Not interested in exception if we're closed
throw ioe;
}
}
}
finally
{
synchronized(this)
{
m_awaitingClient = false;
// Close connections if some thread closed while we
// were waiting for client
if (m_fakeServerClosed)
{
close();
}
}
}
}
public boolean connectClient(Object remote) throws IOException
{
synchronized(this)
{
m_closed = false;
}
boolean res = false;
try
{
m_connection = BTFACADE.connect(SERVICE_NBR, (RemoteDevice) remote);
if (m_connection != null)
{
m_input = m_connection.openDataInputStream();
m_output = m_connection.openDataOutputStream();
res = true;
}
}
catch (IOException ioe)
{
synchronized(this)
{
if (!m_closed)
{
// Not interested in exception if we're closed
throw ioe;
}
}
}
finally
{
synchronized(this)
{
if (m_closed)
{
close();
}
}
}
return res;
}
public StreamConnection getConnection() throws IOException
{
return m_connection;
}
public DataInputStream getInput()
{
return m_input;
}
public DataOutputStream getOutput()
{
return m_output;
}
/**
* The BT server cannot be interrupted, so lets just
* pretend we close the server. If the server gets a client while
* in pretended closed mode, or when it time out,
* we close connections for real.
*/
public synchronized void pretendServerClose()
{
m_fakeServerClosed = true;
}
public synchronized boolean isAwaitingClient()
{
return m_awaitingClient;
}
public synchronized void close() throws IOException
{
IOException ioe = null;
m_closed = true;
// Close connection
if (m_connection != null)
{
try
{
m_connection.close();
m_connection = null;
}
catch (IOException e)
{
ioe = e;
}
}
// Close input stream
if (m_input != null)
{
try
{
m_input.close();
m_input = null;
}
catch (IOException e)
{
ioe = e;
}
}
// Close output stream
if (m_output != null)
{
try
{
m_output.close();
m_output = null;
}
catch (IOException e)
{
ioe = e;
}
}
// Close server
try
{
BTFACADE.closeServer(SERVICE_NBR);
m_awaitingClient = false;
}
catch (IOException e)
{
ioe = e;
}
// Throw exception if we got any
if (ioe != null)
{
throw ioe;
}
}
public synchronized boolean isClosed()
{
return m_closed || m_fakeServerClosed;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -