📄 jremclientconnector.java
字号:
/* * JRemCntl - Copyright (C) 2007 Filippo Di Vattimo <fildiv@gmail.com> * See COPYING */package fildiv.jremcntl.common.core;import java.io.IOException;import java.util.Enumeration;import java.util.Vector;import javax.bluetooth.BluetoothStateException;import javax.bluetooth.DataElement;import javax.bluetooth.DeviceClass;import javax.bluetooth.DiscoveryAgent;import javax.bluetooth.DiscoveryListener;import javax.bluetooth.LocalDevice;import javax.bluetooth.RemoteDevice;import javax.bluetooth.ServiceRecord;import javax.bluetooth.UUID;import javax.microedition.io.Connector;import javax.microedition.io.StreamConnection;import fildiv.jremcntl.client.core.JRemClientProtocol;import fildiv.jremcntl.common.proto.JRemAbstractProtocol;import fildiv.jremcntl.common.proto.JRemProtocolMessagesType;public class JRemClientConnector extends JRemBaseConnector { private static final short STATE_NOP = (short) 0; private static final short STATE_INQUIRY = (short) 1; private static final short STATE_SEARCH_SERVICES = (short) 2; private static final short STATE_INTERRUPTING = (short) 3; private static final UUID[] UUID_LIST = new UUID[] { JRemBTConstants.JREM_SERVICE_UUID }; /* private static final UUID[] UUID_LIST = new UUID[] { new UUID(0x1101) }; */ private LocalDevice localDevice; private DiscoveryAgent agent; private JRemClientProtocol proto; private StreamConnection scon; private Thread theThread; private short state; private int transID = -1; private String url; private boolean isConnected; /* * Discovery listener */ protected class JRemDiscoveryListener implements DiscoveryListener { private Vector devices; private Vector servicesRec; protected JRemDiscoveryListener() { clear(); } public synchronized void deviceDiscovered(RemoteDevice rd, DeviceClass dc) { log("Device discovered : " + rd.getBluetoothAddress()); devices.addElement(rd); connectorListener.deviceDiscovered(rd, dc); } public synchronized void inquiryCompleted(int discType) { String msg = ""; boolean error = false; switch(discType) { case DiscoveryListener.INQUIRY_COMPLETED: msg = "completed"; break; case DiscoveryListener.INQUIRY_TERMINATED: connectorListener.interrupt(); msg = "terminated"; break; case DiscoveryListener.INQUIRY_ERROR: error = true; msg = "error"; break; } log("Inquiry [" + msg + "]"); if (devices.size() == 0) log("No device found!"); connectorListener.discoveryCompleted(devices, error); awakeThread(); } public synchronized void serviceSearchCompleted(int transId, int respCode) { String msg = ""; switch(respCode) { case DiscoveryListener.SERVICE_SEARCH_COMPLETED: msg = "completed"; break; case DiscoveryListener.SERVICE_SEARCH_TERMINATED: connectorListener.interrupt(); msg = "terminated"; break; case DiscoveryListener.SERVICE_SEARCH_ERROR: msg = "error"; break; case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE: msg = "not reachable"; break; } log("Service Search [" + msg + "]"); int serviceNo = servicesRec.size(); if (serviceNo == 0) log("No services found!"); else log("Tot services : " + serviceNo); awakeThread(); } public synchronized void servicesDiscovered(int tid, ServiceRecord[] srs) { log("Service discovered on tid " + tid); for (int i = 0; i < srs.length; i++) { ServiceRecord sr = srs[i]; servicesRec.addElement(sr); String URL = sr.getConnectionURL( ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); log("URL=" + URL); } } protected Vector getDevices() { return devices; } protected Vector getServicesRec() { return servicesRec; } public void clear() { devices = new Vector(); servicesRec = new Vector(); } }; private JRemClientConnectionListener connectorListener; private JRemDiscoveryListener discoveryListener = new JRemDiscoveryListener(); public JRemClientConnector() { super(); } public void setConnectorListener(JRemClientConnectionListener listener) { if (theThread != null) return; this.connectorListener = listener; } public synchronized void findDevices() { if (theThread != null) { connectorListener.inProgress(); return; } theThread = new Thread() { public void run() { inquiry(); } }; theThread.start(); } public synchronized void connect(final RemoteDevice rd) { if (isConnected()) throw new IllegalStateException("Already connected"); if (theThread != null) { connectorListener.inProgress(); return; } theThread = new Thread() { public void run() { connectToRD(rd); } }; theThread.start(); } public synchronized void connect(final String url) { if (isConnected()) throw new IllegalStateException("Already connected"); if (theThread != null) { connectorListener.inProgress(); } theThread = new Thread() { public void run() { connectToUrl(url); } }; theThread.start(); } /* * Called in thread */ private void inquiry() { if (theThread == null) return; DiscoveryAgent agent = getAgent(); JRemDiscoveryListener dl = getDiscoveryListener(); try { log("Start inquiry..."); connectorListener.discoveryStarted(); state = STATE_INQUIRY; agent.startInquiry(DiscoveryAgent.GIAC, dl); synchronized(theThread) { theThread.wait(); } } catch (Exception e) { log(e); connectorListener.exceptionOccurred(e); } finally { state = STATE_NOP; synchronized(theThread) { theThread = null; } } } /* * Called in thread */ private void connectToRD(RemoteDevice rd) { if (theThread == null) return; connectorListener.serviceOpening(); DiscoveryAgent agent = getAgent(); JRemDiscoveryListener dl = getDiscoveryListener(); boolean success = false; try { log("Start service search..."); state = STATE_SEARCH_SERVICES; transID = agent.searchServices(null, UUID_LIST, rd, dl); synchronized(theThread) { theThread.wait(); } String url = getURL(dl.getServicesRec()); if (url != null) success = connectImpl(url); else success = false; } catch (Exception e) { success = false; connectorListener.exceptionOccurred(e); } finally { state = STATE_NOP; synchronized(theThread) { theThread = null; } connectorListener.connected(success); } } /* * Called in thread */ private void connectToUrl(String url) { boolean success = false; try { success = connectImpl(url); } finally { synchronized(theThread) { theThread = null; } connectorListener.connected(success); } } private String getURL(Vector servicesRec) { for (int index = 0; index < servicesRec.size(); ++index) { ServiceRecord sr = (ServiceRecord) servicesRec.elementAt(index); if (hasUUID(sr, JRemBTConstants.JREM_SERVICE_UUID)) { String url = sr.getConnectionURL( ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); return url; } } return null; } /* * This function is derived from the class "Util.java" originally distributed with: * ValhallaChat, Instant messaging application for bluetooth networks. * * Copyright: (C) 2006 * Adapted by Jaume de Juan on http://sf.net/projects/valhallachat * Author: Jaume de Juan * This method is necessary to avoid the BUG in Blue Cove 1.1.2 where devices * that do not have a searched UUID will be returned as if they do. * This method basically performs a double-check. */ protected static boolean hasUUID(ServiceRecord sr, UUID uuid) { DataElement de = sr.getAttributeValue(JRemBTConstants.SERVICE_ATTR_CLASS_ID_LIST); if ((de != null) && (de.getDataType() == DataElement.DATSEQ)) { Enumeration enu = (Enumeration) de.getValue(); while (enu.hasMoreElements()) { DataElement el = (DataElement) enu.nextElement(); if (el.getDataType() == DataElement.UUID) { if (uuid.equals((UUID) el.getValue())) { return true; } } } } return false; } public synchronized void interrupt() { if ( (theThread == null) || (state == STATE_NOP) || (state == STATE_INTERRUPTING) ) return; DiscoveryAgent agent = getAgent(); if (state == STATE_INQUIRY) { agent.cancelInquiry(discoveryListener); } else if (state == STATE_SEARCH_SERVICES) { if (transID >= 0) agent.cancelServiceSearch(transID); } state = STATE_INTERRUPTING; } public JRemAbstractProtocol getProtocol() { return proto; } public boolean isConnected() { return isConnected; } public synchronized void close() { try { if (proto != null) { if (!proto.isClosed()) proto.sendCommandID(JRemProtocolMessagesType.MSG_TYPE_CLOSE_CONNECTION); proto.close(); } if (scon != null) scon.close(); } catch (Exception e) { log("Exception occurred while closing connection."); log(e.getMessage()); } finally { proto = null; isConnected = false; url = null; } } public String getURL() { return url; } private boolean connectImpl(String url) { log("Connect to : " + url); this.url = url; try { scon = (StreamConnection) Connector.open(url); proto = new JRemClientProtocol( scon.openDataInputStream(), scon.openDataOutputStream(), log); isConnected = true; } catch (IOException e) { log("Failed to connect."); log(e.getMessage()); isConnected = false; // connectorListener.exceptionOccurred(e); } return isConnected; } private JRemDiscoveryListener getDiscoveryListener() { synchronized (discoveryListener) { discoveryListener.clear(); } return discoveryListener; } private void awakeThread() { synchronized(theThread) { theThread.notify(); } } protected DiscoveryAgent getAgent() { if (agent != null) return agent; synchronized(this) { try { localDevice = LocalDevice.getLocalDevice(); } catch (BluetoothStateException e) { throw new JRemRuntimeException(e); } agent = localDevice.getDiscoveryAgent(); } return agent; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -