All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intel.bluetooth.BluetoothStackBlueZ Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
/**
 * BlueCove BlueZ module - Java library for Bluetooth on Linux
 *  Copyright (C) 2008 Mina Shokry
 *  Copyright (C) 2007-2008 Vlad Skarzhevskyy
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see .
 *
 * @version $Id: BluetoothStackBlueZ.java 2396 2008-08-12 04:33:53Z skarzhevskyy $
 */
package com.intel.bluetooth;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DataElement;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.ServiceRegistrationException;
import javax.bluetooth.UUID;

/**
 * Property "bluecove.deviceID" or "bluecove.deviceAddress" can be used to
 * select Local Bluetooth device.
 * 
 */
class BluetoothStackBlueZ implements BluetoothStack, DeviceInquiryRunnable, SearchServicesRunnable {

	public static final String NATIVE_BLUECOVE_LIB_BLUEZ = "bluecove";

	static final int NATIVE_LIBRARY_VERSION = BlueCoveImpl.nativeLibraryVersionExpected;

	// TODO what is the real number for Attributes retrievable ?
	private final static int ATTR_RETRIEVABLE_MAX = 256;

	private final static int LISTEN_BACKLOG_RFCOMM = 4;

	private final static int LISTEN_BACKLOG_L2CAP = 4;

	private final static Vector devicesUsed = new Vector();

	private int deviceID = -1;

	private int deviceDescriptor;

	private long localDeviceBTAddress;

	private long sdpSesion;

	private int registeredServicesCount = 0;

	private Hashtable/*  */propertiesMap;

	private DiscoveryListener discoveryListener;

	// Prevent the device from been discovered twice
	private Vector/*  */discoveredDevices;

	private boolean deviceInquiryCanceled = false;

	BluetoothStackBlueZ() {
	}

	// --- Library initialization

	public String getStackID() {
		return BlueCoveImpl.STACK_BLUEZ;
	}

	public String toString() {
		if (deviceID >= 0) {
			return getStackID() + ":" + deviceID;
		} else {
			return getStackID();
		}
	}

	/*
	 * (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(NATIVE_BLUECOVE_LIB_BLUEZ);
	}

	public native int getLibraryVersionNative();

	public int getLibraryVersion() throws BluetoothStateException {
		int version = getLibraryVersionNative();
		if (version != NATIVE_LIBRARY_VERSION) {
			DebugLog.fatal("BlueCove native library version mismatch " + version + " expected "
					+ NATIVE_LIBRARY_VERSION);
			throw new BluetoothStateException("BlueCove native library version mismatch");
		}
		return version;
	}

	public int detectBluetoothStack() {
		return BlueCoveImpl.BLUECOVE_STACK_DETECT_BLUEZ;
	}

	private native int nativeGetDeviceID(int id, long findLocalDeviceBTAddress) throws BluetoothStateException;

	private native int nativeOpenDevice(int deviceID) throws BluetoothStateException;

	public void initialize() throws BluetoothStateException {
		int findID = -1;
		long findLocalDeviceBTAddress = -1;
		String deviceIDStr = BlueCoveImpl.getConfigProperty("bluecove.deviceID");
		if (deviceIDStr != null) {
			findID = Integer.parseInt(deviceIDStr);
		}
		String deviceAddressStr = BlueCoveImpl.getConfigProperty("bluecove.deviceAddress");
		if (deviceAddressStr != null) {
			findLocalDeviceBTAddress = Long.parseLong(deviceAddressStr, 16);
		}
		int foundDeviceID = nativeGetDeviceID(findID, findLocalDeviceBTAddress);
		if (devicesUsed.contains(new Long(foundDeviceID))) {
			throw new BluetoothStateException("LocalDevice " + foundDeviceID + " alredy in use");
		}

		this.deviceID = foundDeviceID;
		DebugLog.debug("localDeviceID", deviceID);
		deviceDescriptor = nativeOpenDevice(deviceID);
		localDeviceBTAddress = getLocalDeviceBluetoothAddressImpl(deviceDescriptor);
		propertiesMap = new Hashtable/*  */();
		final String TRUE = "true";
		final String FALSE = "false";
		propertiesMap.put("bluetooth.connected.devices.max", "7");
		propertiesMap.put("bluetooth.sd.trans.max", "7");
		propertiesMap.put("bluetooth.connected.inquiry.scan", TRUE);
		propertiesMap.put("bluetooth.connected.page.scan", TRUE);
		propertiesMap.put("bluetooth.connected.inquiry", TRUE);
		propertiesMap.put("bluetooth.connected.page", TRUE);
		propertiesMap.put("bluetooth.sd.attr.retrievable.max", String.valueOf(ATTR_RETRIEVABLE_MAX));
		propertiesMap.put("bluetooth.master.switch", FALSE);
		propertiesMap.put("bluetooth.l2cap.receiveMTU.max", "65535");
		// propertiesMap.put("bluecove.radio.version", );
		// propertiesMap.put("bluecove.radio.manufacturer", );
		// propertiesMap.put("bluecove.stack.version", );
		propertiesMap.put(BlueCoveLocalDeviceProperties.LOCAL_DEVICE_PROPERTY_DEVICE_ID, String.valueOf(deviceID));

