1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package com.intel.bluetooth;
27
28 import java.util.Random;
29 import java.util.Vector;
30
31 import javax.bluetooth.BluetoothStateException;
32 import javax.bluetooth.DeviceClass;
33 import javax.bluetooth.DiscoveryListener;
34 import javax.bluetooth.RemoteDevice;
35
36 import com.intel.bluetooth.emu.DeviceDescriptor;
37
38
39
40
41 class EmulatorDeviceInquiry implements DeviceInquiryRunnable {
42
43 private static final int DISCOVERY_DURATION_ALWAYS = 200;
44
45 private static final int DISCOVERY_DURATION_MINIMUM = 500;
46
47 private EmulatorLocalDevice localDevice;
48
49 private BluetoothStack bluetoothStack;
50
51 private DiscoveryListener discoveryListener;
52
53 private boolean deviceInquiryCanceled = false;
54
55 private Object canceledEvent = new Object();
56
57 private static Random rnd;
58
59 EmulatorDeviceInquiry(EmulatorLocalDevice localDevice, BluetoothStack bluetoothStack,
60 DiscoveryListener discoveryListener) {
61 this.localDevice = localDevice;
62 this.bluetoothStack = bluetoothStack;
63 this.discoveryListener = discoveryListener;
64 }
65
66
67
68
69
70
71
72 public int runDeviceInquiry(DeviceInquiryThread startedNotify, int accessCode, DiscoveryListener listener)
73 throws BluetoothStateException {
74 try {
75 DeviceDescriptor[] devices = localDevice.getDeviceManagerService().getDiscoveredDevices(
76 localDevice.getAddress());
77 startedNotify.deviceInquiryStartedCallback();
78 long start = System.currentTimeMillis();
79
80 while (devices.length == 0) {
81 if (!randomWait(start, -1)) {
82 break;
83 }
84 devices = updateDiscoveredDevices(devices);
85 }
86
87 int reportedIndex = 0;
88 while ((randomWait(start, reportedIndex)) || (reportedIndex < devices.length)) {
89 if (deviceInquiryCanceled) {
90 return DiscoveryListener.INQUIRY_TERMINATED;
91 }
92 if (reportedIndex < devices.length) {
93 DeviceDescriptor d = devices[reportedIndex];
94
95 d = localDevice.getDeviceManagerService().getDeviceDescriptor(d.getAddress());
96 reportedIndex++;
97 RemoteDevice remoteDevice = RemoteDeviceHelper.createRemoteDevice(bluetoothStack, d.getAddress(), d
98 .getName(), false);
99 DeviceClass cod = new DeviceClass(d.getDeviceClass());
100 DebugLog.debug("deviceDiscovered address", remoteDevice.getBluetoothAddress());
101 DebugLog.debug("deviceDiscovered deviceClass", cod);
102 listener.deviceDiscovered(remoteDevice, cod);
103 }
104 devices = updateDiscoveredDevices(devices);
105 }
106
107 if (deviceInquiryCanceled) {
108 return DiscoveryListener.INQUIRY_TERMINATED;
109 }
110 return DiscoveryListener.INQUIRY_COMPLETED;
111 } finally {
112 bluetoothStack.cancelInquiry(discoveryListener);
113 }
114 }
115
116 private DeviceDescriptor[] updateDiscoveredDevices(DeviceDescriptor[] devices) {
117 DeviceDescriptor[] newDevices = localDevice.getDeviceManagerService().getDiscoveredDevices(
118 localDevice.getAddress());
119 Vector<DeviceDescriptor> discoveredDevice = new Vector<DeviceDescriptor>();
120
121 for (int i = 0; i < devices.length; i++) {
122 discoveredDevice.addElement(devices[i]);
123 }
124
125 newDevicesLoop: for (int i = 0; i < newDevices.length; i++) {
126 for (int k = 0; k < devices.length; k++) {
127 if (newDevices[i].getAddress() == devices[k].getAddress()) {
128 continue newDevicesLoop;
129 }
130 }
131 discoveredDevice.addElement(newDevices[i]);
132 }
133 return (DeviceDescriptor[]) discoveredDevice.toArray(new DeviceDescriptor[discoveredDevice.size()]);
134 }
135
136 private boolean randomWait(long start, int device) {
137 long duration = localDevice.getConfiguration().getDeviceInquiryDuration() * 1000;
138 if (duration <= 0) {
139 duration = DISCOVERY_DURATION_MINIMUM;
140 }
141 long now = System.currentTimeMillis();
142 if ((duration == 0) || (now > start + duration)) {
143 return false;
144 }
145 long timeout = duration / 7;
146 if (localDevice.getConfiguration().isDeviceInquiryRandomDelay()) {
147 if (rnd == null) {
148 rnd = new Random();
149 }
150 long timeleft = start + duration - now;
151 if (timeleft > 0) {
152 timeout = rnd.nextInt((int) timeleft);
153 }
154 }
155 if (device == 0) {
156 timeout += DISCOVERY_DURATION_ALWAYS;
157 }
158
159
160 if (now + timeout > start + duration) {
161 timeout = start + duration - now;
162 }
163 if (timeout <= 0) {
164 return true;
165 }
166 synchronized (canceledEvent) {
167 try {
168 canceledEvent.wait(timeout);
169 } catch (InterruptedException e) {
170 deviceInquiryCanceled = true;
171 }
172 }
173 return true;
174 }
175
176 boolean cancelInquiry(DiscoveryListener listener) {
177 if (discoveryListener != listener) {
178 return false;
179 }
180 deviceInquiryCanceled = true;
181 synchronized (canceledEvent) {
182 canceledEvent.notifyAll();
183 }
184 return true;
185 }
186
187
188
189
190
191
192
193 public void deviceDiscoveredCallback(DiscoveryListener listener, long deviceAddr, int deviceClass,
194 String deviceName, boolean paired) {
195 }
196
197 }