1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package motej;
17
18 import java.io.IOException;
19 import java.util.HashSet;
20 import java.util.Set;
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.swing.event.EventListenerList;
30
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import com.intel.bluetooth.BlueCoveConfigProperties;
35
36
37
38
39
40
41
42 public class MoteFinder {
43
44
45 private static class SingletonHolder {
46
47 private static final MoteFinder INSTANCE = new MoteFinder();
48
49 }
50
51
52
53
54
55
56 public static MoteFinder getMoteFinder() {
57 try {
58
59 System.setProperty(BlueCoveConfigProperties.PROPERTY_JSR_82_PSM_MINIMUM_OFF, "true");
60
61 SingletonHolder.INSTANCE.localDevice = LocalDevice.getLocalDevice();
62 SingletonHolder.INSTANCE.discoveryAgent = SingletonHolder.INSTANCE.localDevice.getDiscoveryAgent();
63 return SingletonHolder.INSTANCE;
64 } catch (BluetoothStateException ex) {
65 throw new RuntimeException(ex);
66 }
67 }
68
69 private Logger log = LoggerFactory.getLogger(MoteFinder.class);
70
71 private EventListenerList listenerList = new EventListenerList();
72
73 private DiscoveryAgent discoveryAgent;
74
75 private Set<String> bluetoothAddressCache = new HashSet<String>();
76
77 private Set<DiscoveryListener> discoveryListeners;
78
79 public void addDiscoveryListener(DiscoveryListener listener) {
80 if (discoveryListeners == null) {
81 discoveryListeners = new HashSet<DiscoveryListener>();
82 }
83
84 discoveryListeners.add(listener);
85 }
86
87 public void removeDiscoveryListener(DiscoveryListener listener) {
88 if (discoveryListeners != null) {
89 discoveryListeners.remove(listener);
90 }
91 }
92
93 protected final DiscoveryListener listener = new DiscoveryListener() {
94
95 public void deviceDiscovered(final RemoteDevice device, DeviceClass clazz) {
96 if (log.isInfoEnabled()) {
97 try {
98 log.info("found device: " + device.getFriendlyName(true)
99 + " - " + device.getBluetoothAddress() + " - "
100 + clazz.getMajorDeviceClass() + ":"
101 + clazz.getMinorDeviceClass() + " - "
102 + clazz.getServiceClasses());
103 } catch (IOException ex) {
104 log.error(ex.getMessage(), ex);
105 throw new RuntimeException(ex);
106 }
107 }
108
109 try {
110 if (!device.getFriendlyName(true).startsWith("Nintendo")) {
111 return;
112 }
113 } catch (IOException ex) {
114 log.error(ex.getMessage(), ex);
115 throw new RuntimeException(ex);
116 }
117
118 final String address = device.getBluetoothAddress();
119
120
121 if (!bluetoothAddressCache.contains(address)) {
122 Thread connectThread = new Thread("connect: " + address) {
123 public void run() {
124 Mote mote = new Mote(address);
125 fireMoteFound(mote);
126 bluetoothAddressCache.add(address);
127 };
128 };
129 connectThread.start();
130
131 for (DiscoveryListener delegate : discoveryListeners) {
132 delegate.deviceDiscovered(device, clazz);
133 }
134 }
135 }
136
137 public void inquiryCompleted(int discType) {
138 if (discType == DiscoveryListener.INQUIRY_COMPLETED) {
139 if (log.isInfoEnabled()) {
140 log.info("inquiry completed");
141 }
142 }
143
144 if (discType == DiscoveryListener.INQUIRY_TERMINATED) {
145 if (log.isInfoEnabled()) {
146 log.info("inquiry terminated");
147 }
148 }
149
150 if (discType == DiscoveryListener.INQUIRY_ERROR) {
151 if (log.isInfoEnabled()) {
152 log.info("inquiry error");
153 }
154 }
155
156 for (DiscoveryListener delegate : discoveryListeners) {
157 delegate.inquiryCompleted(discType);
158 }
159 }
160
161 public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
162
163
164 for (DiscoveryListener delegate : discoveryListeners) {
165 delegate.servicesDiscovered(transID, servRecord);
166 }
167 }
168
169 public void serviceSearchCompleted(int transID, int respCode) {
170
171
172 for (DiscoveryListener delegate : discoveryListeners) {
173 delegate.serviceSearchCompleted(transID, respCode);
174 }
175 }
176 };
177
178 private LocalDevice localDevice;
179
180 private MoteFinder() {};
181
182 public void addMoteFinderListener(MoteFinderListener listener) {
183 listenerList.add(MoteFinderListener.class, listener);
184 }
185
186 protected void fireMoteFound(Mote mote) {
187 MoteFinderListener[] listeners = listenerList.getListeners(MoteFinderListener.class);
188 for (MoteFinderListener l : listeners) {
189 l.moteFound(mote);
190 }
191 }
192
193 public void removeMoteFinderListener(MoteFinderListener listener) {
194 listenerList.remove(MoteFinderListener.class, listener);
195 }
196
197 public void startDiscovery() {
198 try {
199 discoveryAgent.startInquiry(DiscoveryAgent.GIAC, listener);
200 } catch (BluetoothStateException ex) {
201 throw new RuntimeException(ex);
202 }
203 }
204
205 public void stopDiscovery() {
206 discoveryAgent.cancelInquiry(listener);
207 }
208
209 }