Fields Summary |
---|
private static final boolean | DEBUGSet to false in RR version - then the javac skip the code. |
private static final String | cnthis class name for debug. |
private short | transactionIDID of transaction this listener works in. |
private javax.bluetooth.DiscoveryListener | discListenerListens for service discovery and is informed as a service is
discovered. |
private SDPClient | sdpSDP client to send requests. |
private int[] | handlesService records handles retrieved from a server response. |
private int | processedHandleNumber of service records handles processed. |
private boolean | inactiveIndicates if this listener is inactive. |
private boolean | canceledIndicates if service search has been canceled. |
private boolean | notifiedIndicates if listener notification has been called. |
private static int | requestCounterCurrent quantity of service discovering requests. |
private static Hashtable | searchersKeeps the references of current service search requests. |
Methods Summary |
---|
static boolean | cancel(int transactionID)Cancels transaction with given ID.
ServiceSearcher carrier = (ServiceSearcher)
searchers.get(new Integer(transactionID));
if (carrier == null) {
return false;
} else {
return carrier.cancel();
}
|
boolean | cancel()Cancels current transaction.
synchronized (this) {
if (inactive) {
return false;
}
inactive = true;
if (sdp == null) {
return false;
}
if (canceled) {
return false;
}
canceled = true;
}
// cancel running effective transaction if any.
// if sdp.cancelServiceSearch returns false (there is no running
// transactions) then call the notification directly.
if (!sdp.cancelServiceSearch(transactionID)) {
new NotifyListenerRunner(
DiscoveryListener.SERVICE_SEARCH_TERMINATED);
}
return true;
|
public void | errorResponse(int errorCode, java.lang.String info, int transactionID)Receives SDP_ErrorResponse and completes the search request activity
by error reason.
if (DEBUG) {
System.out.println(cn + ".errorResponse: called");
}
stop();
if ((errorCode == SDP_INVALID_VERSION)
|| (errorCode == SDP_INVALID_SYNTAX)
|| (errorCode == SDP_INVALID_PDU_SIZE)
|| (errorCode == SDP_INVALID_CONTINUATION_STATE)
|| (errorCode == SDP_INSUFFICIENT_RESOURCES)) {
notifyListener(DiscoveryListener.SERVICE_SEARCH_ERROR);
System.err.println(info);
} else if (errorCode == SDP_INVALID_SR_HANDLE) {
notifyListener(DiscoveryListener.SERVICE_SEARCH_NO_RECORDS);
System.err.println(info);
} else if (errorCode == IO_ERROR) {
notifyListener(
DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE);
} else if (errorCode == TERMINATED) {
new NotifyListenerRunner(
DiscoveryListener.SERVICE_SEARCH_TERMINATED);
}
|
private boolean | isCanceled()Determines whether the service search has been canceled by
the application and did not complete.
return canceled;
|
private void | notifyListener(int respCode)Notifies the listener that service search has
been completed with specified response code.
// guard against multiple notification calls
synchronized (this) {
if (!notified) {
notified = true;
} else {
return;
}
}
if (DEBUG) {
String codeStr = "Undefined";
switch (respCode) {
case DiscoveryListener.SERVICE_SEARCH_COMPLETED:
codeStr = "SERVICE_SEARCH_COMPLETED";
break;
case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
codeStr = "SERVICE_SEARCH_DEVICE_NOT_REACHABLE";
break;
case DiscoveryListener.SERVICE_SEARCH_ERROR:
codeStr = "SERVICE_SEARCH_ERROR";
break;
case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
codeStr = "SERVICE_SEARCH_NO_RECORDS";
break;
case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
codeStr = "SERVICE_SEARCH_TERMINATED";
break;
default:
}
System.out.println("serviceSearchCompleted:");
System.out.println("\ttransID=" + transactionID);
System.out.println("\trespCode=" + codeStr);
System.out.println("\tinactive=" + inactive);
}
try {
discListener.serviceSearchCompleted(transactionID, respCode);
} catch (Throwable e) {
e.printStackTrace();
}
|
public void | serviceAttributeResponse(int[] attrIDs, javax.bluetooth.DataElement[] attributeValues, int transactionID)Receives arrays of service record attributes and their values retrieved
from server response.
if (DEBUG) {
System.out.println(cn + ".serviceAttributeResponse: called");
}
// there is no reason to process service attributes if service
// search is canceled
if (isCanceled()) {
return;
}
synchronized (this) {
processedHandle++;
}
if (attributeValues != null) {
ServiceRecordImpl[] serviceRecordSet =
new ServiceRecordImpl[1];
serviceRecordSet[0] =
new ServiceRecordImpl(btDev, attrIDs, attributeValues);
try {
// The spec for DiscoveryAgent.cancelServiceSearch() says:
// "After receiving SERVICE_SEARCH_TERMINATED event,
// no further servicesDiscovered() events will occur
// as a result of this search."
if (isCanceled()) {
return;
}
discListener.servicesDiscovered(this.transactionID,
serviceRecordSet);
} catch (Throwable e) {
e.printStackTrace();
}
}
if (processedHandle == handles.length) {
stop();
notifyListener(DiscoveryListener.SERVICE_SEARCH_COMPLETED);
return;
}
try {
// there is no reason to continue attributes discovery if search
// is canceled
if (isCanceled()) {
return;
}
sdp.serviceAttributeRequest(handles[processedHandle],
attrSet, transactionID, this);
} catch (IOException ioe) {
if (DEBUG) {
ioe.printStackTrace();
}
stop();
notifyListener(
DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE);
}
|
public void | serviceSearchAttributeResponse(int[] attrIDs, javax.bluetooth.DataElement[] attributeValues, int transactionID)Base class method not relevant to this subclass, must never be called.
if (DEBUG) {
System.out.println(cn + ".serviceSearchAttributeResponse: called");
}
throw new RuntimeException("Unexpected call");
|
public void | serviceSearchResponse(int[] handleList, int transactionID)Receives array of handles retrieved form SDP_serviceSearchResponse.
if (DEBUG) {
System.out.println(cn + ".serviceSearchResponse: called");
}
// there is no reason to perform response processing if search
// is canceled
if (isCanceled()) {
return;
}
if (handleList == null || handleList.length == 0) {
stop();
notifyListener(DiscoveryListener.SERVICE_SEARCH_NO_RECORDS);
return;
}
synchronized (this) {
handles = handleList;
processedHandle = 0;
}
try {
// there is no reason to request service attributes if service
// search is canceled
if (isCanceled()) {
return;
}
sdp.serviceAttributeRequest(handles[processedHandle],
attrSet, transactionID, this);
} catch (IOException ioe) {
if (DEBUG) {
ioe.printStackTrace();
}
stop();
notifyListener(
DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE);
}
|
int | start()Starts SDP_ServiceSearchRequest.
synchronized (ServiceSearcher.class) {
if (requestCounter == ServiceRecordImpl.TRANS_MAX) {
throw new BluetoothStateException(
"Too much concurrent requests");
}
requestCounter++;
}
transactionID = SDPClient.newTransactionID();
searchers.put(new Integer(transactionID), this);
try {
sdp = new SDPClient(btDev.getBluetoothAddress());
sdp.serviceSearchRequest(uuidSet, transactionID, this);
} catch (IOException ioe) {
if (DEBUG) {
ioe.printStackTrace();
}
synchronized (this) {
stop();
new NotifyListenerRunner(
DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE);
}
}
return transactionID;
|
void | stop()Finishes the service searcher activity.
SDPClient sdp;
SDPClient.freeTransactionID(transactionID);
searchers.remove(new Integer(transactionID));
synchronized (this) {
if (this.sdp == null) {
return;
}
inactive = true;
sdp = this.sdp;
this.sdp = null;
}
synchronized (ServiceSearcher.class) {
requestCounter --;
}
try {
sdp.close();
} catch (IOException ioe) {
if (DEBUG) {
ioe.printStackTrace();
}
// ignore
}
|