/** * BlueCove - Java library for Bluetooth * Copyright (C) 2006-2009 Vlad Skarzhevskyy * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * @version $Id$ */ package com.intel.bluetooth; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InterruptedIOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.bluetooth.BluetoothConnectionException; import javax.bluetooth.BluetoothStateException; import javax.bluetooth.DataElement; import javax.bluetooth.DeviceClass; import javax.bluetooth.DiscoveryAgent; import javax.bluetooth.DiscoveryListener; import javax.bluetooth.RemoteDevice; import javax.bluetooth.ServiceRecord; import javax.bluetooth.ServiceRegistrationException; import javax.bluetooth.UUID; class BluetoothStackMicrosoft implements BluetoothStack { private static final int BTH_MODE_POWER_OFF = 1; private static final int BTH_MODE_CONNECTABLE = 2; private static final int BTH_MODE_DISCOVERABLE = 3; private static BluetoothStackMicrosoft singleInstance = null; private boolean peerInitialized = false; private boolean windowsCE; private long localBluetoothAddress = 0; private DiscoveryListener currentDeviceDiscoveryListener; private Thread limitedDiscoverableTimer; // TODO what is the real number for Attributes retrievable ? private final static int ATTR_RETRIEVABLE_MAX = 256; private Hashtable deviceDiscoveryDevices; private static int connectThreadNumber; private static synchronized int nextConnectThreadNum() { return connectThreadNumber++; } BluetoothStackMicrosoft() { } // ---------------------- Library initialization public String getStackID() { return BlueCoveImpl.STACK_WINSOCK; } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#isNativeCodeLoaded() */ public native boolean isNativeCodeLoaded(); /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#requireNativeLibraries() */ public LibraryInformation[] requireNativeLibraries() { return LibraryInformation.library(BlueCoveImpl.NATIVE_LIB_MS); } public String toString() { return getStackID(); } public native int getLibraryVersion(); public native int detectBluetoothStack(); public native void enableNativeDebug(Class nativeDebugCallback, boolean on); private static native int initializationStatus() throws IOException; private native void uninitialize(); private native boolean isWindowsCE(); public void initialize() throws BluetoothStateException { if (singleInstance != null) { throw new BluetoothStateException("Only one instance of " + getStackID() + " stack supported"); } try { int status = initializationStatus(); DebugLog.debug("initializationStatus", status); if (status == 1) { peerInitialized = true; } windowsCE = isWindowsCE(); singleInstance = this; } catch (BluetoothStateException e) { throw e; } catch (IOException e) { DebugLog.fatal("initialization", e); throw new BluetoothStateException(e.getMessage()); } } public void destroy() { if (singleInstance != this) { throw new RuntimeException("Destroy invalid instance"); } if (peerInitialized) { peerInitialized = false; uninitialize(); } cancelLimitedDiscoverableTimer(); singleInstance = null; } private void initialized() throws BluetoothStateException { if (!peerInitialized) { throw new BluetoothStateException("Bluetooth system is unavailable"); } } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#getFeatureSet() */ public int getFeatureSet() { return FEATURE_SERVICE_ATTRIBUTES | (windowsCE ? 0 : FEATURE_SET_DEVICE_SERVICE_CLASSES); } // ---------------------- LocalDevice private native int getDeviceClass(long address); private native void setDiscoverable(boolean on) throws BluetoothStateException; private native int getBluetoothRadioMode(); private native String getradioname(long address); private native int getDeviceVersion(long address); private native int getDeviceManufacturer(long address); public String getLocalDeviceBluetoothAddress() { try { long socket = socket(false, false); bind(socket); localBluetoothAddress = getsockaddress(socket); String address = RemoteDeviceHelper.getBluetoothAddress(localBluetoothAddress); storesockopt(socket); close(socket); return address; } catch (IOException e) { DebugLog.error("get local bluetoothAddress", e); return "000000000000"; } } public String getLocalDeviceName() { if (localBluetoothAddress == 0) { getLocalDeviceBluetoothAddress(); } return getradioname(localBluetoothAddress); } public String getRemoteDeviceFriendlyName(long address) throws IOException { return getpeername(address); } public DeviceClass getLocalDeviceClass() { return new DeviceClass(getDeviceClass(localBluetoothAddress)); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#setLocalDeviceServiceClasses(int) */ public void setLocalDeviceServiceClasses(int classOfDevice) { // Done in rfServerUpdateServiceRecord } private void cancelLimitedDiscoverableTimer() { if (limitedDiscoverableTimer != null) { limitedDiscoverableTimer.interrupt(); limitedDiscoverableTimer = null; } } public boolean setLocalDeviceDiscoverable(int mode) throws BluetoothStateException { switch (mode) { case DiscoveryAgent.NOT_DISCOVERABLE: cancelLimitedDiscoverableTimer(); DebugLog.debug("setDiscoverable(false)"); setDiscoverable(false); return (DiscoveryAgent.NOT_DISCOVERABLE == getLocalDeviceDiscoverable()); case DiscoveryAgent.GIAC: cancelLimitedDiscoverableTimer(); DebugLog.debug("setDiscoverable(true)"); setDiscoverable(true); return (DiscoveryAgent.GIAC == getLocalDeviceDiscoverable()); case DiscoveryAgent.LIAC: cancelLimitedDiscoverableTimer(); DebugLog.debug("setDiscoverable(LIAC)"); setDiscoverable(true); if (!(DiscoveryAgent.GIAC == getLocalDeviceDiscoverable())) { return false; } // Timer to turn it off limitedDiscoverableTimer = Utils.schedule(60 * 1000, new Runnable() { public void run() { try { setDiscoverable(false); } catch (BluetoothStateException e) { DebugLog.debug("error setDiscoverable", e); } finally { limitedDiscoverableTimer = null; } } }); return true; } return false; } public boolean isLocalDevicePowerOn() { int mode = getBluetoothRadioMode(); if (mode == BTH_MODE_POWER_OFF) { return false; } return ((mode == BTH_MODE_CONNECTABLE) || (mode == BTH_MODE_DISCOVERABLE)); } public int getLocalDeviceDiscoverable() { int mode = getBluetoothRadioMode(); if (mode == BTH_MODE_DISCOVERABLE) { if (limitedDiscoverableTimer != null) { DebugLog.debug("Discoverable = LIAC"); return DiscoveryAgent.LIAC; } else { DebugLog.debug("Discoverable = GIAC"); return DiscoveryAgent.GIAC; } } else { DebugLog.debug("Discoverable = NOT_DISCOVERABLE"); return DiscoveryAgent.NOT_DISCOVERABLE; } } public String getLocalDeviceProperty(String property) { if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_DEVICES_MAX.equals(property)) { return "7"; } if (BluetoothConsts.PROPERTY_BLUETOOTH_SD_TRANS_MAX.equals(property)) { return "7"; } if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_INQUIRY_SCAN.equals(property)) { return BlueCoveImpl.TRUE; } if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_PAGE_SCAN.equals(property)) { return BlueCoveImpl.TRUE; } if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_INQUIRY.equals(property)) { return BlueCoveImpl.TRUE; } if (BluetoothConsts.PROPERTY_BLUETOOTH_CONNECTED_PAGE.equals(property)) { return BlueCoveImpl.TRUE; } if (BluetoothConsts.PROPERTY_BLUETOOTH_SD_ATTR_RETRIEVABLE_MAX.equals(property)) { return String.valueOf(ATTR_RETRIEVABLE_MAX); } if (BluetoothConsts.PROPERTY_BLUETOOTH_MASTER_SWITCH.equals(property)) { return BlueCoveImpl.FALSE; } if (BluetoothConsts.PROPERTY_BLUETOOTH_L2CAP_RECEIVEMTU_MAX.equals(property)) { return "0"; } if (BlueCoveLocalDeviceProperties.LOCAL_DEVICE_RADIO_VERSION.equals(property)) { return String.valueOf(getDeviceVersion(localBluetoothAddress)); } if (BlueCoveLocalDeviceProperties.LOCAL_DEVICE_RADIO_MANUFACTURER.equals(property)) { return String.valueOf(getDeviceManufacturer(localBluetoothAddress)); } return null; } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#isCurrentThreadInterruptedCallback() */ public boolean isCurrentThreadInterruptedCallback() { return UtilsJavaSE.isCurrentThreadInterrupted(); } private native boolean retrieveDevicesImpl(int option, RetrieveDevicesCallback retrieveDevicesCallback); public RemoteDevice[] retrieveDevices(int option) { if (windowsCE) { return null; } final Vector devices = new Vector(); RetrieveDevicesCallback retrieveDevicesCallback = new RetrieveDevicesCallback() { public void deviceFoundCallback(long deviceAddr, int deviceClass, String deviceName, boolean paired) { DebugLog.debug("device found", deviceAddr); RemoteDevice remoteDevice = RemoteDeviceHelper.createRemoteDevice(BluetoothStackMicrosoft.this, deviceAddr, deviceName, paired); devices.add(remoteDevice); } }; if (retrieveDevicesImpl(option, retrieveDevicesCallback)) { return RemoteDeviceHelper.remoteDeviceListToArray(devices); } else { return null; } } private native boolean isRemoteDeviceTrustedImpl(long address); public Boolean isRemoteDeviceTrusted(long address) { if (windowsCE) { return null; } return new Boolean(isRemoteDeviceTrustedImpl(address)); } private native boolean isRemoteDeviceAuthenticatedImpl(long address); public Boolean isRemoteDeviceAuthenticated(long address) { if (windowsCE) { return null; } return new Boolean(isRemoteDeviceAuthenticatedImpl(address)); } private native boolean authenticateRemoteDeviceImpl(long address, String passkey) throws IOException; public boolean authenticateRemoteDevice(long address) throws IOException { return authenticateRemoteDeviceImpl(address, null); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#authenticateRemoteDevice(long, java.lang.String) */ public boolean authenticateRemoteDevice(long address, String passkey) throws IOException { return authenticateRemoteDeviceImpl(address, passkey); } private native void removeAuthenticationWithRemoteDeviceImpl(long address) throws IOException; /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#removeAuthenticationWithRemoteDevice (long) */ public void removeAuthenticationWithRemoteDevice(long address) throws IOException { removeAuthenticationWithRemoteDeviceImpl(address); } // ---------------------- Device Inquiry /* * perform synchronous inquiry */ private native int runDeviceInquiryImpl(DeviceInquiryRunnable inquiryRunnable, DeviceInquiryThread inquiryThread, int accessCode, int duration, DiscoveryListener listener) throws BluetoothStateException; public boolean startInquiry(int accessCode, DiscoveryListener listener) throws BluetoothStateException { initialized(); if (currentDeviceDiscoveryListener != null) { throw new BluetoothStateException("Another inquiry already running"); } currentDeviceDiscoveryListener = listener; DeviceInquiryRunnable inquiryRunnable = new DeviceInquiryRunnable() { public int runDeviceInquiry(DeviceInquiryThread inquiryThread, int accessCode, DiscoveryListener listener) throws BluetoothStateException { try { deviceDiscoveryDevices = new Hashtable(); int discType = runDeviceInquiryImpl(this, inquiryThread, accessCode, DeviceInquiryThread .getConfigDeviceInquiryDuration(), listener); if (discType == DiscoveryListener.INQUIRY_COMPLETED) { for (Enumeration en = deviceDiscoveryDevices.keys(); en.hasMoreElements();) { RemoteDevice remoteDevice = (RemoteDevice) en.nextElement(); DeviceClass deviceClass = (DeviceClass) deviceDiscoveryDevices.get(remoteDevice); listener.deviceDiscovered(remoteDevice, deviceClass); // If cancelInquiry has been called if (currentDeviceDiscoveryListener == null) { return DiscoveryListener.INQUIRY_TERMINATED; } } } return discType; } finally { deviceDiscoveryDevices = null; currentDeviceDiscoveryListener = null; } } /** * This is called when all device discoved by stack. To avoid problems with getpeername we will postpone the calls * to User deviceDiscovered function until runDeviceInquiry is finished. */ public void deviceDiscoveredCallback(DiscoveryListener listener, long deviceAddr, int deviceClass, String deviceName, boolean paired) { RemoteDevice remoteDevice = RemoteDeviceHelper.createRemoteDevice(BluetoothStackMicrosoft.this, deviceAddr, deviceName, paired); if ((currentDeviceDiscoveryListener == null) || (deviceDiscoveryDevices == null) || (currentDeviceDiscoveryListener != listener)) { return; } DeviceClass cod = new DeviceClass(deviceClass); DebugLog.debug("deviceDiscoveredCallback address", remoteDevice.getBluetoothAddress()); DebugLog.debug("deviceDiscoveredCallback deviceClass", cod); deviceDiscoveryDevices.put(remoteDevice, cod); } }; return DeviceInquiryThread.startInquiry(this, inquiryRunnable, accessCode, listener); } /* * cancel current inquiry (if any) */ private native boolean cancelInquiry(); public boolean cancelInquiry(DiscoveryListener listener) { if (currentDeviceDiscoveryListener != listener) { return false; } // no further deviceDiscovered() events will occur for this inquiry currentDeviceDiscoveryListener = null; return cancelInquiry(); } // ---------------------- Service search /* * perform synchronous service discovery */ private native int[] runSearchServicesImpl(UUID[] uuidSet, long address) throws SearchServicesException; /* * get service attributes */ public native byte[] getServiceAttributes(int[] attrIDs, long address, int handle) throws IOException; public int searchServices(int[] attrSet, UUID[] uuidSet, RemoteDevice device, DiscoveryListener listener) throws BluetoothStateException { SearchServicesRunnable searchRunnable = new SearchServicesRunnable() { public int runSearchServices(SearchServicesThread sst, int[] attrSet, UUID[] uuidSet, RemoteDevice device, DiscoveryListener listener) throws BluetoothStateException { sst.searchServicesStartedCallback(); int[] handles; try { handles = runSearchServicesImpl(uuidSet, RemoteDeviceHelper.getAddress(device)); } catch (SearchServicesDeviceNotReachableException e) { return DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE; } catch (SearchServicesTerminatedException e) { return DiscoveryListener.SERVICE_SEARCH_TERMINATED; } catch (SearchServicesException e) { return DiscoveryListener.SERVICE_SEARCH_ERROR; } if (handles == null) { return DiscoveryListener.SERVICE_SEARCH_ERROR; } else if (handles.length > 0) { ServiceRecord[] records = new ServiceRecordImpl[handles.length]; int[] requiredAttrIDs = new int[] { BluetoothConsts.ServiceRecordHandle, BluetoothConsts.ServiceClassIDList, BluetoothConsts.ServiceRecordState, BluetoothConsts.ServiceID, BluetoothConsts.ProtocolDescriptorList }; boolean hasError = false; for (int i = 0; i < handles.length; i++) { records[i] = new ServiceRecordImpl(BluetoothStackMicrosoft.this, device, handles[i]); try { records[i].populateRecord(requiredAttrIDs); if (attrSet != null) { records[i].populateRecord(attrSet); } } catch (Exception e) { DebugLog.debug("populateRecord error", e); hasError = true; } if (sst.isTerminated()) { return DiscoveryListener.SERVICE_SEARCH_TERMINATED; } } listener.servicesDiscovered(sst.getTransID(), records); if (hasError) { return DiscoveryListener.SERVICE_SEARCH_ERROR; } else { return DiscoveryListener.SERVICE_SEARCH_COMPLETED; } } else { return DiscoveryListener.SERVICE_SEARCH_NO_RECORDS; } } }; return SearchServicesThread.startSearchServices(this, searchRunnable, attrSet, uuidSet, device, listener); } public boolean cancelServiceSearch(int transID) { SearchServicesThread sst = SearchServicesThread.getServiceSearchThread(transID); if (sst != null) { return sst.setTerminated(); } else { return false; } } public boolean populateServicesRecordAttributeValues(ServiceRecordImpl serviceRecord, int[] attrIDs) throws IOException { if (attrIDs.length > ATTR_RETRIEVABLE_MAX) { throw new IllegalArgumentException(); } /* * retrieve SDP blob */ byte[] blob = getServiceAttributes(attrIDs, RemoteDeviceHelper.getAddress(serviceRecord.getHostDevice()), (int) serviceRecord.getHandle()); if (blob.length > 0) { try { boolean anyRetrived = false; DataElement element = (new SDPInputStream(new ByteArrayInputStream(blob))).readElement(); for (Enumeration e = (Enumeration) element.getValue(); e.hasMoreElements();) { int attrID = (int) ((DataElement) e.nextElement()).getLong(); serviceRecord.populateAttributeValue(attrID, (DataElement) e.nextElement()); if (!anyRetrived) { for (int i = 0; i < attrIDs.length; i++) { if (attrIDs[i] == attrID) { anyRetrived = true; break; } } } } return anyRetrived; } catch (IOException e) { throw e; } catch (Throwable e) { throw new IOException(); } } else { return false; } } /* * socket operations */ private native long socket(boolean authenticate, boolean encrypt) throws IOException; private native long getsockaddress(long socket) throws IOException; private native void storesockopt(long socket); private native int getsockchannel(long socket) throws IOException; private native void connect(long socket, long address, int channel, int retryUnreachable) throws IOException; private native void bind(long socket) throws IOException; private native void listen(long socket) throws IOException; private native long accept(long socket) throws IOException; private native int recvAvailable(long socket) throws IOException; private native int recv(long socket) throws IOException; private native int recv(long socket, byte[] b, int off, int len) throws IOException; private native void send(long socket, int b) throws IOException; private native void send(long socket, byte[] b, int off, int len) throws IOException; private native void close(long socket) throws IOException; private native String getpeername(long address) throws IOException; private native long getpeeraddress(long socket) throws IOException; // ---------------------- Client RFCOMM connections private class ConnectThread extends Thread { final Object event; final long socket; final BluetoothConnectionParams params; final int retryUnreachable; volatile IOException error; volatile boolean success = false; volatile boolean connecting = true; ConnectThread(Object event, long socket, BluetoothConnectionParams params) { super("ConnectThread-" + nextConnectThreadNum()); this.event = event; this.socket = socket; this.params = params; retryUnreachable = BlueCoveImpl.getConfigProperty( BlueCoveConfigProperties.PROPERTY_CONNECT_UNREACHABLE_RETRY, 2); } public void run() { try { connect(socket, params.address, params.channel, retryUnreachable); success = true; } catch (IOException e) { error = e; } finally { connecting = false; synchronized (event) { event.notifyAll(); } } } } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2OpenClientConnection(com.intel.bluetooth .BluetoothConnectionParams, * int, int) */ public long connectionRfOpenClientConnection(final BluetoothConnectionParams params) throws IOException { final long socket = socket(params.authenticate, params.encrypt); // Allow to interrupt connection thread final Object event = new Object(); ConnectThread connectThread = new ConnectThread(event, socket, params); UtilsJavaSE.threadSetDaemon(connectThread); boolean timeoutHappend = false; synchronized (event) { connectThread.start(); while (connectThread.connecting) { try { if (params.timeouts) { event.wait(params.timeout); timeoutHappend = connectThread.connecting; connectThread.interrupt(); break; } else { event.wait(); } } catch (InterruptedException e) { try { close(socket); } catch (Exception ignore) { } throw new InterruptedIOException(); } } } if (!connectThread.success) { try { close(socket); } catch (Exception ignore) { } } if (connectThread.error != null) { throw connectThread.error; } if (!connectThread.success) { if (timeoutHappend) { throw new BluetoothConnectionException(BluetoothConnectionException.TIMEOUT); } else { throw new BluetoothConnectionException(BluetoothConnectionException.FAILED_NOINFO); } } return socket; } public void connectionRfCloseClientConnection(long handle) throws IOException { close(handle); } public long rfServerOpen(BluetoothConnectionNotifierParams params, ServiceRecordImpl serviceRecord) throws IOException { /* * open socket */ long socket = socket(params.authenticate, params.encrypt); boolean success = false; try { synchronized (this) { bind(socket); } listen(socket); int channel = getsockchannel(socket); DebugLog.debug("service channel ", channel); long serviceRecordHandle = socket; serviceRecord.populateRFCOMMAttributes(serviceRecordHandle, channel, params.uuid, params.name, params.obex); /* * register service */ serviceRecord.setHandle(registerService(serviceRecord.toByteArray(), serviceRecord.deviceServiceClasses)); success = true; } finally { if (!success) { try { close(socket); } catch (IOException e) { DebugLog.debug("close on failure", e); } } } return socket; } public void rfServerClose(long handle, ServiceRecordImpl serviceRecord) throws IOException { try { /* * close socket */ close(handle); } finally { /* * unregister service */ unregisterService(serviceRecord.getHandle()); } } /* * register service */ private native long registerService(byte[] record, int classOfDevice) throws ServiceRegistrationException; /* * unregister service */ private native void unregisterService(long handle) throws ServiceRegistrationException; public long rfServerAcceptAndOpenRfServerConnection(long handle) throws IOException { return accept(handle); } public void rfServerUpdateServiceRecord(long handle, ServiceRecordImpl serviceRecord, boolean acceptAndOpen) throws ServiceRegistrationException { unregisterService(serviceRecord.getHandle()); byte[] blob; try { blob = serviceRecord.toByteArray(); } catch (IOException e) { throw new ServiceRegistrationException(e.toString()); } serviceRecord.setHandle(registerService(blob, serviceRecord.deviceServiceClasses)); DebugLog.debug("new serviceRecord", serviceRecord); } public void connectionRfCloseServerConnection(long handle) throws IOException { connectionRfCloseClientConnection(handle); } public long getConnectionRfRemoteAddress(long handle) throws IOException { return getpeeraddress(handle); } public int connectionRfRead(long handle) throws IOException { return recv(handle); } public int connectionRfRead(long handle, byte[] b, int off, int len) throws IOException { return recv(handle, b, off, len); } public int connectionRfReadAvailable(long handle) throws IOException { return recvAvailable(handle); } public void connectionRfWrite(long handle, int b) throws IOException { send(handle, b); } public void connectionRfWrite(long handle, byte[] b, int off, int len) throws IOException { send(handle, b, off, len); } public void connectionRfFlush(long handle) throws IOException { // TODO are there any flush } public int rfGetSecurityOpt(long handle, int expected) throws IOException { return expected; } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2Encrypt(long,long,boolean) */ public boolean rfEncrypt(long address, long handle, boolean on) throws IOException { return false; } // ---------------------- Client and Server L2CAP connections /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2OpenClientConnection(com.intel.bluetooth .BluetoothConnectionParams, * int, int) */ public long l2OpenClientConnection(BluetoothConnectionParams params, int receiveMTU, int transmitMTU) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2CloseClientConnection(long) */ public void l2CloseClientConnection(long handle) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @seecom.intel.bluetooth.BluetoothStack#l2ServerOpen(com.intel.bluetooth. BluetoothConnectionNotifierParams, int, * int, com.intel.bluetooth.ServiceRecordImpl) */ public long l2ServerOpen(BluetoothConnectionNotifierParams params, int receiveMTU, int transmitMTU, ServiceRecordImpl serviceRecord) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2ServerUpdateServiceRecord(long, com.intel.bluetooth.ServiceRecordImpl, * boolean) */ public void l2ServerUpdateServiceRecord(long handle, ServiceRecordImpl serviceRecord, boolean acceptAndOpen) throws ServiceRegistrationException { throw new ServiceRegistrationException("Not Supported on" + getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2ServerAcceptAndOpenServerConnection (long) */ public long l2ServerAcceptAndOpenServerConnection(long handle) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2CloseServerConnection(long) */ public void l2CloseServerConnection(long handle) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2ServerClose(long, com.intel.bluetooth.ServiceRecordImpl) */ public void l2ServerClose(long handle, ServiceRecordImpl serviceRecord) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2GetSecurityOpt(long, int) */ public int l2GetSecurityOpt(long handle, int expected) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2Ready(long) */ public boolean l2Ready(long handle) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2receive(long, byte[]) */ public int l2Receive(long handle, byte[] inBuf) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2send(long, byte[]) */ public void l2Send(long handle, byte[] data, int transmitMTU) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2GetReceiveMTU(long) */ public int l2GetReceiveMTU(long handle) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2GetTransmitMTU(long) */ public int l2GetTransmitMTU(long handle) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2RemoteAddress(long) */ public long l2RemoteAddress(long handle) throws IOException { throw new NotSupportedIOException(getStackID()); } /* * (non-Javadoc) * * @see com.intel.bluetooth.BluetoothStack#l2Encrypt(long,long,boolean) */ public boolean l2Encrypt(long address, long handle, boolean on) throws IOException { throw new NotSupportedIOException(getStackID()); } }