Fields Summary |
---|
static final int | RETRIEVABLE_MAXMaxumum quantity of attributes in one request |
static final int | TRANS_MAXMaximum number of concurrent service searches that can
exist at any one time. |
private javax.bluetooth.RemoteDevice | remoteDeviceRemote device service provided by. |
private BluetoothNotifier | notifierService notifier. |
private Hashtable | attributesTableAttribues of the record. |
private int | serviceClassesBit scale that keeps service classes. |
private static final int | MASK_OVERFLOWMask to identify attribute IDs out of range. |
private static final int | MASK_INCORRECT_CLASSMask of incorrect class bits. |
public static final int | SERVICE_RECORD_HANDLEServiceRecordHandle attribute ID. |
public static final int | PROTOCOL_DESCRIPTOR_LISTProtocolDescriptorList attribute ID. |
public static final int | SERVICE_CLASS_ATTR_IDService class attribute id. |
public static final int | NAME_ATTR_IDName attribute id. |
private int | protocolProtocol type. |
private String | btaddrBluetooth address of device service record came from. |
private int | portPSM or channel id. |
Methods Summary |
---|
private void | attrsInit(int[] attrIDs, javax.bluetooth.DataElement[] attrValues)Fills up attributes table by values given.
for (int i = 0; i < attrIDs.length; i++) {
attributesTable.put(new Integer(attrIDs[i]),
dataElementCopy(attrValues[i]));
}
DataElement handle = getAttributeValue(SERVICE_RECORD_HANDLE);
if (handle == null) {
attributesTable.put(new Integer(SERVICE_RECORD_HANDLE),
new DataElement(DataElement.U_INT_4, 0));
}
|
public synchronized com.sun.kvem.jsr082.bluetooth.ServiceRecordImpl | copy()Creates a copy of this record. The copy recieves new instances of
attributes values which are of types DataElement.DATSEQ
or DataElement.DATALT (the only data element types that
can be modified after creation).
int count = attributesTable.size();
int[] attrIDs = new int[count];
DataElement[] attrValues = new DataElement[count];
Enumeration ids = attributesTable.keys();
Enumeration values = attributesTable.elements();
for (int i = 0; i < count; i++) {
attrIDs[i] = ((Integer)ids.nextElement()).intValue();
// no nedd to copy elements here; service record constructor
// performs the copying
attrValues[i] = (DataElement)values.nextElement();
}
ServiceRecordImpl servRec = new ServiceRecordImpl(notifier,
attrIDs, attrValues);
servRec.serviceClasses = serviceClasses;
return servRec;
|
private javax.bluetooth.DataElement | dataElementCopy(javax.bluetooth.DataElement original)Creates a copy of DataElement if it's necessary.
if ((original.getDataType() == DataElement.DATSEQ)
|| (original.getDataType() == DataElement.DATALT)) {
DataElement copy = new DataElement(original.getDataType());
Enumeration elements = (Enumeration) original.getValue();
while (elements.hasMoreElements()) {
copy.addElement(dataElementCopy((DataElement)
elements.nextElement()));
}
return copy;
} else {
return original;
}
|
public synchronized int[] | getAttributeIDs()
int[] attrIDs = new int[attributesTable.size()];
Enumeration e = attributesTable.keys();
for (int i = 0; i < attrIDs.length; i++) {
attrIDs[i] = ((Integer) e.nextElement()).intValue();
}
return attrIDs;
|
public javax.bluetooth.DataElement | getAttributeValue(int attrID)
if ((attrID & MASK_OVERFLOW) != 0) {
throw new IllegalArgumentException(
"attrID isn't a 16-bit unsigned integer");
}
DataElement attrValue = (DataElement) attributesTable.get(new
Integer(attrID));
if (attrValue == null) {
return null;
} else {
return dataElementCopy(attrValue);
}
|
public synchronized java.lang.String | getConnectionURL(int requiredSecurity, boolean mustBeMaster)
// protocol, btaddr, port
retrieveUrlCommonParams();
BluetoothUrl url = BluetoothUrl.createClientUrl(
protocol, btaddr, port);
if (mustBeMaster) {
url.master = true;
} else {
url.master = false;
}
switch (requiredSecurity) {
case NOAUTHENTICATE_NOENCRYPT:
break;
case AUTHENTICATE_ENCRYPT:
url.encrypt = true;
case AUTHENTICATE_NOENCRYPT:
url.authenticate = true;
break;
default:
throw new IllegalArgumentException("unsupported security type: "
+ requiredSecurity);
}
return url.toString();
|
public int | getDeviceServiceClasses()Retrieve service classes bits provided by corresponing service
at local device.
if (remoteDevice != null) {
throw new RuntimeException(
"This ServiceRecord was created by a call to "
+ "DiscoveryAgent.searchServices()");
}
// it's necessary to improve these code
return serviceClasses;
|
public int | getHandle()Returns service record handle.
DataElement handle = getAttributeValue(SERVICE_RECORD_HANDLE);
return handle != null ? (int)handle.getLong() : 0;
|
public javax.bluetooth.RemoteDevice | getHostDevice()
return remoteDevice;
|
public BluetoothNotifier | getNotifier()Returns notifier that has created this record.
return notifier;
|
private void | init(int[] attrIDs, javax.bluetooth.DataElement[] attrValues)Creates attributes table and fills it up by values given.
attributesTable = new Hashtable(attrIDs.length + 1);
attrsInit(attrIDs, attrValues);
|
public synchronized boolean | populateRecord(int[] attrIDs)
Hashtable dupChecker = new Hashtable();
Object checkObj = new Object();
if (remoteDevice == null) {
throw new RuntimeException("local ServiceRecord");
}
if (attrIDs.length == 0) {
throw new IllegalArgumentException("attrIDs size is zero");
}
if (attrIDs.length > RETRIEVABLE_MAX) {
throw new IllegalArgumentException(
"attrIDs size exceeds retrievable.max");
}
for (int i = 0; i < attrIDs.length; i++) {
if ((attrIDs[i] & MASK_OVERFLOW) != 0) {
throw new IllegalArgumentException("attrID does not represent "
+ "a 16-bit unsigned integer");
}
// check attribute ID duplication
if (dupChecker.put(new Integer(attrIDs[i]), checkObj) != null) {
throw new IllegalArgumentException(
"duplicated attribute ID");
}
}
// obtains transaction ID for request
short transactionID = SDPClient.newTransactionID();
// SDP connection and listener. They are initialized in try blok.
SDPClient sdp = null;
SRSDPListener listener = null;
try {
// prepare data for request
DataElement handleEl = (DataElement) attributesTable.get(
new Integer(SERVICE_RECORD_HANDLE));
int handle = (int) handleEl.getLong();
// create and prepare SDP listner
listener = new SRSDPListener();
// create SDP connection and ..
sdp = new SDPClient(remoteDevice.getBluetoothAddress());
// ... and make request
sdp.serviceAttributeRequest(handle, attrIDs, transactionID,
listener);
synchronized (listener) {
if ((listener.ioExcpt == null)
&& (listener.attrValues == null)) {
try {
listener.wait();
} catch (InterruptedException ie) {
// ignore (breake waiting)
}
}
}
} finally {
// Closes SDP connection and frees transaction ID in any case
SDPClient.freeTransactionID(transactionID);
// if connection was created try to close it
if (sdp != null) {
try {
sdp.close();
} catch (IOException ioe) {
// ignore
}
}
}
if (listener.ioExcpt != null) {
throw listener.ioExcpt;
} else if (listener.attrValues == null) {
return false;
} else if (listener.attrValues.length == 0) {
return false;
} else {
attrsInit(listener.attrIDs, listener.attrValues);
return true;
}
|
private void | retrieveUrlCommonParams()Retrieves service protocol, device address and port (PSM or channel)
from service record attributes. Results are set to
protocol , btaddr and port
variables correspondingly.
if (protocol != BluetoothUrl.UNKNOWN) {
// already retrieved
return;
}
if (remoteDevice != null) {
btaddr = remoteDevice.getBluetoothAddress();
} else {
try {
btaddr = LocalDevice.getLocalDevice().getBluetoothAddress();
} catch (BluetoothStateException bse) {
throw new IllegalArgumentException("cannot generate url");
}
}
/*
* There are three protocols supported -
* they are obex or rfcomm or l2cap. So, if obex is
* found in ProtocolDescriptorList, the protocol is btgoep,
* if RFCOMM is found (and no obex) - the btspp, otherwise
* the protocol is btl2cap.
*/
DataElement protocolList = getAttributeValue(PROTOCOL_DESCRIPTOR_LIST);
Enumeration val = (Enumeration) protocolList.getValue();
int type = -1; // 0 = l2cap, 1 = spp, 2 = obex
final UUID L2CAP_UUID = new UUID(0x0100);
final UUID RFCOMM_UUID = new UUID(0x0003);
final UUID OBEX_UUID = new UUID(0x0008);
// go through all of the protocols in the protocols list
while (val.hasMoreElements()) {
DataElement protoDE = (DataElement) val.nextElement();
// application adds a garbage in protocolList - ignore
if (protoDE.getDataType() != DataElement.DATSEQ) {
continue;
}
Enumeration protoEnum = (Enumeration) protoDE.getValue();
int tmpPort = -1;
int tmpType = -1;
// look on protocol details
while (protoEnum.hasMoreElements()) {
DataElement de = (DataElement) protoEnum.nextElement();
// may be PSM or channel id
if (de.getDataType() == DataElement.U_INT_1 ||
de.getDataType() == DataElement.U_INT_2) {
tmpPort = (int) de.getLong();
} else if (de.getDataType() == DataElement.UUID) {
UUID protoUUID = (UUID) de.getValue();
if (protoUUID.equals(L2CAP_UUID)) {
tmpType = 0;
} else if (protoUUID.equals(RFCOMM_UUID)) {
tmpType = 1;
} else if (protoUUID.equals(OBEX_UUID)) {
tmpType = 2;
}
}
}
/*
* ok, new protocol has been parsed - let's check if it
* is over the previous one or not.
*
* Note, that OBEX protocol may appear before the RFCOMM
* one - in this case the port (channel id) is not set -
* need to check this case separately.
*/
if (tmpType > type) {
type = tmpType;
// no "port" for obex type (obex = 2)
if (tmpType != 2) {
port = tmpPort;
}
} else if (tmpType == 1) {
port = tmpPort;
}
}
switch (type) {
case 0:
protocol = BluetoothUrl.L2CAP;
break;
case 1:
protocol = BluetoothUrl.RFCOMM;
break;
case 2:
protocol = BluetoothUrl.OBEX;
break;
default:
throw new IllegalArgumentException("wrong protocol list");
}
|
public synchronized boolean | setAttributeValue(int attrID, javax.bluetooth.DataElement attrValue)
if ((attrID & MASK_OVERFLOW) != 0) {
throw new IllegalArgumentException(
"attrID does not represent a 16-bit unsigned integer");
}
if (attrID == SERVICE_RECORD_HANDLE) {
throw new IllegalArgumentException(
"attrID is the value of ServiceRecordHandle (0x0000)");
}
if (remoteDevice != null) {
throw new RuntimeException(
"can't update ServiceRecord of the RemoteDevice");
}
Object key = new Integer(attrID);
if (attrValue == null) {
return attributesTable.remove(key) != null;
} else {
attributesTable.put(key, dataElementCopy(attrValue));
return true;
}
|
public synchronized void | setDeviceServiceClasses(int classes)
// checks that it's service record from remote device
if (remoteDevice != null) {
throw new RuntimeException("This ServiceRecord was created"
+ " by a call to DiscoveryAgent.searchServices()");
}
// checks correction of set classbits
if ((classes & MASK_INCORRECT_CLASS) != 0) {
throw new IllegalArgumentException("attempt to set incorrect bits");
}
serviceClasses = classes;
|
public void | setHandle(int handle)Sets service record handle.
Integer attrID = new Integer(SERVICE_RECORD_HANDLE);
attributesTable.remove(attrID);
attributesTable.put(attrID, new DataElement(
DataElement.U_INT_4, handle));
|