001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026: package com.sun.kvem.jsr082.bluetooth;
027:
028: import java.io.IOException;
029: import javax.bluetooth.RemoteDevice;
030: import javax.bluetooth.DataElement;
031: import javax.bluetooth.ServiceRecord;
032: import javax.bluetooth.UUID;
033:
034: /**
035: * This class provides functionality of DiscoveryAgent.selectService()
036: * (see JSR 82 texts for details) using SDP serviceAttribute request.
037: */
038: class ServiceSelector extends ServiceSearcherBase {
039:
040: /** Set to false in RR version - then the javac skip the code. */
041: private static final boolean DEBUG = false;
042:
043: /** this class name for debug. */
044: private static final String cn = "ServiceSelector";
045:
046: /** Keeps attributes values retrieved from SDP_ServiceAttributeResponse. */
047: private DataElement[] attrValues = null;
048:
049: /** Keeps an IOException if any occured or SDP_ErrorResponceRecieved. */
050: private IOException ioExcpt = null;
051:
052: /**
053: * Creates ServiceDiscoverer and save all required info in it.
054: */
055: ServiceSelector(int[] attrSet, UUID[] uuidSet, RemoteDevice btDev) {
056: super (attrSet, uuidSet, btDev);
057: }
058:
059: /**
060: * Recieves error information retrieved from SDP_ErrorResponse and
061: * copmpletes the request activity by error reason.
062: */
063: public void errorResponse(int errorCode, String info,
064: int transactionID) {
065: if (DEBUG) {
066: System.out.println(cn + ".errorResponse: called");
067: }
068:
069: synchronized (this ) {
070: ioExcpt = new IOException(info);
071: notify();
072: }
073: }
074:
075: /**
076: * Base class method not relevant to this subclass, it must never be called.
077: */
078: public void serviceSearchResponse(int[] handleList,
079: int transactionID) {
080: if (DEBUG) {
081: System.out.println(cn
082: + ".serviceSearchResponse: unexpected call");
083: }
084: throw new RuntimeException("unexpected call");
085: }
086:
087: /**
088: * Base class method not relevant to this subclass, it must never be called.
089: */
090: public void serviceAttributeResponse(int[] attrIDs,
091: DataElement[] attributeValues, int transactionID) {
092: if (DEBUG) {
093: System.out.println(cn
094: + ".serviceAttributeResponse: unexpected call");
095: }
096: throw new RuntimeException("unexpected call");
097: }
098:
099: /**
100: * Receives arrays of service record attributes and their values retrieved
101: * from SDP_ServiceSearchAttributeResponse.
102: */
103: public void serviceSearchAttributeResponse(int[] attrIDs,
104: DataElement[] attributeValues, int transactionID) {
105: if (DEBUG) {
106: System.out.println(cn
107: + ".serviceSearchAttributeResponse: called");
108: }
109: synchronized (this ) {
110: attrSet = attrIDs;
111: attrValues = attributeValues;
112: notify();
113: }
114: }
115:
116: /**
117: * Performs SERVICESEARCHATTRIBUTE transaction and returns newly created
118: * <code>ServiceRecordImpl</code> instance with attributes and values
119: * returned by server within SDP_serviceSearchAttributeResponse.
120: *
121: * @return newly created <code>ServiceRecordImpl</code> instance with
122: * attributes and values returned by server if the transaction has completed
123: * successfully and attributes list retrieved is not empty,
124: * <code>null</code> otherwise.
125: */
126: ServiceRecord getServiceRecord() {
127: SDPClient sdp = null;
128: short transactionID = SDPClient.newTransactionID();
129:
130: try {
131: sdp = new SDPClient(btDev.getBluetoothAddress());
132:
133: if (sdp != null) {
134: sdp.serviceSearchAttributeRequest(attrSet, uuidSet,
135: transactionID, this );
136: }
137: } catch (IOException ioe) {
138: if (DEBUG) {
139: ioe.printStackTrace();
140: }
141: ioExcpt = ioe;
142: }
143:
144: synchronized (this ) {
145: if (ioExcpt == null && attrValues == null && sdp != null) {
146: try {
147: wait();
148: } catch (InterruptedException ie) {
149: // ignore (break waiting)
150: }
151: }
152: }
153: SDPClient.freeTransactionID(transactionID);
154:
155: try {
156: if (sdp != null) {
157: sdp.close();
158: }
159: } catch (IOException ioe) {
160: if (DEBUG) {
161: ioe.printStackTrace();
162: }
163: // ignore
164: }
165:
166: if (ioExcpt != null) {
167: return null;
168: } else if (attrValues == null) {
169: return null;
170: } else if (attrValues.length == 0) {
171: return null;
172: } else {
173: return new ServiceRecordImpl(btDev, attrSet, attrValues);
174: }
175: }
176: }
|