📄 netlayer.java
字号:
endpt = new EndPoint( this, rdev, c);
Thread t1 = new Thread( endpt.sender );
t1.start();
Thread t2 = new Thread( endpt.reader );
t2.start();
// add this EndPoint to the active list
endPoints.addElement( endpt );
log("a new active EndPoint is established. name=" + endpt.remoteName);
}
}
catch (IOException e) {
e.printStackTrace();
log(e.getClass().getName()+" "+e.getMessage());
// if any exception happen, we assume this connection is
// failed and close it. closing the connection will cause
// the reader and sender thread to exit (because they will got
// exception as well).
if (c != null)
try {
c.close();
}
catch (IOException e2) {
// ignore
}
}
finally {
// nothing to do here
}
} // while !done
} // end run()
public static void log( String s)
{
System.out.println("NetLayer: "+s);
// "N" means NetLayer
if ( ChatMain.isDebug )
ChatMain.instance.gui_log( "N", s );
}
/**
* Internal discovery listener class for handling device & service discovery events.
* @author Ben Hui
* @version 1.0
*/
class Listener implements DiscoveryListener
{
/**
* A device is discovered.
* Create a EndPoint for the device discovered and put it on the pending list.
* A service search will happen when all the qualifying devices are discovered.
*
* @param remoteDevice
* @param deviceClass
*/
public void deviceDiscovered(RemoteDevice remoteDevice,
DeviceClass deviceClass)
{
try {
log("invoke deviceDiscovered name=" + remoteDevice.getFriendlyName(false));
}
catch (IOException ex) {
}
// only device of SERVICE_OBJECT_TRANSFER will be considered as candidate device
// because in our BlueChat service, we explicitly set the service class to
// SERVICE_OBJECT_TRANSFER. see the run() method
// if ( (deviceClass.getServiceClasses() & SERVICE_OBJECT_TRANSFER) != 0 )
// {
try
{
// create a inactive EndPoint and put it on the pending list
EndPoint endpt = new EndPoint(NetLayer.this, remoteDevice, null);
pendingEndPoints.addElement( endpt );
} catch (Exception e)
{
e.printStackTrace();
log(e.getClass().getName()+" "+e.getMessage());
}
// } else
// {
// log("found device that is not Object Transfer Service, ignore this device...");
// }
}
/**
* device discovery completed.
* After device inquery completed, we start to search for BlueChat services.
* We loop through all the pending EndPoints and request agent.searchServices
* on each of the remote device.
* @param transId
*/
public void inquiryCompleted(int transId)
{
log( "invoke inqueryCompleted" );
// wait 100ms and start doing service discovery
// the choice of 100ms is really just a guess
timer.schedule( new DoServiceDiscovery(), 100 );
}
/**
* a service is discovered from a remote device.
* when a BlueChat service is discovered, we establish a connection to
* this service. This signal joining the existing virtual chat room.
* @param transId
* @param svcRec
*/
public void servicesDiscovered(int transId, ServiceRecord[] svcRec)
{
log( "invoke servicesDiscovered:"+transId+","+svcRec.length);
try {
for ( int i=0; i< svcRec.length; i++ )
{
Util.printServiceRecord( svcRec[i] );
EndPoint endpt = findEndPointByTransId( transId );
serviceRecordToEndPoint.put( svcRec[i], endpt );
}
}
catch (Exception e) {
e.printStackTrace();
log(e.getClass().getName());
log(e.getMessage());
}
}
/**
* service discovery is completed.
* @param int0
* @param int1
*/
public void serviceSearchCompleted(int transID, int respCode)
{
log("invoke serviceSearchCompleted: "+transID);
// print response code
if ( respCode == SERVICE_SEARCH_COMPLETED )
log("SERVICE_SEARCH_COMPLETED");
else if ( respCode == SERVICE_SEARCH_TERMINATED )
log("SERVICE_SEARCH_TERMINATED");
else if ( respCode == SERVICE_SEARCH_ERROR )
log("SERVICE_SEARCH_ERROR");
else if ( respCode == SERVICE_SEARCH_NO_RECORDS )
log("SERVICE_SEARCH_NO_RECORDS");
else if ( respCode == SERVICE_SEARCH_DEVICE_NOT_REACHABLE )
log("SERVICE_SEARCH_DEVICE_NOT_REACHABLE");
for ( Enumeration records = serviceRecordToEndPoint.keys(); records.hasMoreElements(); )
{
try {
ServiceRecord rec = (ServiceRecord) records.nextElement();
// We make an assumption that the first service is BlueChat. In fact, only one
// service record will be found on each device.
// Note: we know the found service is BlueChat service because we search on specific UUID,
// this UUID is unique to us.
String url = rec.getConnectionURL( ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false );
log("BlueChat service url="+url);
StreamConnection con = (StreamConnection)Connector.open( url );
// retrieve the pending EndPoint and initialize the necessary member variables
// to activate the EndPoint. this includes
// - initialize connection
// - start sender and reader thread
EndPoint endpt = (EndPoint) serviceRecordToEndPoint.get( rec );
if ( endpt != null )
{
endpt.con = con;
Thread t1 = new Thread( endpt.sender );
t1.start();
Thread t2 = new Thread( endpt.reader );
t2.start();
endPoints.addElement( endpt );
log("a new active EndPoint is established. name=" + endpt.remoteName);
// once a EndPoint established, the BlueChat client is responsible to initiate the
// handshake protocol.
endpt.putString( NetLayer.SIGNAL_HANDSHAKE, localName );
} else
{
log("cannot find pending EndPoint when a service is discovered. ignore this service...");
}
} catch (Exception e)
{
e.printStackTrace();
log(e.getClass().getName()+" "+e.getMessage());
}
} // for
// finished process current batch of service record
// clear it and service discovery on next device
serviceRecordToEndPoint.clear();
synchronized( lock )
{
// unlock to proceed to service search on next device
// see DoServiceDiscovery.run()
lock.notifyAll();
}
}
} // inner class Listener
class DoServiceDiscovery extends TimerTask
{
public void run()
{
//
// for each EndPoint, we search for BlueChat service
for (int i = 0; i < pendingEndPoints.size(); i++)
{
EndPoint endpt = (EndPoint) pendingEndPoints.elementAt(i);
try {
log("search service on device " + endpt.remoteName);
//
// searchServices return a transaction id, which we will used to
// identify which remote device the service is found in our callback
// listener (class Listener)
//
// note: in theory, only one runtine instance of Listener is needed
// to handle all discovery callback. however, there is a bug in rococo
// simualtor that cause callback fails with one instance of used
// so we make a new Listener for every searchServices()
endpt.transId = agent.searchServices(null // null to indicate retrieve default attributes
,
new UUID[] { uuid } // BlueChat service UUID SerialPort
,
endpt.remoteDev,
new Listener());
// wait until the above service discovery is completed
// because N6600 cannot handle more than one service discovery
// request at the same time
// see serviceSearchCompleted()
synchronized( lock )
{
try {
lock.wait();
}
catch (InterruptedException ex) {
}
}
}
catch (BluetoothStateException e) {
e.printStackTrace();
log(e.getClass().getName()+" "+e.getMessage());
}
} // for
// no more service to discovery. so any pending EndPoints
// will be ignored and removed
pendingEndPoints.removeAllElements();
// this message is to inform user that chatting can start
ChatMain.instance.gui_log( "", "You can start chatting now" );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -