View Javadoc

1   /**
2    *  BlueCove - Java library for Bluetooth
3    *  Copyright (C) 2006-2008 Vlad Skarzhevskyy
4    * 
5    *  Licensed to the Apache Software Foundation (ASF) under one
6    *  or more contributor license agreements.  See the NOTICE file
7    *  distributed with this work for additional information
8    *  regarding copyright ownership.  The ASF licenses this file
9    *  to you under the Apache License, Version 2.0 (the
10   *  "License"); you may not use this file except in compliance
11   *  with the License.  You may obtain a copy of the License at
12   *
13   *    http://www.apache.org/licenses/LICENSE-2.0
14   *
15   *  Unless required by applicable law or agreed to in writing,
16   *  software distributed under the License is distributed on an
17   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   *  KIND, either express or implied.  See the License for the
19   *  specific language governing permissions and limitations
20   *  under the License.
21   *
22   *  @author vlads
23   *  @version $Id: BluetoothInquirer.java 2471 2008-12-01 03:44:20Z skarzhevskyy $
24   */
25  package net.sf.bluecove.obex;
26  
27  import java.io.IOException;
28  import java.util.Vector;
29  
30  import javax.bluetooth.BluetoothStateException;
31  import javax.bluetooth.DeviceClass;
32  import javax.bluetooth.DiscoveryAgent;
33  import javax.bluetooth.DiscoveryListener;
34  import javax.bluetooth.LocalDevice;
35  import javax.bluetooth.RemoteDevice;
36  import javax.bluetooth.ServiceRecord;
37  import javax.bluetooth.UUID;
38  
39  /**
40   * 
41   */
42  public class BluetoothInquirer implements DiscoveryListener {
43  
44  	public static final int MAJOR_COMPUTER = 0x0100;
45  
46  	public static final int MAJOR_PHONE = 0x0200;
47  
48  	public final UUID L2CAP = new UUID(0x0100);
49  
50  	public final UUID RFCOMM = new UUID(0x0003);
51  
52  	public final UUID OBEX = new UUID(0x0008);
53  
54  	public final UUID OBEX_OBJECT_PUSH = new UUID(0x1105);
55  
56  	public final UUID OBEX_FILE_TRANSFER = new UUID(0x1106);
57  
58  	private Main mainInstance;
59  
60  	boolean inquiring;
61  
62  	int servicesSearchTransID = 0;
63  
64  	Vector devices;
65  
66  	String serviceURL;
67  
68  	String serviceSearchOn;
69  
70  	BluetoothInquirer(Main main) {
71  		mainInstance = main;
72  		devices = new Vector();
73  	}
74  
75  	public boolean startInquiry() {
76  		devices.removeAllElements();
77  		inquiring = false;
78  		try {
79  			inquiring = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, this);
80  		} catch (Throwable e) {
81  			Logger.error(e);
82  			mainInstance.setStatus("Cannot start inquiry " + e.getMessage());
83  			return false;
84  		}
85  		if (!inquiring) {
86  			mainInstance.setStatus("Cannot start inquiry");
87  		}
88  		return inquiring;
89  	}
90  
91  	public boolean startServiceSearch(RemoteDevice device, UUID obexUUID) {
92  		serviceURL = null;
93  		try {
94  			UUID[] searchUuidSet = new UUID[] { /* L2CAP, RFCOMM, */obexUUID };
95  			int[] attrIDs = new int[] { 0x0100 // Service name
96  			};
97  			serviceSearchOn = getFriendlyName(device);
98  			servicesSearchTransID = LocalDevice.getLocalDevice().getDiscoveryAgent().searchServices(attrIDs,
99  					searchUuidSet, device, this);
100 		} catch (Throwable e) {
101 			Logger.error(e);
102 			mainInstance.setStatus("Cannot start inquiry " + e.getMessage());
103 			return false;
104 		}
105 		return servicesSearchTransID != 0;
106 	}
107 
108 	static String getFriendlyName(RemoteDevice device) {
109 		try {
110 			String name = device.getFriendlyName(false);
111 			if ((name == null) || (name.length() == 0)) {
112 				return device.getBluetoothAddress();
113 			} else {
114 				return name;
115 			}
116 		} catch (IOException e) {
117 			return device.getBluetoothAddress();
118 		}
119 	}
120 
121 	public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
122 		if ((cod.getMajorDeviceClass() != MAJOR_COMPUTER) && (cod.getMajorDeviceClass() != MAJOR_PHONE)) {
123 			return;
124 		}
125 		devices.add(btDevice);
126 		try {
127 			String name = btDevice.getFriendlyName(false);
128 			mainInstance.setStatus("Found " + name + " " + btDevice.getBluetoothAddress());
129 		} catch (IOException ioe) {
130 			mainInstance.setStatus("Found " + btDevice.getBluetoothAddress());
131 		}
132 	}
133 
134 	public void inquiryCompleted(int discType) {
135 		inquiring = false;
136 	}
137 
138 	public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
139 		for (int i = 0; i < servRecord.length; i++) {
140 			String url = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
141 			if (url == null) {
142 				continue;
143 			}
144 			serviceURL = url;
145 
146 			mainInstance.setStatus("found service on " + serviceSearchOn);
147 		}
148 	}
149 
150 	public void serviceSearchCompleted(int transID, int respCode) {
151 		switch (respCode) {
152 		case SERVICE_SEARCH_ERROR:
153 			// log.info(" -> Error occurred while processing the service
154 			// search");
155 			mainInstance.setStatus("Error on " + serviceSearchOn);
156 			break;
157 		case SERVICE_SEARCH_TERMINATED:
158 			break;
159 		case SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
160 			// log.info(" -> Device not reachable");
161 			mainInstance.setStatus(serviceSearchOn + " not reachable");
162 			break;
163 		default:
164 			if (serviceURL == null) {
165 				// log.info(" -> OBEX Object Push service not found");
166 				mainInstance.setStatus(serviceSearchOn + " no services");
167 			}
168 		}
169 		servicesSearchTransID = 0;
170 	}
171 
172 	public boolean searching() {
173 		return servicesSearchTransID != 0;
174 	}
175 
176 	public String findOBEX(String btAddress) {
177 		RemoteDevice device = new RemoteDeviceExt(btAddress);
178 		this.serviceURL = null;
179 		if (!startServiceSearch(device, OBEX_OBJECT_PUSH)) {
180 			mainInstance.setStatus("Cannot start inquiry");
181 		} else {
182 			while (searching()) {
183 				try {
184 					Thread.sleep(1000);
185 				} catch (Exception e) {
186 				}
187 			}
188 		}
189 		if (this.serviceURL == null) {
190 			if (!startServiceSearch(device, OBEX_FILE_TRANSFER)) {
191 				mainInstance.setStatus("Cannot start inquiry");
192 			} else {
193 				while (searching()) {
194 					try {
195 						Thread.sleep(1000);
196 					} catch (Exception e) {
197 					}
198 				}
199 			}
200 		}
201 		return this.serviceURL;
202 	}
203 
204 	/**
205 	 * 
206 	 */
207 	public void shutdown() {
208 		try {
209 			if (inquiring) {
210 				LocalDevice.getLocalDevice().getDiscoveryAgent().cancelInquiry(this);
211 			}
212 		} catch (BluetoothStateException ignore) {
213 		}
214 	}
215 
216 }