1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package com.intel.bluetooth;
25
26 import java.io.ByteArrayInputStream;
27 import java.io.IOException;
28 import java.io.InterruptedIOException;
29 import java.util.Enumeration;
30 import java.util.Hashtable;
31 import java.util.Vector;
32
33 import javax.bluetooth.BluetoothConnectionException;
34 import javax.bluetooth.BluetoothStateException;
35 import javax.bluetooth.DataElement;
36 import javax.bluetooth.DeviceClass;
37 import javax.bluetooth.DiscoveryAgent;
38 import javax.bluetooth.DiscoveryListener;
39 import javax.bluetooth.RemoteDevice;
40 import javax.bluetooth.ServiceRecord;
41 import javax.bluetooth.ServiceRegistrationException;
42 import javax.bluetooth.UUID;
43
44 class BluetoothStackMicrosoft implements BluetoothStack {
45
46 private static final int BTH_MODE_POWER_OFF = 1;
47
48 private static final int BTH_MODE_CONNECTABLE = 2;
49
50 private static final int BTH_MODE_DISCOVERABLE = 3;
51
52 private static BluetoothStackMicrosoft singleInstance = null;
53
54 private boolean peerInitialized = false;
55
56 private boolean windowsCE;
57
58 private long localBluetoothAddress = 0;
59
60 private DiscoveryListener currentDeviceDiscoveryListener;
61
62 private Thread limitedDiscoverableTimer;
63
64
65 private final static int ATTR_RETRIEVABLE_MAX = 256;
66
67 private Hashtable deviceDiscoveryDevices;
68
69 private static int connectThreadNumber;
70
71 private static synchronized int nextConnectThreadNum() {
72 return connectThreadNumber++;
73 }
74
75 BluetoothStackMicrosoft() {
76 }
77
78
79
80 public String getStackID() {
81 return BlueCoveImpl.STACK_WINSOCK;
82 }
83
84
85
86
87
88
89 public native boolean isNativeCodeLoaded();
90
91
92
93
94
95
96 public LibraryInformation[] requireNativeLibraries() {
97 return LibraryInformation.library(BlueCoveImpl.NATIVE_LIB_MS);
98 }
99
100 public String toString() {
101 return getStackID();
102 }
103
104 public native int getLibraryVersion();
105
106 public native int detectBluetoothStack();
107
108 public native void enableNativeDebug(Class nativeDebugCallback, boolean on);
109
110 private static native int initializationStatus() throws IOException;
111
112 private native void uninitialize();
113
114 private native boolean isWindowsCE();
115
116 public void initialize() throws BluetoothStateException {
117 if (singleInstance != null) {
118 throw new BluetoothStateException("Only one instance of " + getStackID() + " stack supported");
119 }
120 try {
121 int status = initializationStatus();
122 DebugLog.debug("initializationStatus", status);
123 if (status == 1) {
124 peerInitialized = true;
125 }
126 windowsCE = isWindowsCE();
127 singleInstance = this;
128 } catch (BluetoothStateException e) {
129 throw e;
130 } catch (IOException e) {
131 DebugLog.fatal("initialization", e);
132 throw new BluetoothStateException(e.getMessage());
133 }
134 }
135
136 public void destroy() {
137 if (singleInstance != this) {
138 throw new RuntimeException("Destroy invalid instance");
139 }
140 if (peerInitialized) {
141 peerInitialized = false;
142 uninitialize();
143 }
144 cancelLimitedDiscoverableTimer();
145 singleInstance = null;
146 }
147
148 private void initialized() throws BluetoothStateException {
149 if (!peerInitialized) {
150 throw new BluetoothStateException("Bluetooth system is unavailable");
151 }
152 }
153
154
155
156
157
158
159 public int getFeatureSet() {
160 return FEATURE_SERVICE_ATTRIBUTES | (windowsCE ? 0 : FEATURE_SET_DEVICE_SERVICE_CLASSES);
161 }
162
163
164
165 private native int getDeviceClass(long address);
166
167 private native void setDiscoverable(boolean on) throws BluetoothStateException;
168
169 private native int getBluetoothRadioMode();
170
171 private native String getradioname(long address);
172
173 private native int getDeviceVersion(long address);
174
175 private native int getDeviceManufacturer(long address);
176
177 public String getLocalDeviceBluetoothAddress() {
178 try {
179 long socket = socket(false, false);
180 bind(socket);
181 localBluetoothAddress = getsockaddress(socket);
182 String address = RemoteDeviceHelper.getBluetoothAddress(localBluetoothAddress);
183 storesockopt(socket);
184 close(socket);
185 return address;
186 } catch (IOException e) {
187 DebugLog.error("get local bluetoothAddress", e);
188 return "000000000000";
189 }
190 }
191
192 public String getLocalDeviceName() {
193 if (localBluetoothAddress == 0) {
194 getLocalDeviceBluetoothAddress();
195 }
196 return getradioname(localBluetoothAddress);
197 }
198
199 public String getRemoteDeviceFriendlyName(long address) throws IOException {
200 return getpeername(address);
201 }
202
203 public DeviceClass getLocalDeviceClass() {
204 return new DeviceClass(getDeviceClass(localBluetoothAddress));
205 }
206
207
208
209
210
211
212 public void setLocalDeviceServiceClasses(int classOfDevice) {
213
214 }
215
216 private void cancelLimitedDiscoverableTimer() {
217 if (limitedDiscoverableTimer != null) {
218 limitedDiscoverableTimer.interrupt();
219 limitedDiscoverableTimer = null;
220 }
221 }
222
223 public boolean setLocalDeviceDiscoverable(int mode) throws BluetoothStateException {
224 switch (mode) {
225 case DiscoveryAgent.NOT_DISCOVERABLE:
226 cancelLimitedDiscoverableTimer();
227 DebugLog.debug("setDiscoverable(false)");
228 setDiscoverable(false);
229 return (DiscoveryAgent.NOT_DISCOVERABLE == getLocalDeviceDiscoverable());
230 case DiscoveryAgent.GIAC:
231 cancelLimitedDiscoverableTimer();
232 DebugLog.debug("setDiscoverable(true)");
233 setDiscoverable(true);
234 return (DiscoveryAgent.GIAC == getLocalDeviceDiscoverable());
235 case DiscoveryAgent.LIAC:
236 cancelLimitedDiscoverableTimer();
237 DebugLog.debug("setDiscoverable(LIAC)");
238 setDiscoverable(true);
239 if (!(DiscoveryAgent.GIAC == getLocalDeviceDiscoverable())) {
240 return false;
241 }
242
243 limitedDiscoverableTimer = Utils.schedule(60 * 1000, new Runnable() {
244 public void run() {
245 try {
246 setDiscoverable(false);
247 } catch (BluetoothStateException e) {
248 DebugLog.debug("error setDiscoverable", e);
249 } finally {
250 limitedDiscoverableTimer = null;
251 }
252 }
253 });
254 return true;
255 }
256 return false;
257 }
258
259 public boolean isLocalDevicePowerOn() {
260 int mode = getBluetoothRadioMode();
261 if (mode == BTH_MODE_POWER_OFF) {
262 return false;
263 }
264 return ((mode == BTH_MODE_CONNECTABLE) || (mode == BTH_MODE_DISCOVERABLE));
265 }
266
267 public int getLocalDeviceDiscoverable() {
268 int mode = getBluetoothRadioMode();
269 if (mode == BTH_MODE_DISCOVERABLE) {
270 if (limitedDiscoverableTimer != null) {
271 DebugLog.debug("Discoverable = LIAC");
272 return DiscoveryAgent.LIAC;
273 } else {
274 DebugLog.debug("Discoverable = GIAC");
275 return DiscoveryAgent.GIAC;
276 }
277 } else {
278 DebugLog.debug("Discoverable = NOT_DISCOVERABLE");
279 return DiscoveryAgent.NOT_DISCOVERABLE;
280 }
281 }
282
283 public String getLocalDeviceProperty(String property) {
284 if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_DEVICES_MAX.equals(property)) {
285 return "7";
286 }
287 if (BluetoothConsts.PROPERTY_BLUETOOTH_SD_TRANS_MAX.equals(property)) {
288 return "7";
289 }
290 if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_INQUIRY_SCAN.equals(property)) {
291 return BlueCoveImpl.TRUE;
292 }
293 if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_PAGE_SCAN.equals(property)) {
294 return BlueCoveImpl.TRUE;
295 }
296 if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_INQUIRY.equals(property)) {
297 return BlueCoveImpl.TRUE;
298 }
299 if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_PAGE.equals(property)) {
300 return BlueCoveImpl.TRUE;
301 }
302
303 if (BluetoothConsts.PROPERTY_BLUETOOTH_SD_ATTR_RETRIEVABLE_MAX.equals(property)) {
304 return String.valueOf(ATTR_RETRIEVABLE_MAX);
305 }
306 if (BluetoothConsts.PROPERTY_BLUETOOTH_MASTER_SWITCH.equals(property)) {
307 return BlueCoveImpl.FALSE;
308 }
309 if (BluetoothConsts.PROPERTY_BLUETOOTH_L2CAP_RECEIVEMTU_MAX.equals(property)) {
310 return "0";
311 }
312
313 if ("bluecove.radio.version".equals(property)) {
314 return String.valueOf(getDeviceVersion(localBluetoothAddress));
315 }
316 if ("bluecove.radio.manufacturer".equals(property)) {
317 return String.valueOf(getDeviceManufacturer(localBluetoothAddress));
318 }
319 return null;
320 }
321
322
323
324
325
326
327 public boolean isCurrentThreadInterruptedCallback() {
328 return UtilsJavaSE.isCurrentThreadInterrupted();
329 }
330
331 private native boolean retrieveDevicesImpl(int option, RetrieveDevicesCallback retrieveDevicesCallback);
332
333 public RemoteDevice[] retrieveDevices(int option) {
334 if (windowsCE) {
335 return null;
336 }
337 final Vector devices = new Vector();
338 RetrieveDevicesCallback retrieveDevicesCallback = new RetrieveDevicesCallback() {
339 public void deviceFoundCallback(long deviceAddr, int deviceClass, String deviceName, boolean paired) {
340 DebugLog.debug("device found", deviceAddr);
341 RemoteDevice remoteDevice = RemoteDeviceHelper.createRemoteDevice(BluetoothStackMicrosoft.this,
342 deviceAddr, deviceName, paired);
343 devices.add(remoteDevice);
344 }
345 };
346 if (retrieveDevicesImpl(option, retrieveDevicesCallback)) {
347 return RemoteDeviceHelper.remoteDeviceListToArray(devices);
348 } else {
349 return null;
350 }
351 }
352
353 private native boolean isRemoteDeviceTrustedImpl(long address);
354
355 public Boolean isRemoteDeviceTrusted(long address) {
356 if (windowsCE) {
357 return null;
358 }
359 return new Boolean(isRemoteDeviceTrustedImpl(address));
360 }
361
362 private native boolean isRemoteDeviceAuthenticatedImpl(long address);
363
364 public Boolean isRemoteDeviceAuthenticated(long address) {
365 if (windowsCE) {
366 return null;
367 }
368 return new Boolean(isRemoteDeviceAuthenticatedImpl(address));
369 }
370
371 private native boolean authenticateRemoteDeviceImpl(long address, String passkey) throws IOException;
372
373 public boolean authenticateRemoteDevice(long address) throws IOException {
374 return authenticateRemoteDeviceImpl(address, null);
375 }
376
377
378
379
380
381
382 public boolean authenticateRemoteDevice(long address, String passkey) throws IOException {
383 return authenticateRemoteDeviceImpl(address, passkey);
384 }
385
386 private native void removeAuthenticationWithRemoteDeviceImpl(long address) throws IOException;
387
388
389
390
391
392
393 public void removeAuthenticationWithRemoteDevice(long address) throws IOException {
394 removeAuthenticationWithRemoteDeviceImpl(address);
395 }
396
397
398
399
400
401
402 private native int runDeviceInquiryImpl(DeviceInquiryRunnable inquiryRunnable, DeviceInquiryThread inquiryThread, int accessCode, int duration,
403 DiscoveryListener listener) throws BluetoothStateException;
404
405 public boolean startInquiry(int accessCode, DiscoveryListener listener) throws BluetoothStateException {
406 initialized();
407 if (currentDeviceDiscoveryListener != null) {
408 throw new BluetoothStateException("Another inquiry already running");
409 }
410 currentDeviceDiscoveryListener = listener;
411
412 DeviceInquiryRunnable inquiryRunnable = new DeviceInquiryRunnable() {
413
414 public int runDeviceInquiry(DeviceInquiryThread inquiryThread, int accessCode, DiscoveryListener listener) throws BluetoothStateException {
415 try {
416 deviceDiscoveryDevices = new Hashtable();
417 int discType = runDeviceInquiryImpl(this, inquiryThread, accessCode, DeviceInquiryThread
418 .getConfigDeviceInquiryDuration(), listener);
419 if (discType == DiscoveryListener.INQUIRY_COMPLETED) {
420 for (Enumeration en = deviceDiscoveryDevices.keys(); en.hasMoreElements();) {
421 RemoteDevice remoteDevice = (RemoteDevice) en.nextElement();
422 DeviceClass deviceClass = (DeviceClass) deviceDiscoveryDevices.get(remoteDevice);
423 listener.deviceDiscovered(remoteDevice, deviceClass);
424
425 if (currentDeviceDiscoveryListener == null) {
426 return DiscoveryListener.INQUIRY_TERMINATED;
427 }
428 }
429 }
430 return discType;
431 } finally {
432 deviceDiscoveryDevices = null;
433 currentDeviceDiscoveryListener = null;
434 }
435 }
436
437
438
439
440
441 public void deviceDiscoveredCallback(DiscoveryListener listener, long deviceAddr, int deviceClass, String deviceName, boolean paired) {
442 RemoteDevice remoteDevice = RemoteDeviceHelper.createRemoteDevice(BluetoothStackMicrosoft.this, deviceAddr, deviceName, paired);
443 if ((currentDeviceDiscoveryListener == null) || (deviceDiscoveryDevices == null)
444 || (currentDeviceDiscoveryListener != listener)) {
445 return;
446 }
447 DeviceClass cod = new DeviceClass(deviceClass);
448 DebugLog.debug("deviceDiscoveredCallback address", remoteDevice.getBluetoothAddress());
449 DebugLog.debug("deviceDiscoveredCallback deviceClass", cod);
450 deviceDiscoveryDevices.put(remoteDevice, cod);
451
452 }
453 };
454 return DeviceInquiryThread.startInquiry(this, inquiryRunnable, accessCode, listener);
455 }
456
457
458
459
460 private native boolean cancelInquiry();
461
462 public boolean cancelInquiry(DiscoveryListener listener) {
463 if (currentDeviceDiscoveryListener != listener) {
464 return false;
465 }
466
467 currentDeviceDiscoveryListener = null;
468 return cancelInquiry();
469 }
470
471
472
473
474
475
476 private native int[] runSearchServicesImpl(UUID[] uuidSet, long address) throws SearchServicesException;
477
478
479
480
481 public native byte[] getServiceAttributes(int[] attrIDs, long address, int handle) throws IOException;
482
483 public int searchServices(int[] attrSet, UUID[] uuidSet, RemoteDevice device, DiscoveryListener listener)
484 throws BluetoothStateException {
485
486 SearchServicesRunnable searchRunnable = new SearchServicesRunnable() {
487
488 public int runSearchServices(SearchServicesThread sst, int[] attrSet, UUID[] uuidSet, RemoteDevice device, DiscoveryListener listener)
489 throws BluetoothStateException {
490 sst.searchServicesStartedCallback();
491 int[] handles;
492 try {
493 handles = runSearchServicesImpl(uuidSet, RemoteDeviceHelper.getAddress(device));
494 } catch (SearchServicesDeviceNotReachableException e) {
495 return DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE;
496 } catch (SearchServicesTerminatedException e) {
497 return DiscoveryListener.SERVICE_SEARCH_TERMINATED;
498 } catch (SearchServicesException e) {
499 return DiscoveryListener.SERVICE_SEARCH_ERROR;
500 }
501 if (handles == null) {
502 return DiscoveryListener.SERVICE_SEARCH_ERROR;
503 } else if (handles.length > 0) {
504 ServiceRecord[] records = new ServiceRecordImpl[handles.length];
505 int[] requiredAttrIDs = new int[] { BluetoothConsts.ServiceRecordHandle,
506 BluetoothConsts.ServiceClassIDList, BluetoothConsts.ServiceRecordState, BluetoothConsts.ServiceID,
507 BluetoothConsts.ProtocolDescriptorList };
508 boolean hasError = false;
509 for (int i = 0; i < handles.length; i++) {
510 records[i] = new ServiceRecordImpl(BluetoothStackMicrosoft.this, device, handles[i]);
511 try {
512 records[i].populateRecord(requiredAttrIDs);
513 if (attrSet != null) {
514 records[i].populateRecord(attrSet);
515 }
516 } catch (Exception e) {
517 DebugLog.debug("populateRecord error", e);
518 hasError = true;
519 }
520 if (sst.isTerminated()) {
521 return DiscoveryListener.SERVICE_SEARCH_TERMINATED;
522 }
523 }
524 listener.servicesDiscovered(sst.getTransID(), records);
525 if (hasError) {
526 return DiscoveryListener.SERVICE_SEARCH_ERROR;
527 } else {
528 return DiscoveryListener.SERVICE_SEARCH_COMPLETED;
529 }
530 } else {
531 return DiscoveryListener.SERVICE_SEARCH_NO_RECORDS;
532 }
533 }
534
535 };
536 return SearchServicesThread.startSearchServices(this, searchRunnable, attrSet, uuidSet, device, listener);
537 }
538
539 public boolean cancelServiceSearch(int transID) {
540 SearchServicesThread sst = SearchServicesThread.getServiceSearchThread(transID);
541 if (sst != null) {
542 return sst.setTerminated();
543 } else {
544 return false;
545 }
546 }
547
548 public boolean populateServicesRecordAttributeValues(ServiceRecordImpl serviceRecord, int[] attrIDs)
549 throws IOException {
550 if (attrIDs.length > ATTR_RETRIEVABLE_MAX) {
551 throw new IllegalArgumentException();
552 }
553
554
555
556 byte[] blob = getServiceAttributes(attrIDs, RemoteDeviceHelper.getAddress(serviceRecord.getHostDevice()),
557 (int) serviceRecord.getHandle());
558
559 if (blob.length > 0) {
560 try {
561 boolean anyRetrived = false;
562 DataElement element = (new SDPInputStream(new ByteArrayInputStream(blob))).readElement();
563 for (Enumeration e = (Enumeration) element.getValue(); e.hasMoreElements();) {
564 int attrID = (int) ((DataElement) e.nextElement()).getLong();
565 serviceRecord.populateAttributeValue(attrID, (DataElement) e.nextElement());
566 if (!anyRetrived) {
567 for (int i = 0; i < attrIDs.length; i++) {
568 if (attrIDs[i] == attrID) {
569 anyRetrived = true;
570 break;
571 }
572 }
573 }
574 }
575 return anyRetrived;
576 } catch (IOException e) {
577 throw e;
578 } catch (Throwable e) {
579 throw new IOException();
580 }
581 } else {
582 return false;
583 }
584 }
585
586
587
588
589 private native long socket(boolean authenticate, boolean encrypt) throws IOException;
590
591 private native long getsockaddress(long socket) throws IOException;
592
593 private native void storesockopt(long socket);
594
595 private native int getsockchannel(long socket) throws IOException;
596
597 private native void connect(long socket, long address, int channel, int retryUnreachable) throws IOException;
598
599 private native void bind(long socket) throws IOException;
600
601 private native void listen(long socket) throws IOException;
602
603 private native long accept(long socket) throws IOException;
604
605 private native int recvAvailable(long socket) throws IOException;
606
607 private native int recv(long socket) throws IOException;
608
609 private native int recv(long socket, byte[] b, int off, int len) throws IOException;
610
611 private native void send(long socket, int b) throws IOException;
612
613 private native void send(long socket, byte[] b, int off, int len) throws IOException;
614
615 private native void close(long socket) throws IOException;
616
617 private native String getpeername(long address) throws IOException;
618
619 private native long getpeeraddress(long socket) throws IOException;
620
621
622
623 private class ConnectThread extends Thread {
624
625 final Object event;
626
627 final long socket;
628
629 final BluetoothConnectionParams params;
630
631 final int retryUnreachable;
632
633 volatile IOException error;
634
635 volatile boolean success = false;
636
637 volatile boolean connecting = true;
638
639 ConnectThread(Object event, long socket, BluetoothConnectionParams params) {
640 super("ConnectThread-" + nextConnectThreadNum());
641 this.event = event;
642 this.socket = socket;
643 this.params = params;
644 retryUnreachable = BlueCoveImpl.getConfigProperty(
645 BlueCoveConfigProperties.PROPERTY_CONNECT_UNREACHABLE_RETRY, 2);
646
647 }
648
649 public void run() {
650 try {
651 connect(socket, params.address, params.channel, retryUnreachable);
652 success = true;
653 } catch (IOException e) {
654 error = e;
655 } finally {
656 connecting = false;
657 synchronized (event) {
658 event.notifyAll();
659 }
660 }
661 }
662 }
663
664
665
666
667
668
669
670 public long connectionRfOpenClientConnection(final BluetoothConnectionParams params) throws IOException {
671 final long socket = socket(params.authenticate, params.encrypt);
672
673
674 final Object event = new Object();
675 ConnectThread connectThread = new ConnectThread(event, socket, params);
676 UtilsJavaSE.threadSetDaemon(connectThread);
677
678 boolean timeoutHappend = false;
679
680 synchronized (event) {
681 connectThread.start();
682 while (connectThread.connecting) {
683 try {
684 if (params.timeouts) {
685 event.wait(params.timeout);
686 timeoutHappend = connectThread.connecting;
687 connectThread.interrupt();
688 break;
689 } else {
690 event.wait();
691 }
692 } catch (InterruptedException e) {
693 try {
694 close(socket);
695 } catch (Exception ignore) {
696 }
697 throw new InterruptedIOException();
698 }
699 }
700 }
701 if (!connectThread.success) {
702 try {
703 close(socket);
704 } catch (Exception ignore) {
705 }
706 }
707 if (connectThread.error != null) {
708 throw connectThread.error;
709 }
710
711 if (!connectThread.success) {
712 if (timeoutHappend) {
713 throw new BluetoothConnectionException(BluetoothConnectionException.TIMEOUT);
714 } else {
715 throw new BluetoothConnectionException(BluetoothConnectionException.FAILED_NOINFO);
716 }
717 }
718 return socket;
719 }
720
721 public void connectionRfCloseClientConnection(long handle) throws IOException {
722 close(handle);
723 }
724
725 public long rfServerOpen(BluetoothConnectionNotifierParams params, ServiceRecordImpl serviceRecord)
726 throws IOException {
727
728
729
730 long socket = socket(params.authenticate, params.encrypt);
731 boolean success = false;
732 try {
733
734 synchronized (this) {
735 bind(socket);
736 }
737 listen(socket);
738
739 int channel = getsockchannel(socket);
740 DebugLog.debug("service channel ", channel);
741
742 long serviceRecordHandle = socket;
743 serviceRecord.populateRFCOMMAttributes(serviceRecordHandle, channel, params.uuid, params.name, params.obex);
744
745
746
747
748 serviceRecord.setHandle(registerService(serviceRecord.toByteArray(), serviceRecord.deviceServiceClasses));
749
750 success = true;
751 } finally {
752 if (!success) {
753 try {
754 close(socket);
755 } catch (IOException e) {
756 DebugLog.debug("close on failure", e);
757 }
758 }
759 }
760 return socket;
761 }
762
763 public void rfServerClose(long handle, ServiceRecordImpl serviceRecord) throws IOException {
764 try {
765
766
767
768 close(handle);
769 } finally {
770
771
772
773 unregisterService(serviceRecord.getHandle());
774 }
775 }
776
777
778
779
780 private native long registerService(byte[] record, int classOfDevice) throws ServiceRegistrationException;
781
782
783
784
785 private native void unregisterService(long handle) throws ServiceRegistrationException;
786
787 public long rfServerAcceptAndOpenRfServerConnection(long handle) throws IOException {
788 return accept(handle);
789 }
790
791 public void rfServerUpdateServiceRecord(long handle, ServiceRecordImpl serviceRecord, boolean acceptAndOpen)
792 throws ServiceRegistrationException {
793 unregisterService(serviceRecord.getHandle());
794 byte[] blob;
795 try {
796 blob = serviceRecord.toByteArray();
797 } catch (IOException e) {
798 throw new ServiceRegistrationException(e.toString());
799 }
800 serviceRecord.setHandle(registerService(blob, serviceRecord.deviceServiceClasses));
801 DebugLog.debug("new serviceRecord", serviceRecord);
802 }
803
804 public void connectionRfCloseServerConnection(long handle) throws IOException {
805 connectionRfCloseClientConnection(handle);
806 }
807
808 public long getConnectionRfRemoteAddress(long handle) throws IOException {
809 return getpeeraddress(handle);
810 }
811
812 public int connectionRfRead(long handle) throws IOException {
813 return recv(handle);
814 }
815
816 public int connectionRfRead(long handle, byte[] b, int off, int len) throws IOException {
817 return recv(handle, b, off, len);
818 }
819
820 public int connectionRfReadAvailable(long handle) throws IOException {
821 return recvAvailable(handle);
822 }
823
824 public void connectionRfWrite(long handle, int b) throws IOException {
825 send(handle, b);
826 }
827
828 public void connectionRfWrite(long handle, byte[] b, int off, int len) throws IOException {
829 send(handle, b, off, len);
830 }
831
832 public void connectionRfFlush(long handle) throws IOException {
833
834 }
835
836 public int rfGetSecurityOpt(long handle, int expected) throws IOException {
837 return expected;
838 }
839
840
841
842
843
844
845 public boolean rfEncrypt(long address, long handle, boolean on) throws IOException {
846 return false;
847 }
848
849
850
851
852
853
854
855
856
857 public long l2OpenClientConnection(BluetoothConnectionParams params, int receiveMTU, int transmitMTU)
858 throws IOException {
859 throw new NotSupportedIOException(getStackID());
860 }
861
862
863
864
865
866
867 public void l2CloseClientConnection(long handle) throws IOException {
868 throw new NotSupportedIOException(getStackID());
869 }
870
871
872
873
874
875
876
877 public long l2ServerOpen(BluetoothConnectionNotifierParams params, int receiveMTU, int transmitMTU,
878 ServiceRecordImpl serviceRecord) throws IOException {
879 throw new NotSupportedIOException(getStackID());
880 }
881
882
883
884
885
886
887
888 public void l2ServerUpdateServiceRecord(long handle, ServiceRecordImpl serviceRecord, boolean acceptAndOpen)
889 throws ServiceRegistrationException {
890 throw new ServiceRegistrationException("Not Supported on" + getStackID());
891 }
892
893
894
895
896
897
898 public long l2ServerAcceptAndOpenServerConnection(long handle) throws IOException {
899 throw new NotSupportedIOException(getStackID());
900 }
901
902
903
904
905
906
907 public void l2CloseServerConnection(long handle) throws IOException {
908 throw new NotSupportedIOException(getStackID());
909 }
910
911
912
913
914
915
916 public void l2ServerClose(long handle, ServiceRecordImpl serviceRecord) throws IOException {
917 throw new NotSupportedIOException(getStackID());
918 }
919
920
921
922
923
924
925 public int l2GetSecurityOpt(long handle, int expected) throws IOException {
926 throw new NotSupportedIOException(getStackID());
927 }
928
929
930
931
932
933
934 public boolean l2Ready(long handle) throws IOException {
935 throw new NotSupportedIOException(getStackID());
936 }
937
938
939
940
941
942
943 public int l2Receive(long handle, byte[] inBuf) throws IOException {
944 throw new NotSupportedIOException(getStackID());
945 }
946
947
948
949
950
951
952 public void l2Send(long handle, byte[] data) throws IOException {
953 throw new NotSupportedIOException(getStackID());
954 }
955
956
957
958
959
960
961 public int l2GetReceiveMTU(long handle) throws IOException {
962 throw new NotSupportedIOException(getStackID());
963 }
964
965
966
967
968
969
970 public int l2GetTransmitMTU(long handle) throws IOException {
971 throw new NotSupportedIOException(getStackID());
972 }
973
974
975
976
977
978
979 public long l2RemoteAddress(long handle) throws IOException {
980 throw new NotSupportedIOException(getStackID());
981 }
982
983
984
985
986
987
988 public boolean l2Encrypt(long address, long handle, boolean on) throws IOException {
989 throw new NotSupportedIOException(getStackID());
990 }
991 }