		devicesUsed.addElement(new Long(deviceID));
	}

	private native void nativeCloseDevice(int deviceDescriptor);

	public void destroy() {
		if (sdpSesion != 0) {
			try {
				long s = sdpSesion;
				sdpSesion = 0;
				closeSDPSessionImpl(s, true);
			} catch (ServiceRegistrationException ignore) {
			}
		}
		nativeCloseDevice(deviceDescriptor);
		if (deviceID >= 0) {
			devicesUsed.removeElement(new Long(deviceID));
			deviceID = -1;
		}
	}

	public native void enableNativeDebug(Class nativeDebugCallback, boolean on);

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.intel.bluetooth.BluetoothStack#isCurrentThreadInterruptedCallback()
	 */
	public boolean isCurrentThreadInterruptedCallback() {
		return UtilsJavaSE.isCurrentThreadInterrupted();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#getFeatureSet()
	 */
	public int getFeatureSet() {
		return FEATURE_SERVICE_ATTRIBUTES | FEATURE_L2CAP;
	}

	private native int[] getLocalDevicesID();

	// --- LocalDevice

	private native long getLocalDeviceBluetoothAddressImpl(int deviceDescriptor) throws BluetoothStateException;

	public String getLocalDeviceBluetoothAddress() throws BluetoothStateException {
		return RemoteDeviceHelper.getBluetoothAddress(getLocalDeviceBluetoothAddressImpl(deviceDescriptor));
	}

	private native int nativeGetDeviceClass(int deviceDescriptor);

	public DeviceClass getLocalDeviceClass() {
		int record = nativeGetDeviceClass(deviceDescriptor);
		if (record == 0xff000000) {
			// could not be determined
			return null;
		}
		return new DeviceClass(record);
	}

	private native String nativeGetDeviceName(int deviceDescriptor);

	public String getLocalDeviceName() {
		return nativeGetDeviceName(deviceDescriptor);
	}

	public boolean isLocalDevicePowerOn() {
		// Have no idea how turn on and off device on BlueZ, as well to how to
		// detect this condition.
		return true;
	}

	public String getLocalDeviceProperty(String property) {
		if (BlueCoveLocalDeviceProperties.LOCAL_DEVICE_DEVICES_LIST.equals(property)) {
			int[] ids = getLocalDevicesID();
			StringBuffer b = new StringBuffer();
			if (ids != null) {
				for (int i = 0; i < ids.length; i++) {
					if (i != 0) {
						b.append(',');
					}
					b.append(String.valueOf(ids[i]));
				}
			}
			return b.toString();
		}
		// Some Hack and testing functions, not documented
		if (property.startsWith("bluecove.nativeFunction:")) {
			String functionDescr = property.substring(property.indexOf(':') + 1, property.length());
			int paramIdx = functionDescr.indexOf(':');
			if (paramIdx == -1) {
				throw new RuntimeException("Invalid native function " + functionDescr + "; arguments expected");
			}
			String function = functionDescr.substring(0, paramIdx);
			long address = RemoteDeviceHelper.getAddress(functionDescr.substring(function.length() + 1, functionDescr
					.length()));
			if ("getRemoteDeviceVersionInfo".equals(function)) {
				return getRemoteDeviceVersionInfo(address);
			} else if ("getRemoteDeviceRSSI".equals(function)) {
				return String.valueOf(getRemoteDeviceRSSI(address));
			}
			return null;
		}
		return (String) propertiesMap.get(property);
	}

	private native int nativeGetLocalDeviceDiscoverable(int deviceDescriptor);

	public int getLocalDeviceDiscoverable() {
		return nativeGetLocalDeviceDiscoverable(deviceDescriptor);
	}

	private native int nativeSetLocalDeviceDiscoverable(int deviceDescriptor, int mode);

	/**
	 * From JSR-82 docs
	 * 
	 * @return true if the request succeeded, otherwise
	 *         false if the request failed because the BCC denied
	 *         the request; false if the Bluetooth system does not
	 *         support the access mode specified in mode
	 */
	public boolean setLocalDeviceDiscoverable(int mode) throws BluetoothStateException {
		int curentMode = getLocalDeviceDiscoverable();
		if (curentMode == mode) {
			return true;
		} else {
			int error = nativeSetLocalDeviceDiscoverable(deviceDescriptor, mode);
			if (error != 0) {
				DebugLog.error("Unable to change discovery mode. It may be because you aren't root; " + error);
				return false;
			}
			return true;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#setLocalDeviceServiceClasses(int)
	 */
	public void setLocalDeviceServiceClasses(int classOfDevice) {
		throw new NotSupportedRuntimeException(getStackID());
	}

	// --- Remote Device authentication

	public boolean authenticateRemoteDevice(long address) throws IOException {
		return false;
	}

	// --- Some testing functions accessible by LocalDevice.getProperty

	private native String getRemoteDeviceVersionInfoImpl(int deviceDescriptor, long address);

	public String getRemoteDeviceVersionInfo(long address) {
		return getRemoteDeviceVersionInfoImpl(this.deviceDescriptor, address);
	}

	private native int getRemoteDeviceRSSIImpl(int deviceDescriptor, long address);

	public int getRemoteDeviceRSSI(long address) {
		return getRemoteDeviceRSSIImpl(this.deviceDescriptor, address);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#authenticateRemoteDevice(long,
	 * java.lang.String)
	 */
	public boolean authenticateRemoteDevice(long address, String passkey) throws IOException {
		return false;
	}

	// --- Device Inquiry

	public boolean startInquiry(int accessCode, DiscoveryListener listener) throws BluetoothStateException {
		if (discoveryListener != null) {
			throw new BluetoothStateException("Another inquiry already running");
		}
		discoveryListener = listener;
		discoveredDevices = new Vector();
		deviceInquiryCanceled = false;
		return DeviceInquiryThread.startInquiry(this, this, accessCode, listener);
	}

	private native int runDeviceInquiryImpl(DeviceInquiryThread startedNotify, int deviceID, int deviceDescriptor,
			int accessCode, int inquiryLength, int maxResponses, DiscoveryListener listener)
			throws BluetoothStateException;

	public int runDeviceInquiry(DeviceInquiryThread startedNotify, int accessCode, DiscoveryListener listener)
			throws BluetoothStateException {
		try {
			int discType = runDeviceInquiryImpl(startedNotify, deviceID, deviceDescriptor, accessCode, 8, 20, listener);
			if (deviceInquiryCanceled) {
				return DiscoveryListener.INQUIRY_TERMINATED;
			}
			return discType;
		} finally {
			discoveryListener = null;
			discoveredDevices = null;
		}
	}

	public void deviceDiscoveredCallback(DiscoveryListener listener, long deviceAddr, int deviceClass,
			String deviceName, boolean paired) {
		RemoteDevice remoteDevice = RemoteDeviceHelper.createRemoteDevice(this, deviceAddr, deviceName, paired);
		if (deviceInquiryCanceled || (discoveryListener == null) || (discoveredDevices == null)
				|| (discoveredDevices.contains(remoteDevice))) {
			return;
		}
		discoveredDevices.addElement(remoteDevice);
		DeviceClass cod = new DeviceClass(deviceClass);
		DebugLog.debug("deviceDiscoveredCallback address", remoteDevice.getBluetoothAddress());
		DebugLog.debug("deviceDiscoveredCallback deviceClass", cod);
		listener.deviceDiscovered(remoteDevice, cod);
	}

	private native boolean deviceInquiryCancelImpl(int deviceDescriptor);

	public boolean cancelInquiry(DiscoveryListener listener) {
		if (discoveryListener != null && discoveryListener == listener) {
			deviceInquiryCanceled = true;
			return deviceInquiryCancelImpl(deviceDescriptor);
		}
		return false;
	}

	private native String getRemoteDeviceFriendlyNameImpl(int deviceDescriptor, long remoteAddress) throws IOException;

	public String getRemoteDeviceFriendlyName(long address) throws IOException {
		return getRemoteDeviceFriendlyNameImpl(deviceDescriptor, address);
	}

	// --- Service search

	public int searchServices(int[] attrSet, UUID[] uuidSet, RemoteDevice device, DiscoveryListener listener)
			throws BluetoothStateException {
		return SearchServicesThread.startSearchServices(this, this, attrSet, uuidSet, device, listener);
	}

	private native int runSearchServicesImpl(SearchServicesThread sst, long localDeviceBTAddress, byte[][] uuidValues,
			long remoteDeviceAddress) throws SearchServicesException;

	public int runSearchServices(SearchServicesThread sst, int[] attrSet, UUID[] uuidSet, RemoteDevice device,
			DiscoveryListener listener) throws BluetoothStateException {
		sst.searchServicesStartedCallback();
		try {
			byte[][] uuidValues = new byte[uuidSet.length][];
			for (int i = 0; i < uuidSet.length; i++) {
				uuidValues[i] = Utils.UUIDToByteArray(uuidSet[i]);
			}
			int respCode = runSearchServicesImpl(sst, this.localDeviceBTAddress, uuidValues, RemoteDeviceHelper
					.getAddress(device));
			if ((respCode != DiscoveryListener.SERVICE_SEARCH_ERROR) && (sst.isTerminated())) {
				return DiscoveryListener.SERVICE_SEARCH_TERMINATED;
			} else if (respCode == DiscoveryListener.SERVICE_SEARCH_COMPLETED) {
				Vector records = sst.getServicesRecords();
				if (records.size() != 0) {
					DebugLog.debug("SearchServices finished", sst.getTransID());
					ServiceRecord[] servRecordArray = (ServiceRecord[]) Utils.vector2toArray(records,
							new ServiceRecord[records.size()]);
					listener.servicesDiscovered(sst.getTransID(), servRecordArray);
				}
				if (records.size() != 0) {
					return DiscoveryListener.SERVICE_SEARCH_COMPLETED;
				} else {
					return DiscoveryListener.SERVICE_SEARCH_NO_RECORDS;
				}
			} else {
				return respCode;
			}
		} 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;
		}
	}

	public boolean serviceDiscoveredCallback(SearchServicesThread sst, long sdpSession, long handle) {
		if (sst.isTerminated()) {
			return true;
		}
		ServiceRecordImpl servRecord = new ServiceRecordImpl(this, sst.getDevice(), handle);
		int[] attrIDs = sst.getAttrSet();
		long remoteDeviceAddress = RemoteDeviceHelper.getAddress(sst.getDevice());
		populateServiceRecordAttributeValuesImpl(this.localDeviceBTAddress, remoteDeviceAddress, sdpSession, handle,
				attrIDs, servRecord);
		sst.addServicesRecords(servRecord);
		return false;
	}

	public boolean cancelServiceSearch(int transID) {
		SearchServicesThread sst = SearchServicesThread.getServiceSearchThread(transID);
		if (sst != null) {
			return sst.setTerminated();
		} else {
			return false;
		}
	}

	private native boolean populateServiceRecordAttributeValuesImpl(long localDeviceBTAddress,
			long remoteDeviceAddress, long sdpSession, long handle, int[] attrIDs, ServiceRecordImpl serviceRecord);

	public boolean populateServicesRecordAttributeValues(ServiceRecordImpl serviceRecord, int[] attrIDs)
			throws IOException {
		long remoteDeviceAddress = RemoteDeviceHelper.getAddress(serviceRecord.getHostDevice());
		return populateServiceRecordAttributeValuesImpl(this.localDeviceBTAddress, remoteDeviceAddress, 0,
				serviceRecord.getHandle(), attrIDs, serviceRecord);
	}

	// --- SDP Server

	private native long openSDPSessionImpl() throws ServiceRegistrationException;

	private synchronized long getSDPSession() throws ServiceRegistrationException {
		if (this.sdpSesion == 0) {
			sdpSesion = openSDPSessionImpl();
			DebugLog.debug("created SDPSession", sdpSesion);
		}
		return sdpSesion;
	}

	private native void closeSDPSessionImpl(long sdpSesion, boolean quietly) throws ServiceRegistrationException;

	private native long registerSDPServiceImpl(long sdpSesion, long localDeviceBTAddress, byte[] record)
			throws ServiceRegistrationException;

	private native void updateSDPServiceImpl(long sdpSesion, long localDeviceBTAddress, long handle, byte[] record)
			throws ServiceRegistrationException;

	private native void unregisterSDPServiceImpl(long sdpSesion, long localDeviceBTAddress, long handle, byte[] record)
			throws ServiceRegistrationException;

	private byte[] getSDPBinary(ServiceRecordImpl serviceRecord) throws ServiceRegistrationException {
		byte[] blob;
		try {
			blob = serviceRecord.toByteArray();
		} catch (IOException e) {
			throw new ServiceRegistrationException(e.toString());
		}
		return blob;
	}

	private synchronized void registerSDPRecord(ServiceRecordImpl serviceRecord) throws ServiceRegistrationException {
		long handle = registerSDPServiceImpl(getSDPSession(), this.localDeviceBTAddress, getSDPBinary(serviceRecord));
		serviceRecord.setHandle(handle);
		serviceRecord.populateAttributeValue(BluetoothConsts.ServiceRecordHandle, new DataElement(DataElement.U_INT_4,
				handle));
		registeredServicesCount++;
	}

	private void updateSDPRecord(ServiceRecordImpl serviceRecord) throws ServiceRegistrationException {
		updateSDPServiceImpl(getSDPSession(), this.localDeviceBTAddress, serviceRecord.getHandle(),
				getSDPBinary(serviceRecord));
	}

	private synchronized void unregisterSDPRecord(ServiceRecordImpl serviceRecord) throws ServiceRegistrationException {
		try {
			unregisterSDPServiceImpl(getSDPSession(), this.localDeviceBTAddress, serviceRecord.getHandle(),
					getSDPBinary(serviceRecord));
		} finally {
			registeredServicesCount--;
			if (registeredServicesCount <= 0) {
				registeredServicesCount = 0;
				DebugLog.debug("closeSDPSession", sdpSesion);
				long s = sdpSesion;
				sdpSesion = 0;
				closeSDPSessionImpl(s, false);
			}
		}
	}

	// --- Client RFCOMM connections

	private native long connectionRfOpenClientConnectionImpl(long localDeviceBTAddress, long address, int channel,
			boolean authenticate, boolean encrypt, int timeout) throws IOException;

	public long connectionRfOpenClientConnection(BluetoothConnectionParams params) throws IOException {
		return connectionRfOpenClientConnectionImpl(localDeviceBTAddress, params.address, params.channel,
				params.authenticate, params.encrypt, params.timeout);
	}

	public native void connectionRfCloseClientConnection(long handle) throws IOException;

	public native int rfGetSecurityOptImpl(long handle) throws IOException;

	public int rfGetSecurityOpt(long handle, int expected) throws IOException {
		return rfGetSecurityOptImpl(handle);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2Encrypt(long,long,boolean)
	 */
	public boolean rfEncrypt(long address, long handle, boolean on) throws IOException {
		return false;
	}

	private native long rfServerOpenImpl(long localDeviceBTAddress, boolean authorize, boolean authenticate,
			boolean encrypt, boolean master, boolean timeouts, int backlog) throws IOException;

	private native int rfServerGetChannelIDImpl(long handle) throws IOException;

	public long rfServerOpen(BluetoothConnectionNotifierParams params, ServiceRecordImpl serviceRecord)
			throws IOException {
		long socket = rfServerOpenImpl(this.localDeviceBTAddress, params.authorize, params.authenticate,
				params.encrypt, params.master, params.timeouts, LISTEN_BACKLOG_RFCOMM);
		boolean success = false;
		try {
			int channel = rfServerGetChannelIDImpl(socket);
			serviceRecord.populateRFCOMMAttributes(0, channel, params.uuid, params.name, params.obex);
			registerSDPRecord(serviceRecord);
			success = true;
			return socket;
		} finally {
			if (!success) {
				rfServerCloseImpl(socket, true);
			}
		}
	}

	private native void rfServerCloseImpl(long handle, boolean quietly) throws IOException;

	public void rfServerClose(long handle, ServiceRecordImpl serviceRecord) throws IOException {
		try {
			unregisterSDPRecord(serviceRecord);
		} finally {
			rfServerCloseImpl(handle, false);
		}
	}

	public void rfServerUpdateServiceRecord(long handle, ServiceRecordImpl serviceRecord, boolean acceptAndOpen)
			throws ServiceRegistrationException {
		updateSDPRecord(serviceRecord);
	}

	public native long rfServerAcceptAndOpenRfServerConnection(long handle) throws IOException;

	public void connectionRfCloseServerConnection(long clientHandle) throws IOException {
		connectionRfCloseClientConnection(clientHandle);
	}

	// --- Shared Client and Server RFCOMM connections

	public int connectionRfRead(long handle) throws IOException {
		byte[] data = new byte[1];
		int size = connectionRfRead(handle, data, 0, 1);
		if (size == -1) {
			return -1;
		}
		return 0xFF & data[0];
	}

	public native int connectionRfRead(long handle, byte[] b, int off, int len) throws IOException;

	public native int connectionRfReadAvailable(long handle) throws IOException;

	public native void connectionRfWrite(long handle, int b) throws IOException;

	public native void connectionRfWrite(long handle, byte[] b, int off, int len) throws IOException;

	public native void connectionRfFlush(long handle) throws IOException;

	public native long getConnectionRfRemoteAddress(long handle) throws IOException;

	// --- Client and Server L2CAP connections

	private native long l2OpenClientConnectionImpl(long localDeviceBTAddress, long address, int channel,
			boolean authenticate, boolean encrypt, int receiveMTU, int transmitMTU, int timeout) throws IOException;

	/*
	 * (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 {
		return l2OpenClientConnectionImpl(this.localDeviceBTAddress, params.address, params.channel,
				params.authenticate, params.encrypt, receiveMTU, transmitMTU, params.timeout);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2CloseClientConnection(long)
	 */
	public native void l2CloseClientConnection(long handle) throws IOException;

	private native long l2ServerOpenImpl(long localDeviceBTAddress, boolean authorize, boolean authenticate,
			boolean encrypt, boolean master, boolean timeouts, int backlog, int receiveMTU, int transmitMTU,
			int assignPsm) throws IOException;

	public native int l2ServerGetPSMImpl(long handle) throws IOException;

	/*
	 * (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 {
		long socket = l2ServerOpenImpl(this.localDeviceBTAddress, params.authorize, params.authenticate,
				params.encrypt, params.master, params.timeouts, LISTEN_BACKLOG_L2CAP, receiveMTU, transmitMTU,
				params.bluecove_ext_psm);
		boolean success = false;
		try {
			int channel = l2ServerGetPSMImpl(socket);
			serviceRecord.populateL2CAPAttributes(0, channel, params.uuid, params.name);
			registerSDPRecord(serviceRecord);
			success = true;
			return socket;
		} finally {
			if (!success) {
				l2ServerCloseImpl(socket, true);
			}
		}
	}

	/*
	 * (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 {
		updateSDPRecord(serviceRecord);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.intel.bluetooth.BluetoothStack#l2ServerAcceptAndOpenServerConnection
	 * (long)
	 */
	public native long l2ServerAcceptAndOpenServerConnection(long handle) throws IOException;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2CloseServerConnection(long)
	 */
	public void l2CloseServerConnection(long handle) throws IOException {
		l2CloseClientConnection(handle);
	}

	private native void l2ServerCloseImpl(long handle, boolean quietly) throws IOException;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2ServerClose(long,
	 * com.intel.bluetooth.ServiceRecordImpl)
	 */
	public void l2ServerClose(long handle, ServiceRecordImpl serviceRecord) throws IOException {
		try {
			unregisterSDPRecord(serviceRecord);
		} finally {
			l2ServerCloseImpl(handle, false);
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2Ready(long)
	 */
	public native boolean l2Ready(long handle) throws IOException;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2receive(long, byte[])
	 */
	public native int l2Receive(long handle, byte[] inBuf) throws IOException;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2send(long, byte[])
	 */
	public native void l2Send(long handle, byte[] data) throws IOException;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2GetReceiveMTU(long)
	 */
	public native int l2GetReceiveMTU(long handle) throws IOException;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2GetTransmitMTU(long)
	 */
	public native int l2GetTransmitMTU(long handle) throws IOException;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2RemoteAddress(long)
	 */
	public native long l2RemoteAddress(long handle) throws IOException;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2GetSecurityOpt(long, int)
	 */
	public native int l2GetSecurityOpt(long handle, int expected) throws IOException;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.intel.bluetooth.BluetoothStack#l2Encrypt(long,long,boolean)
	 */
	public boolean l2Encrypt(long address, long handle, boolean on) throws IOException {
		return false;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy