com.intel.bluetooth.ServiceRecordImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bluecove Show documentation
Show all versions of bluecove Show documentation
BlueCove is JSR-82 J2SE implementation that currently interfaces with the Mac OS X, WIDCOMM, BlueSoleil and Microsoft Bluetooth stack
The newest version!
/**
* BlueCove - Java library for Bluetooth
* Copyright (C) 2004 Intel Corporation
*
* 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: ServiceRecordImpl.java 2624 2008-12-19 17:16:25Z skarzhevskyy $
*/
package com.intel.bluetooth;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DataElement;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import com.intel.bluetooth.BluetoothConsts.DeviceClassConsts;
class ServiceRecordImpl implements ServiceRecord {
private BluetoothStack bluetoothStack;
private RemoteDevice device;
private long handle;
Hashtable attributes;
protected boolean attributeUpdated;
int deviceServiceClasses;
int deviceServiceClassesRegistered;
ServiceRecordImpl(BluetoothStack bluetoothStack, RemoteDevice device, long handle) {
this.bluetoothStack = bluetoothStack;
this.device = device;
this.handle = handle;
this.deviceServiceClassesRegistered = 0;
this.attributes = new Hashtable();
}
byte[] toByteArray() throws IOException {
DataElement element = new DataElement(DataElement.DATSEQ);
final boolean sort = true;
if (sort) {
int[] sortIDs = new int[attributes.size()];
int k = 0;
for (Enumeration e = attributes.keys(); e.hasMoreElements();) {
Integer key = (Integer) e.nextElement();
sortIDs[k] = key.intValue();
k++;
}
// DebugLog.debug("b4 sort", sortIDs);
// Sort
for (int i = 0; i < sortIDs.length; i++) {
for (int j = 0; j < sortIDs.length - i - 1; j++) {
if (sortIDs[j] > sortIDs[j + 1]) {
int temp = sortIDs[j];
sortIDs[j] = sortIDs[j + 1];
sortIDs[j + 1] = temp;
}
}
}
// DebugLog.debug("sorted", sortIDs);
for (int i = 0; i < sortIDs.length; i++) {
element.addElement(new DataElement(DataElement.U_INT_2, sortIDs[i]));
element.addElement(getAttributeValue(sortIDs[i]));
}
} else {
for (Enumeration e = attributes.keys(); e.hasMoreElements();) {
Integer key = (Integer) e.nextElement();
element.addElement(new DataElement(DataElement.U_INT_2, key.intValue()));
element.addElement((DataElement) attributes.get(key));
}
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
(new SDPOutputStream(out)).writeElement(element);
return out.toByteArray();
}
void loadByteArray(byte data[]) throws IOException {
DataElement element = (new SDPInputStream(new ByteArrayInputStream(data))).readElement();
if (element.getDataType() != DataElement.DATSEQ) {
throw new IOException("DATSEQ expected instead of " + element.getDataType());
}
Enumeration en = (Enumeration) element.getValue();
while (en.hasMoreElements()) {
DataElement id = (DataElement) en.nextElement();
if (id.getDataType() != DataElement.U_INT_2) {
throw new IOException("U_INT_2 expected instead of " + id.getDataType());
}
DataElement value = (DataElement) en.nextElement();
this.populateAttributeValue((int) id.getLong(), value);
}
}
/*
* Returns the value of the service attribute ID provided it is present in
* the service record, otherwise this method returns null. Parameters:
* attrID - the attribute whose value is to be returned Returns: the value
* of the attribute ID if present in the service record, otherwise null
* Throws: IllegalArgumentException - if attrID is negative or greater than
* or equal to 2^16
*/
public DataElement getAttributeValue(int attrID) {
if (attrID < 0x0000 || attrID > 0xffff) {
throw new IllegalArgumentException();
}
return (DataElement) attributes.get(new Integer(attrID));
}
/*
* Returns the remote Bluetooth device that populated the service record
* with attribute values. It is important to note that the Bluetooth device
* that provided the value might not be reachable anymore, since it can
* move, turn off, or change its security mode denying all further
* transactions. Returns: the remote Bluetooth device that populated the
* service record, or null if the local device populated this ServiceRecord
*/
public RemoteDevice getHostDevice() {
return device;
}
/*
* Returns the service attribute IDs whose value could be retrieved by a
* call to getAttributeValue(). The list of attributes being returned is not
* sorted and includes default attributes. Returns: an array of service
* attribute IDs that are in this object and have values for them; if there
* are no attribute IDs that have values, this method will return an array
* of length zero. See Also: getAttributeValue(int)
*/
public int[] getAttributeIDs() {
int[] attrIDs = new int[attributes.size()];
int i = 0;
for (Enumeration e = attributes.keys(); e.hasMoreElements();) {
attrIDs[i++] = ((Integer) e.nextElement()).intValue();
}
return attrIDs;
}
/*
* Retrieves the values by contacting the remote Bluetooth device for a set
* of service attribute IDs of a service that is available on a Bluetooth
* device. (This involves going over the air and contacting the remote
* device for the attribute values.) The system might impose a limit on the
* number of service attribute ID values one can request at a time.
* Applications can obtain the value of this limit as a String by calling
* LocalDevice.getProperty("bluetooth.sd.attr.retrievable.max"). The method
* is blocking and will return when the results of the request are
* available. Attribute IDs whose values could be obtained are added to this
* service record. If there exist attribute IDs for which values are
* retrieved this will cause the old values to be overwritten. If the remote
* device cannot be reached, an IOException will be thrown. Parameters:
* attrIDs - the list of service attributes IDs whose value are to be
* retrieved; the number of attributes cannot exceed the property
* bluetooth.sd.attr.retrievable.max; the attributes in the request must be
* legal, i.e. their values are in the range of [0, 2^16-1]. The input
* attribute IDs can include attribute IDs from the default attribute set
* too. Returns: true if the request was successful in retrieving values for
* some or all of the attribute IDs; false if it was unsuccessful in
* retrieving any values Throws: java.io.IOException - if the local device
* is unable to connect to the remote Bluetooth device that was the source
* of this ServiceRecord; if this ServiceRecord was deleted from the SDDB of
* the remote device IllegalArgumentException - if the size of attrIDs
* exceeds the system specified limit as defined by
* bluetooth.sd.attr.retrievable.max; if the attrIDs array length is zero;
* if any of their values are not in the range of [0, 2^16-1]; if attrIDs
* has duplicate values NullPointerException - if attrIDs is null
* RuntimeException - if this ServiceRecord describes a service on the local
* device rather than a service on a remote device
*/
public boolean populateRecord(int[] attrIDs) throws IOException {
/*
* check this is not a local service record
*/
if (device == null) {
throw new RuntimeException("This is local device service record");
}
if (attrIDs == null) {
throw new NullPointerException("attrIDs is null");
}
/*
* check attrIDs is non-null and has length > 0
*/
if (attrIDs.length == 0) {
throw new IllegalArgumentException();
}
/*
* check attrIDs are in range
*/
for (int i = 0; i < attrIDs.length; i++) {
if (attrIDs[i] < 0x0000 || attrIDs[i] > 0xffff) {
throw new IllegalArgumentException();
}
}
/*
* copy and sort attrIDs (required by MS Bluetooth and for check for
* duplicates)
*/
int[] sortIDs = new int[attrIDs.length];
System.arraycopy(attrIDs, 0, sortIDs, 0, attrIDs.length);
for (int i = 0; i < sortIDs.length; i++) {
for (int j = 0; j < sortIDs.length - i - 1; j++) {
if (sortIDs[j] > sortIDs[j + 1]) {
int temp = sortIDs[j];
sortIDs[j] = sortIDs[j + 1];
sortIDs[j + 1] = temp;
}
}
}
/*
* check for duplicates
*/
for (int i = 0; i < sortIDs.length - 1; i++) {
if (sortIDs[i] == sortIDs[i + 1]) {
throw new IllegalArgumentException();
}
DebugLog.debug0x("srvRec query for attr", sortIDs[i]);
}
DebugLog.debug0x("srvRec query for attr", sortIDs[sortIDs.length - 1]);
return this.bluetoothStack.populateServicesRecordAttributeValues(this, sortIDs);
}
/*
* Returns a String including optional parameters that can be used by a
* client to connect to the service described by this ServiceRecord. The
* return value can be used as the first argument to Connector.open(). In
* the case of a Serial Port service record, this string might look like
* "btspp://0050CD00321B:3;authenticate=true;encrypt=false;master=true",
* where "0050CD00321B" is the Bluetooth address of the device that provided
* this ServiceRecord, "3" is the RFCOMM server channel mentioned in this
* ServiceRecord, and there are three optional parameters related to
* security and master/slave roles. If this method is called on a
* ServiceRecord returned from LocalDevice.getRecord(), it will return the
* connection string that a remote device will use to connect to this
* service.
*
* Parameters: requiredSecurity - determines whether authentication or
* encryption are required for a connection mustBeMaster - true indicates
* that this device must play the role of master in connections to this
* service; false indicates that the local device is willing to be either
* the master or the slave Returns: a string that can be used to connect to
* the service or null if the ProtocolDescriptorList in this ServiceRecord
* is not formatted according to the Bluetooth specification Throws:
* IllegalArgumentException - if requiredSecurity is not one of the
* constants NOAUTHENTICATE_NOENCRYPT, AUTHENTICATE_NOENCRYPT, or
* AUTHENTICATE_ENCRYPT See Also: NOAUTHENTICATE_NOENCRYPT,
* AUTHENTICATE_NOENCRYPT, AUTHENTICATE_ENCRYPT
*/
public String getConnectionURL(int requiredSecurity, boolean mustBeMaster) {
int commChannel = -1;
DataElement protocolDescriptor = getAttributeValue(BluetoothConsts.ProtocolDescriptorList);
if ((protocolDescriptor == null) || (protocolDescriptor.getDataType() != DataElement.DATSEQ)) {
return null;
}
/*
* get RFCOMM Channel ProtocolDescriptorList is DATSEQ of DATSEQ of UUID
* and optional parameters
*/
boolean isL2CAP = false;
boolean isRFCOMM = false;
boolean isOBEX = false;
for (Enumeration protocolsSeqEnum = (Enumeration) protocolDescriptor.getValue(); protocolsSeqEnum
.hasMoreElements();) {
DataElement elementSeq = (DataElement) protocolsSeqEnum.nextElement();
if (elementSeq.getDataType() == DataElement.DATSEQ) {
Enumeration elementSeqEnum = (Enumeration) elementSeq.getValue();
if (elementSeqEnum.hasMoreElements()) {
DataElement protocolElement = (DataElement) elementSeqEnum.nextElement();
if (protocolElement.getDataType() != DataElement.UUID) {
continue;
}
Object uuid = protocolElement.getValue();
if (BluetoothConsts.OBEX_PROTOCOL_UUID.equals(uuid)) {
isOBEX = true;
isRFCOMM = false;
isL2CAP = false;
} else if (elementSeqEnum.hasMoreElements() && (BluetoothConsts.RFCOMM_PROTOCOL_UUID.equals(uuid))) {
DataElement protocolPSMElement = (DataElement) elementSeqEnum.nextElement();
switch (protocolPSMElement.getDataType()) {
case DataElement.U_INT_1:
case DataElement.U_INT_2:
case DataElement.U_INT_4:
case DataElement.INT_1:
case DataElement.INT_2:
case DataElement.INT_4:
case DataElement.INT_8:
long val = protocolPSMElement.getLong();
if ((val >= BluetoothConsts.RFCOMM_CHANNEL_MIN)
&& (val <= BluetoothConsts.RFCOMM_CHANNEL_MAX)) {
commChannel = (int) val;
isRFCOMM = true;
isL2CAP = false;
}
break;
}
} else if (elementSeqEnum.hasMoreElements() && (BluetoothConsts.L2CAP_PROTOCOL_UUID.equals(uuid))) {
DataElement protocolPSMElement = (DataElement) elementSeqEnum.nextElement();
switch (protocolPSMElement.getDataType()) {
case DataElement.U_INT_1:
case DataElement.U_INT_2:
case DataElement.U_INT_4:
case DataElement.INT_1:
case DataElement.INT_2:
case DataElement.INT_4:
case DataElement.INT_8:
long pcm = protocolPSMElement.getLong();
if ((pcm >= BluetoothConsts.L2CAP_PSM_MIN) && (pcm <= BluetoothConsts.L2CAP_PSM_MAX)) {
commChannel = (int) pcm;
isL2CAP = true;
}
break;
}
}
}
}
}
if (commChannel == -1) {
return null;
}
/*
* build URL
*/
StringBuffer buf = new StringBuffer();
if (isOBEX) {
buf.append(BluetoothConsts.PROTOCOL_SCHEME_BT_OBEX);
} else if (isRFCOMM) {
buf.append(BluetoothConsts.PROTOCOL_SCHEME_RFCOMM);
} else if (isL2CAP) {
buf.append(BluetoothConsts.PROTOCOL_SCHEME_L2CAP);
} else {
return null;
}
buf.append("://");
if (device == null) {
try {
Object saveID = BlueCoveImpl.getCurrentThreadBluetoothStackID();
try {
BlueCoveImpl.setThreadBluetoothStack(bluetoothStack);
buf.append(LocalDevice.getLocalDevice().getBluetoothAddress());
} finally {
if (saveID != null) {
BlueCoveImpl.setThreadBluetoothStackID(saveID);
}
}
} catch (BluetoothStateException bse) {
DebugLog.error("can't read LocalAddress", bse);
buf.append("localhost");
}
} else {
buf.append(getHostDevice().getBluetoothAddress());
}
buf.append(":");
if (isL2CAP) {
String hex = Integer.toHexString(commChannel);
for (int i = hex.length(); i < 4; i++) {
buf.append('0');
}
buf.append(hex);
} else {
buf.append(commChannel);
}
switch (requiredSecurity) {
case NOAUTHENTICATE_NOENCRYPT:
buf.append(";authenticate=false;encrypt=false");
break;
case AUTHENTICATE_NOENCRYPT:
buf.append(";authenticate=true;encrypt=false");
break;
case AUTHENTICATE_ENCRYPT:
buf.append(";authenticate=true;encrypt=true");
break;
default:
throw new IllegalArgumentException();
}
if (mustBeMaster) {
buf.append(";master=true");
} else {
buf.append(";master=false");
}
return buf.toString();
}
int getChannel(UUID protocolUUID) {
int channel = -1;
DataElement protocolDescriptor = getAttributeValue(BluetoothConsts.ProtocolDescriptorList);
if ((protocolDescriptor == null) || (protocolDescriptor.getDataType() != DataElement.DATSEQ)) {
return -1;
}
/*
* get RFCOMM Channel or L2CAP PSM ProtocolDescriptorList is DATSEQ of
* DATSEQ of UUID and optional parameters
*/
for (Enumeration protocolsSeqEnum = (Enumeration) protocolDescriptor.getValue(); protocolsSeqEnum
.hasMoreElements();) {
DataElement elementSeq = (DataElement) protocolsSeqEnum.nextElement();
if (elementSeq.getDataType() == DataElement.DATSEQ) {
Enumeration elementSeqEnum = (Enumeration) elementSeq.getValue();
if (elementSeqEnum.hasMoreElements()) {
DataElement protocolElement = (DataElement) elementSeqEnum.nextElement();
if (protocolElement.getDataType() != DataElement.UUID) {
continue;
}
Object uuid = protocolElement.getValue();
if (elementSeqEnum.hasMoreElements() && (protocolUUID.equals(uuid))) {
DataElement protocolPSMElement = (DataElement) elementSeqEnum.nextElement();
switch (protocolPSMElement.getDataType()) {
case DataElement.U_INT_1:
case DataElement.U_INT_2:
case DataElement.U_INT_4:
case DataElement.INT_1:
case DataElement.INT_2:
case DataElement.INT_4:
case DataElement.INT_8:
channel = (int) protocolPSMElement.getLong();
break;
}
}
}
}
}
return channel;
}
/*
* Used by a server application to indicate the major service class bits
* that should be activated in the server's DeviceClass when this
* ServiceRecord is added to the SDDB. When client devices do device
* discovery, the server's DeviceClass is provided as one of the arguments
* of the deviceDiscovered method of the DiscoveryListener interface. Client
* devices can consult the DeviceClass of the server device to get a general
* idea of the kind of device this is (e.g., phone, PDA, or PC) and the
* major service classes it offers (e.g., rendering, telephony, or
* information). A server application should use the setDeviceServiceClasses
* method to describe its service in terms of the major service classes.
* This allows clients to obtain a DeviceClass for the server that
* accurately describes all of the services being offered. When
* acceptAndOpen() is invoked for the first time on the notifier associated
* with this ServiceRecord, the classes argument from the
* setDeviceServiceClasses method is OR'ed with the current setting of the
* major service class bits of the local device. The OR operation
* potentially activates additional bits. These bits may be retrieved by
* calling getDeviceClass() on the LocalDevice object. Likewise, a call to
* LocalDevice.updateRecord() will cause the major service class bits to be
* OR'ed with the current settings and updated.
*
* The documentation for DeviceClass gives examples of the integers that
* describe each of the major service classes and provides a URL for the
* complete list. These integers can be used individually or OR'ed together
* to describe the appropriate value for classes.
*
* Later, when this ServiceRecord is removed from the SDDB, the
* implementation will automatically deactivate the device bits that were
* activated as a result of the call to setDeviceServiceClasses. The only
* exception to this occurs if there is another ServiceRecord that is in the
* SDDB and setDeviceServiceClasses has been sent to that other
* ServiceRecord to request that some of the same bits be activated.
*
* Parameters: classes - an integer whose binary representation indicates
* the major service class bits that should be activated Throws:
* IllegalArgumentException - if classes is not an OR of one or more of the
* major service class integers in the Bluetooth Assigned Numbers document.
* While Limited Discoverable Mode is included in this list of major service
* classes, its bit is activated by placing the device in Limited
* Discoverable Mode (see the GAP specification), so if bit 13 is set this
* exception will be thrown. RuntimeExceptin - if the ServiceRecord
* receiving the message was obtained from a remote device
*/
public void setDeviceServiceClasses(int classes) {
if (device != null) {
throw new RuntimeException("Service record obtained from a remote device");
}
if ((classes & (0xff000000 | DeviceClassConsts.LIMITED_DISCOVERY_SERVICE | DeviceClassConsts.FORMAT_VERSION_MASK)) != 0) {
throw new IllegalArgumentException();
}
if ((classes & (DeviceClassConsts.MAJOR_MASK | DeviceClassConsts.MINOR_MASK)) != 0) {
throw new IllegalArgumentException();
}
if ((bluetoothStack.getFeatureSet() & BluetoothStack.FEATURE_SET_DEVICE_SERVICE_CLASSES) == 0) {
throw new NotSupportedRuntimeException(bluetoothStack.getStackID());
}
this.deviceServiceClasses = classes;
}
/*
* Modifies this ServiceRecord to contain the service attribute defined by
* the attribute-value pair (attrID, attrValue). If the attrID does not
* exist in the ServiceRecord, this attribute-value pair is added to this
* ServiceRecord object. If the attrID is already in this ServiceRecord, the
* value of the attribute is changed to attrValue. If attrValue is null, the
* attribute with the attribute ID of attrID is removed from this
* ServiceRecord object. If attrValue is null and attrID does not exist in
* this object, this method will return false. This method makes no
* modifications to a service record in the SDDB. In order for any changes
* made by this method to be reflected in the SDDB, a call must be made to
* the acceptAndOpen() method of the associated notifier to add this
* ServiceRecord to the SDDB for the first time, or a call must be made to
* the updateRecord() method of LocalDevice to modify the version of this
* ServiceRecord that is already in the SDDB.
*
* This method prevents the ServiceRecordHandle from being modified by
* throwing an IllegalArgumentException.
*
* Parameters: attrID - the service attribute ID attrValue - the DataElement
* which is the value of the service attribute Returns: true if the service
* attribute was successfully added, removed, or modified; false if
* attrValue is null and attrID is not in this object Throws:
* IllegalArgumentException - if attrID does not represent a 16-bit unsigned
* integer; if attrID is the value of ServiceRecordHandle (0x0000)
* RuntimeException - if this method is called on a ServiceRecord that was
* created by a call to DiscoveryAgent.searchServices()
*/
public boolean setAttributeValue(int attrID, DataElement attrValue) {
/*
* check this is a local service record
*/
if (device != null) {
throw new IllegalArgumentException();
}
if (attrID < 0x0000 || attrID > 0xffff) {
throw new IllegalArgumentException();
}
if (attrID == BluetoothConsts.ServiceRecordHandle) {
throw new IllegalArgumentException();
}
/*
* remove, add or modify attribute
*/
attributeUpdated = true;
if (attrValue == null) {
return (attributes.remove(new Integer(attrID)) != null);
} else {
attributes.put(new Integer(attrID), attrValue);
return true;
}
}
/**
* Internal implementation function
*/
void populateAttributeValue(int attrID, DataElement attrValue) {
if (attrID < 0x0000 || attrID > 0xffff) {
throw new IllegalArgumentException();
}
if (attrValue == null) {
attributes.remove(new Integer(attrID));
} else {
attributes.put(new Integer(attrID), attrValue);
}
}
public String toString() {
StringBuffer buf = new StringBuffer("{\n");
for (Enumeration e = attributes.keys(); e.hasMoreElements();) {
Integer i = (Integer) e.nextElement();
buf.append("0x");
buf.append(Integer.toHexString(i.intValue()));
buf.append(":\n\t");
DataElement d = (DataElement) attributes.get(i);
buf.append(d);
buf.append("\n");
}
buf.append("}");
return buf.toString();
}
/**
* Internal implementation function
*/
long getHandle() {
return this.handle;
}
/**
* Internal implementation function
*/
void setHandle(long handle) {
this.handle = handle;
}
/**
* Internal implementation function
*/
boolean hasServiceClassUUID(UUID uuid) {
DataElement attrDataElement = getAttributeValue(BluetoothConsts.ServiceClassIDList);
if ((attrDataElement == null) || (attrDataElement.getDataType() != DataElement.DATSEQ)
|| attrDataElement.getSize() == 0) {
// DebugLog.debug("Bogus ServiceClassIDList");
return false;
}
Object value = attrDataElement.getValue();
if ((value == null) || (!(value instanceof Enumeration))) {
DebugLog.debug("Bogus Value in DATSEQ");
if (value != null) {
DebugLog.error("DATSEQ class " + value.getClass().getName());
}
return false;
}
for (Enumeration e = (Enumeration) value; e.hasMoreElements();) {
Object element = e.nextElement();
if (!(element instanceof DataElement)) {
DebugLog.debug("Bogus element in DATSEQ, " + value.getClass().getName());
continue;
}
DataElement dataElement = (DataElement) element;
if ((dataElement.getDataType() == DataElement.UUID) && (uuid.equals(dataElement.getValue()))) {
return true;
}
}
return false;
}
boolean hasProtocolClassUUID(UUID uuid) {
DataElement protocolDescriptor = getAttributeValue(BluetoothConsts.ProtocolDescriptorList);
if ((protocolDescriptor == null) || (protocolDescriptor.getDataType() != DataElement.DATSEQ)) {
// DebugLog.debug("Bogus ProtocolDescriptorList");
return false;
}
for (Enumeration protocolsSeqEnum = (Enumeration) protocolDescriptor.getValue(); protocolsSeqEnum
.hasMoreElements();) {
DataElement elementSeq = (DataElement) protocolsSeqEnum.nextElement();
if (elementSeq.getDataType() == DataElement.DATSEQ) {
Enumeration elementSeqEnum = (Enumeration) elementSeq.getValue();
if (elementSeqEnum.hasMoreElements()) {
DataElement protocolElement = (DataElement) elementSeqEnum.nextElement();
if (protocolElement.getDataType() != DataElement.UUID) {
continue;
}
if (uuid.equals(protocolElement.getValue())) {
return true;
}
}
}
}
return false;
}
DataElement clone(DataElement de) {
DataElement c = null;
switch (de.getDataType()) {
case DataElement.U_INT_1:
case DataElement.U_INT_2:
case DataElement.U_INT_4:
case DataElement.INT_1:
case DataElement.INT_2:
case DataElement.INT_4:
c = new DataElement(de.getDataType(), de.getLong());
break;
case DataElement.URL:
case DataElement.STRING:
case DataElement.UUID:
case DataElement.INT_16:
case DataElement.INT_8:
case DataElement.U_INT_16:
c = new DataElement(de.getDataType(), de.getValue());
break;
case DataElement.NULL:
c = new DataElement(de.getDataType());
break;
case DataElement.BOOL:
c = new DataElement(de.getBoolean());
break;
case DataElement.DATSEQ:
case DataElement.DATALT:
c = new DataElement(de.getDataType());
for (Enumeration en = (Enumeration) de.getValue(); en.hasMoreElements();) {
DataElement dataElement = (DataElement) en.nextElement();
c.addElement(clone(dataElement));
}
}
return c;
}
/**
* Internal implementation function
*/
void populateRFCOMMAttributes(long handle, int channel, UUID uuid, String name, boolean obex) {
this.populateAttributeValue(BluetoothConsts.ServiceRecordHandle, new DataElement(DataElement.U_INT_4, handle));
/*
* service class ID list
*/
DataElement serviceClassIDList = new DataElement(DataElement.DATSEQ);
serviceClassIDList.addElement(new DataElement(DataElement.UUID, uuid));
if (!obex) {
serviceClassIDList.addElement(new DataElement(DataElement.UUID, BluetoothConsts.SERIAL_PORT_UUID));
}
this.populateAttributeValue(BluetoothConsts.ServiceClassIDList, serviceClassIDList);
/*
* protocol descriptor list
*/
DataElement protocolDescriptorList = new DataElement(DataElement.DATSEQ);
DataElement L2CAPDescriptor = new DataElement(DataElement.DATSEQ);
L2CAPDescriptor.addElement(new DataElement(DataElement.UUID, BluetoothConsts.L2CAP_PROTOCOL_UUID));
protocolDescriptorList.addElement(L2CAPDescriptor);
DataElement RFCOMMDescriptor = new DataElement(DataElement.DATSEQ);
RFCOMMDescriptor.addElement(new DataElement(DataElement.UUID, BluetoothConsts.RFCOMM_PROTOCOL_UUID));
RFCOMMDescriptor.addElement(new DataElement(DataElement.U_INT_1, channel));
protocolDescriptorList.addElement(RFCOMMDescriptor);
if (obex) {
DataElement OBEXDescriptor = new DataElement(DataElement.DATSEQ);
OBEXDescriptor.addElement(new DataElement(DataElement.UUID, BluetoothConsts.OBEX_PROTOCOL_UUID));
protocolDescriptorList.addElement(OBEXDescriptor);
}
this.populateAttributeValue(BluetoothConsts.ProtocolDescriptorList, protocolDescriptorList);
if (name != null) {
this.populateAttributeValue(BluetoothConsts.AttributeIDServiceName, new DataElement(DataElement.STRING,
name));
}
}
void populateL2CAPAttributes(int handle, int channel, UUID uuid, String name) {
this.populateAttributeValue(BluetoothConsts.ServiceRecordHandle, new DataElement(DataElement.U_INT_4, handle));
/*
* service class ID list
*/
DataElement serviceClassIDList = new DataElement(DataElement.DATSEQ);
serviceClassIDList.addElement(new DataElement(DataElement.UUID, uuid));
this.populateAttributeValue(BluetoothConsts.ServiceClassIDList, serviceClassIDList);
/*
* protocol descriptor list
*/
DataElement protocolDescriptorList = new DataElement(DataElement.DATSEQ);
DataElement L2CAPDescriptor = new DataElement(DataElement.DATSEQ);
L2CAPDescriptor.addElement(new DataElement(DataElement.UUID, BluetoothConsts.L2CAP_PROTOCOL_UUID));
L2CAPDescriptor.addElement(new DataElement(DataElement.U_INT_2, channel));
protocolDescriptorList.addElement(L2CAPDescriptor);
this.populateAttributeValue(BluetoothConsts.ProtocolDescriptorList, protocolDescriptorList);
if (name != null) {
this.populateAttributeValue(BluetoothConsts.AttributeIDServiceName, new DataElement(DataElement.STRING,
name));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy