BowlerKernel
BlueCoveManager.java
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright 2010 Neuron Robotics, LLC
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  ******************************************************************************/
15 package com.neuronrobotics.sdk.wireless.bluetooth;
16 
17 import java.io.DataInputStream;
18 import java.io.DataOutputStream;
19 import java.io.IOException;
20 import java.util.ArrayList;
21 
22 import javax.bluetooth.BluetoothStateException;
23 import javax.bluetooth.DeviceClass;
24 import javax.bluetooth.DiscoveryAgent;
25 import javax.bluetooth.DiscoveryListener;
26 import javax.bluetooth.LocalDevice;
27 import javax.bluetooth.RemoteDevice;
28 import javax.bluetooth.ServiceRecord;
29 import javax.bluetooth.UUID;
30 import javax.microedition.io.Connector;
31 import javax.microedition.io.StreamConnection;
32 
33 import com.neuronrobotics.sdk.common.Log;
34 import com.neuronrobotics.sdk.common.MissingNativeLibraryException;
35 
36 
37 
38 
39 // TODO: Auto-generated Javadoc
40 //import com.intel.bluetooth.test.SimpleClient.CancelThread;
41 
45 public class BlueCoveManager implements DiscoveryListener {
46 
48  ArrayList<ServiceRecord> records= new ArrayList<ServiceRecord>();
49 
51  ArrayList<RemoteDevice> deviceList = new ArrayList<RemoteDevice>();
52 
54  static final UUID uuid = com.intel.bluetooth.BluetoothConsts.RFCOMM_PROTOCOL_UUID;
55 
57  private String selected = null;
58 
60  private DataInputStream ins;
61 
63  private DataOutputStream outs;
64 
66  private StreamConnection conn;
67 
69  private int searchId=0xffff;
70 
74  public BlueCoveManager(){
75  }
76 
82  public synchronized void find() throws MissingNativeLibraryException {
83  for (RemoteDevice d:deviceList) {
84  if(d.getBluetoothAddress().equals(selected)){
85  try {Thread.sleep(100);} catch (InterruptedException e) {}
86  return;
87  }
88  }
89  disconnect();
90  Log.info("Finding Devices...");
91  try {
92  LocalDevice.getLocalDevice().getDiscoveryAgent().cancelInquiry(this);
93  LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, this);
94  try {wait();} catch (InterruptedException e) {e.printStackTrace();}
95 
96  } catch (BluetoothStateException e) {
97  e.printStackTrace();
98  }
99  for (RemoteDevice d:deviceList) {
100  try {
101  Log.info("Device name: " + d.getFriendlyName(false)+" address: " + d.getBluetoothAddress());
102  } catch (IOException e) {
103  //e.printStackTrace();
104  }
105  }
106  if(deviceList.size()==0)
107  Log.info("No Devices Found!");
108 
109  }
110 
111  /* (non-Javadoc)
112  * @see javax.bluetooth.DiscoveryListener#deviceDiscovered(javax.bluetooth.RemoteDevice, javax.bluetooth.DeviceClass)
113  */
114  public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
115  deviceList.add(btDevice);
116  //Log.info("deviceDiscovered " + btDevice.getBluetoothAddress() + " DeviceClass: " + ((Object)cod).toString());
117  }
118 
119  /* (non-Javadoc)
120  * @see javax.bluetooth.DiscoveryListener#inquiryCompleted(int)
121  */
122  public synchronized void inquiryCompleted(int discType) {
123  notifyAll();
124  }
125 
126  /* (non-Javadoc)
127  * @see javax.bluetooth.DiscoveryListener#servicesDiscovered(int, javax.bluetooth.ServiceRecord[])
128  */
129  public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
130  //Log.info("###Record list added: "+servRecord.length);
131  for ( int i=0; i< servRecord.length;i++)
132  records.add(servRecord[i]);
133  }
134 
135  /* (non-Javadoc)
136  * @see javax.bluetooth.DiscoveryListener#serviceSearchCompleted(int, int)
137  */
138  public synchronized void serviceSearchCompleted(int transID, int respCode) {
139  notifyAll();
140  }
141 
148  public String [] getAvailableSerialDevices(boolean refresh) {
149  if(refresh){
150  find();
151  }
152  String [] s=new String[deviceList.size()];
153  String tmp="";
154  int i=0;
155  for (RemoteDevice d: deviceList){
156  try {
157  tmp=d.getFriendlyName(false);
158  if (tmp == "")
159  tmp = "No Name";
160  s[i]=tmp+"_"+d.getBluetoothAddress();
161  } catch (Exception e) {
162  s[i]="Failed Name"+"_"+d.getBluetoothAddress();
163  }
164  i++;
165  }
166  return s;
167  }
168 
175  public synchronized RemoteDevice getDevice(String name){
176  String addr = name.substring(name.indexOf('_')+1);
177  //System.out.println("Getting device with address: "+addr);
178  String [] s=getAvailableSerialDevices(false);
179  for (int i=0;i<s.length;i++){
180  if(s[i].contains(addr)){
181  try {
182  RemoteDevice dev = deviceList.get(i);
183  //System.out.println("Found device: "+s[i]);
184  return dev;
185  }catch(Exception e) {
186  e.printStackTrace();
187  }
188  }else {
189  //System.out.println("Non matching device: "+s[i]);
190  }
191  }
192  return null;
193  }
194 
198  public synchronized void disconnect() {
199  Log.info("Disconnecting: "+selected);
200  deviceList.clear();
201  try {
202  if(ins!= null)
203  ins.close();
204  if(outs!=null)
205  outs.close();
206  if (conn != null)
207  conn.close();
208  LocalDevice.getLocalDevice().getDiscoveryAgent().cancelInquiry(this);
209  if(searchId != 0xffff)
210  LocalDevice.getLocalDevice().getDiscoveryAgent().cancelServiceSearch(searchId);
211  } catch (Exception e) {
212  throw new MissingNativeLibraryException(e.getMessage());
213  }
214  Log.info("Disconnected");
215 
216  }
217  /*
218  public boolean reconnect(){
219  find();
220  if(!deviceList.contains(selected))
221  return false;
222  disconnect();
223  return connect();
224  }
225  */
231  public synchronized void connect(String devAddress){
232  RemoteDevice d = getDevice(devAddress);
233  if(deviceList.contains(d))
234  selected = d.getBluetoothAddress();
235  else{
236  find();
237  if(!deviceList.contains(d))
238  throw new RuntimeException("Divice no longer availiable");
239  }
240  connect();
241  }
242 
248  private synchronized boolean connect(){
249  try{
250  if(ins!= null)
251  ins.close();
252  if(outs!=null)
253  outs.close();
254  if(conn!=null)
255  conn.close();
256  }catch (Exception e){
257  throw new RuntimeException(e);
258  }
259  Log.info("Connecting : "+selected);
260  synchronized (this) {
261  records.clear();
262  try {
263  int[] attrSet = null;
264  UUID[] id =new UUID[] { uuid };
265  if(searchId != 0xffff)
266  LocalDevice.getLocalDevice().getDiscoveryAgent().cancelServiceSearch(searchId);
267  searchId=LocalDevice.getLocalDevice().getDiscoveryAgent().searchServices(attrSet,id, getDevice(selected), this);
268  try {wait();} catch (InterruptedException e) {e.printStackTrace();}
269 
270  } catch (BluetoothStateException e) {
271  e.printStackTrace();
272  }
273  }
274 
275  if (records.size()==0){
276  System.err.println("No compatible records");
277  return false;
278  }
279  //Log.info("Found SPP:RFCOMM services OK!");
280  try {
281  String url = records.get(0).getConnectionURL(ServiceRecord.AUTHENTICATE_NOENCRYPT, false);
282  try{
283  StreamConnection c =(StreamConnection) Connector.open(url);
284  conn = c;
285  }catch (IOException ex){
286  System.err.println("Failed to connect to "+url);
287  if(!ex.getMessage().contains("Device or resource busy"))
288  throw ex;
289  }
290  outs = conn.openDataOutputStream();
291  ins = conn.openDataInputStream();
292  outs.flush();
293  ins.available();
294  Log.info("Connection OK!");
295  return true;
296  } catch (Exception e) {
297  e.printStackTrace();
298  System.err.println("No connection");
299  return false;
300  }
301  }
302 
308  public synchronized DataInputStream getDataIns() {
309  if (selected == null || ins==null)
310  throw new RuntimeException();
311  return ins;
312  }
313 
319  public synchronized DataOutputStream getDataOuts() {
320  if (selected == null || outs==null )
321  throw new RuntimeException();
322  return outs;
323  }
324 }
static void info(String message)
Definition: Log.java:110
void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
synchronized void serviceSearchCompleted(int transID, int respCode)
void servicesDiscovered(int transID, ServiceRecord[] servRecord)