SdpManager.java revision bbb4110b455b3aa29106d5b4f0a37e1be8e09475
1bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde/*
2bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* Copyright (C) 2015 Samsung System LSI
3bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* Licensed under the Apache License, Version 2.0 (the "License");
4bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* you may not use this file except in compliance with the License.
5bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* You may obtain a copy of the License at
6bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde*
7bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde*      http://www.apache.org/licenses/LICENSE-2.0
8bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde*
9bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* Unless required by applicable law or agreed to in writing, software
10bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* distributed under the License is distributed on an "AS IS" BASIS,
11bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* See the License for the specific language governing permissions and
13bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde* limitations under the License.
14bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde*/
15bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondepackage com.android.bluetooth.sdp;
16bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
17bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.BluetoothDevice;
18bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.SdpMasRecord;
19bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.SdpMnsRecord;
20bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.SdpOppOpsRecord;
21bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.SdpPseRecord;
22bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.SdpRecord;
23bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.content.Intent;
24bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.os.Handler;
25bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.os.Message;
26bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.os.ParcelUuid;
27bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.os.Parcelable;
28bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.util.Log;
29bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
30bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport com.android.bluetooth.Utils;
31bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport com.android.bluetooth.btservice.AbstractionLayer;
32bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport com.android.bluetooth.btservice.AdapterService;
33bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
34bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.util.ArrayList;
35bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.util.Arrays;
36bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
37bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondepublic class SdpManager {
38bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
39bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final boolean D = true;
40bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final boolean V = false;
41bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final String TAG="SdpManager";
42bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
43bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    // TODO: When changing PBAP to use this new API.
44bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    //       Move the defines to the profile (PBAP already have the feature bits)
45bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* PBAP repositories */
46bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte PBAP_REPO_LOCAL        = 0x01<<0;
47bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte PBAP_REPO_SIM          = 0x01<<1;
48bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte PBAP_REPO_SPEED_DAIL   = 0x01<<2;
49bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte PBAP_REPO_FAVORITES    = 0x01<<3;
50bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
51bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    // TODO: When changing OPP to use this new API.
52bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    //       Move the defines to the profile
53bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* Object Push formats */
54bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte OPP_FORMAT_VCARD21     = 0x01;
55bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte OPP_FORMAT_VCARD30     = 0x02;
56bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte OPP_FORMAT_VCAL10      = 0x03;
57bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte OPP_FORMAT_ICAL20      = 0x04;
58bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte OPP_FORMAT_VNOTE       = 0x05;
59bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte OPP_FORMAT_VMESSAGE    = 0x06;
60bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte OPP_FORMAT_ANY_TYPE_OF_OBJ = (byte)0xFF;
61bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
62bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static final byte[] OPP_FORMAT_ALL= {
63bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        OPP_FORMAT_VCARD21,
64bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        OPP_FORMAT_VCARD30,
65bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        OPP_FORMAT_VCAL10,
66bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        OPP_FORMAT_ICAL20,
67bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        OPP_FORMAT_VNOTE,
68bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        OPP_FORMAT_VMESSAGE,
69bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        OPP_FORMAT_ANY_TYPE_OF_OBJ};
70bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
71bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* Variables to keep track of ongoing and queued search requests.
72bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * mTrackerLock must be held, when using/changing sSdpSearchTracker
73bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * and mSearchInProgress. */
74bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    static SdpSearchTracker sSdpSearchTracker;
75bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    static boolean mSearchInProgress = false;
76bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    static Object mTrackerLock = new Object();
77bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
78bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* The timeout to wait for reply from native. Should never fire. */
79bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final int SDP_INTENT_DELAY = 6000;
80bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static final int MESSAGE_SDP_INTENT = 2;
81bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
82bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    // We need a reference to the adapter service, to be able to send intents
83bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static AdapterService sAdapterService;
84bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static boolean sNativeAvailable;
85bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
86bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    // This object is a singleton
87bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private static SdpManager sSdpManager = null;
88bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
89bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    static {
90bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        classInitNative();
91bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
92bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
93bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private native static void classInitNative();
94bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private native void initializeNative();
95bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private native void cleanupNative();
96bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private native boolean sdpSearchNative(byte[] address, byte[] uuid);
97bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
98bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private native int sdpCreateMapMasRecordNative(String serviceName, int masId,
99bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int rfcommChannel, int l2capPsm, int version, int msgTypes, int features);
100bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
101bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private native int sdpCreateMapMnsRecordNative(String serviceName,
102bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int rfcommChannel, int l2capPsm, int version, int features);
103bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
104bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private native int sdpCreatePbapPseRecordNative(String serviceName, int rfcommChannel,
105bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int l2capPsm, int version, int repositories, int features);
106bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
107bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private native int sdpCreateOppOpsRecordNative(String serviceName,
108bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int rfcommChannel, int l2capPsm, int version, byte[] formats_list);
109bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
110bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private native boolean sdpRemoveSdpRecordNative(int record_id);
111bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
112bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
113bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* Inner class used for wrapping sdp search instance data */
114bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private class SdpSearchInstance {
115bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        private final BluetoothDevice mDevice;
116bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        private final ParcelUuid mUuid;
117bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        private int mStatus = 0;
118bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        private boolean mSearching;
119bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        /* TODO: If we change the API to use another mechanism than intents for
120bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde         *       delivering the results, this would be the place to keep a list
121bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde         *       of the objects to deliver the results to. */
122bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public SdpSearchInstance(int status, BluetoothDevice device, ParcelUuid uuid){
123bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            this.mDevice = device;
124bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            this.mUuid = uuid;
125bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            this.mStatus = status;
126bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            mSearching = true;
127bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
128bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public BluetoothDevice getDevice() {
129bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return mDevice;
130bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
131bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public ParcelUuid getUuid() {
132bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return mUuid;
133bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
134bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public int getStatus(){
135bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return mStatus;
136bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
137bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
138bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public void setStatus(int status) {
139bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            this.mStatus = status;
140bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
141bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
142bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public void startSearch() {
143bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            mSearching = true;
144bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Message message = mHandler.obtainMessage(MESSAGE_SDP_INTENT, this);
145bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            mHandler.sendMessageDelayed(message, SDP_INTENT_DELAY);
146bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
147bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
148bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public void stopSearch() {
149bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(mSearching) {
150bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                mHandler.removeMessages(MESSAGE_SDP_INTENT, this);
151bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
152bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            mSearching = false;
153bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
154bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public boolean isSearching() {
155bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return mSearching;
156bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
157bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
158bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
159bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
160bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* We wrap the ArrayList class to decorate with functionality to
161bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * find an instance based on UUID AND device address.
162bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * As we use a mix of byte[] and object instances, this is more
163bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * efficient than implementing comparable. */
164bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    class SdpSearchTracker {
165bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        private final ArrayList<SdpSearchInstance> list = new ArrayList<SdpSearchInstance>();
166bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
167bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        void clear() {
168bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            list.clear();
169bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
170bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
171bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        boolean add(SdpSearchInstance inst){
172bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return list.add(inst);
173bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
174bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
175bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        boolean remove(SdpSearchInstance inst) {
176bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return list.remove(inst);
177bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
178bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
179bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        SdpSearchInstance getNext() {
180bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(list.size() > 0) {
181bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                return list.get(0);
182bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
183bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return null;
184bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
185bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
186bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        SdpSearchInstance getSearchInstance(byte[] address, byte[] uuidBytes) {
187bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            String addressString = Utils.getAddressStringFromByte(address);
188bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            ParcelUuid uuid = Utils.byteArrayToUuid(uuidBytes)[0];
189bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            for (SdpSearchInstance inst : list) {
190bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                if (inst.getDevice().getAddress().equals(addressString)
191bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        && inst.getUuid().equals(uuid)) {
192bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    return inst;
193bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                }
194bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
195bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return null;
196bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
197bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
198bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        boolean isSearching(BluetoothDevice device, ParcelUuid uuid) {
199bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            String addressString = device.getAddress();
200bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            for (SdpSearchInstance inst : list) {
201bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                if (inst.getDevice().getAddress().equals(addressString)
202bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        && inst.getUuid().equals(uuid)) {
203bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    return inst.isSearching();
204bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                }
205bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
206bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return false;
207bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
208bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
209bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
210bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
211bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private SdpManager(AdapterService adapterService) {
212bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        sSdpSearchTracker = new SdpSearchTracker();
213bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
214bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        /* This is only needed until intents are no longer used */
215bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        sAdapterService = adapterService;
216bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        initializeNative();
217bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        sNativeAvailable=true;
218bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
219bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
220bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
221bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static SdpManager init(AdapterService adapterService) {
222bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        sSdpManager = new SdpManager(adapterService);
223bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return sSdpManager;
224bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
225bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
226bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public static SdpManager getDefaultManager() {
227bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return sSdpManager;
228bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
229bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
230bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void cleanup() {
231bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if (sSdpSearchTracker !=null) {
232bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            synchronized(mTrackerLock) {
233bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sSdpSearchTracker.clear();
234bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
235bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
236bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
237bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if (sNativeAvailable) {
238bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            cleanupNative();
239bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sNativeAvailable=false;
240bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
241bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        sSdpManager = null;
242bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
243bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
244bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
245bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    void sdpMasRecordFoundCallback(int status, byte[] address, byte[] uuid,
246bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int masInstanceId,
247bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int l2capPsm,
248bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int rfcommCannelNumber,
249bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int profileVersion,
250bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int supportedFeatures,
251bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int supportedMessageTypes,
252bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            String serviceName,
253bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            boolean moreResults) {
254bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
255bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        synchronized(mTrackerLock) {
256bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpSearchInstance inst = sSdpSearchTracker.getSearchInstance(address, uuid);
257bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpMasRecord sdpRecord = null;
258bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if (inst == null) {
259bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.e(TAG, "sdpRecordFoundCallback: Search instance is NULL");
260bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                return;
261bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
262bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            inst.setStatus(status);
263bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(status == AbstractionLayer.BT_STATUS_SUCCESS) {
264bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sdpRecord = new SdpMasRecord(masInstanceId,
265bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             l2capPsm,
266bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             rfcommCannelNumber,
267bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             profileVersion,
268bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             supportedFeatures,
269bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             supportedMessageTypes,
270bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             serviceName);
271bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
272bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID: " + Arrays.toString(uuid));
273bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString());
274bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sendSdpIntent(inst, sdpRecord, moreResults);
275bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
276bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
277bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
278bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    void sdpMnsRecordFoundCallback(int status, byte[] address, byte[] uuid,
279bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int l2capPsm,
280bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int rfcommCannelNumber,
281bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int profileVersion,
282bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int supportedFeatures,
283bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            String serviceName,
284bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            boolean moreResults) {
285bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        synchronized(mTrackerLock) {
286bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
287bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpSearchInstance inst = sSdpSearchTracker.getSearchInstance(address, uuid);
288bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpMnsRecord sdpRecord = null;
289bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if (inst == null) {
290bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.e(TAG, "sdpRecordFoundCallback: Search instance is NULL");
291bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                return;
292bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
293bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            inst.setStatus(status);
294bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(status == AbstractionLayer.BT_STATUS_SUCCESS) {
295bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sdpRecord = new SdpMnsRecord(l2capPsm,
296bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             rfcommCannelNumber,
297bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             profileVersion,
298bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             supportedFeatures,
299bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             serviceName);
300bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
301bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID: " + Arrays.toString(uuid));
302bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString());
303bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sendSdpIntent(inst, sdpRecord, moreResults);
304bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
305bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
306bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
307bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    void sdpPseRecordFoundCallback(int status, byte[] address, byte[] uuid,
308bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                        int l2capPsm,
309bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                        int rfcommCannelNumber,
310bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                        int profileVersion,
311bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                        int supportedFeatures,
312bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                        int supportedRepositories,
313bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                        String serviceName,
314bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                        boolean moreResults) {
315bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        synchronized(mTrackerLock) {
316bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpSearchInstance inst = sSdpSearchTracker.getSearchInstance(address, uuid);
317bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpPseRecord sdpRecord = null;
318bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if (inst == null) {
319bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.e(TAG, "sdpRecordFoundCallback: Search instance is NULL");
320bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                return;
321bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
322bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            inst.setStatus(status);
323bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(status == AbstractionLayer.BT_STATUS_SUCCESS) {
324bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sdpRecord = new SdpPseRecord(l2capPsm,
325bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             rfcommCannelNumber,
326bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             profileVersion,
327bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             supportedFeatures,
328bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             supportedRepositories,
329bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                             serviceName);
330bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
331bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID: " + Arrays.toString(uuid));
332bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString());
333bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sendSdpIntent(inst, sdpRecord, moreResults);
334bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
335bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
336bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
337bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    void sdpOppOpsRecordFoundCallback(int status, byte[] address, byte[] uuid,
338bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int l2capPsm,
339bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int rfcommCannelNumber,
340bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int profileVersion,
341bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            String serviceName,
342bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            byte[] formatsList,
343bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            boolean moreResults) {
344bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
345bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        synchronized(mTrackerLock) {
346bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpSearchInstance inst = sSdpSearchTracker.getSearchInstance(address, uuid);
347bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpOppOpsRecord sdpRecord = null;
348bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
349bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if (inst == null) {
350bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.e(TAG, "sdpOppOpsRecordFoundCallback: Search instance is NULL");
351bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                return;
352bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
353bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            inst.setStatus(status);
354bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(status == AbstractionLayer.BT_STATUS_SUCCESS) {
355bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sdpRecord = new SdpOppOpsRecord(serviceName,
356bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                                rfcommCannelNumber,
357bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                                l2capPsm,
358bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                                profileVersion,
359bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                                formatsList);
360bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
361bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID: " + Arrays.toString(uuid));
362bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString());
363bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sendSdpIntent(inst, sdpRecord, moreResults);
364bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
365bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
366bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
367bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* TODO: Test or remove! */
368bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    void sdpRecordFoundCallback(int status, byte[] address, byte[] uuid,
369bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int size_record, byte[] record) {
370bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        synchronized(mTrackerLock) {
371bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
372bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpSearchInstance inst = sSdpSearchTracker.getSearchInstance(address, uuid);
373bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpRecord sdpRecord = null;
374bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if (inst == null) {
375bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.e(TAG, "sdpRecordFoundCallback: Search instance is NULL");
376bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                return;
377bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
378bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            inst.setStatus(status);
379bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(status == AbstractionLayer.BT_STATUS_SUCCESS) {
380bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                if(D) Log.d(TAG, "sdpRecordFoundCallback: found a sdp record of size "
381bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                        + size_record );
382bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                if(D) Log.d(TAG, "Record:"+ Arrays.toString(record));
383bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                sdpRecord = new SdpRecord(size_record, record);
384bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
385bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID: " + Arrays.toString(uuid));
386bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString());
387bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sendSdpIntent(inst, sdpRecord, false);
388bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
389bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
390bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
391bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public void sdpSearch(BluetoothDevice device, ParcelUuid uuid) {
392bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if (sNativeAvailable == false) {
393bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Log.e(TAG, "Native not initialized!");
394bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            return;
395bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
396bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        synchronized (mTrackerLock) {
397bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if (sSdpSearchTracker.isSearching(device, uuid)) {
398bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                /* Search already in progress */
399bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                return;
400bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
401bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
402bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            SdpSearchInstance inst = new SdpSearchInstance(0, device, uuid);
403bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sSdpSearchTracker.add(inst); // Queue the request
404bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
405bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            startSearch(); // Start search if not busy
406bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
407bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
408bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
409bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
410bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* Caller must hold the mTrackerLock */
411bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private void startSearch() {
412bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
413bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        SdpSearchInstance inst = sSdpSearchTracker.getNext();
414bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
415bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if((inst != null) && (mSearchInProgress == false)) {
416bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "Starting search for UUID: "+ inst.getUuid());
417bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            mSearchInProgress = true;
418bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
419bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            inst.startSearch(); // Trigger timeout message
420bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
421bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sdpSearchNative(Utils.getBytesFromAddress(inst.getDevice().getAddress()),
422bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                            Utils.uuidToByteArray(inst.getUuid()));
423bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        } // Else queue is empty.
424bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        else {
425bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            if(D) Log.d(TAG, "startSearch(): nextInst = " + inst +
426bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    " mSearchInProgress = " + mSearchInProgress
427bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    + " - search busy or queue empty.");
428bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
429bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
430bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
431bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /* Caller must hold the mTrackerLock */
432bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private void sendSdpIntent(SdpSearchInstance inst,
433bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            Parcelable record, boolean moreResults) {
434bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
435bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        inst.stopSearch();
436bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
437bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        Intent intent = new Intent(BluetoothDevice.ACTION_SDP_RECORD);
438bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
439bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, inst.getDevice());
440bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        intent.putExtra(BluetoothDevice.EXTRA_SDP_SEARCH_STATUS, inst.getStatus());
441bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if (record != null)  intent.putExtra(BluetoothDevice.EXTRA_SDP_RECORD, record);
442bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        intent.putExtra(BluetoothDevice.EXTRA_UUID, inst.getUuid());
443bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        /* TODO:  BLUETOOTH_ADMIN_PERM was private... change to callback interface.
444bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde         * Keep in mind that the MAP client needs to use this as well,
445bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde         * hence to make it call-backs, the MAP client profile needs to be
446bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde         * part of the Bluetooth APK. */
447bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        sAdapterService.sendBroadcast(intent, AdapterService.BLUETOOTH_ADMIN_PERM);
448bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
449bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(moreResults == false) {
450bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            //Remove the outstanding UUID request
451bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            sSdpSearchTracker.remove(inst);
452bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            mSearchInProgress = false;
453bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            startSearch();
454bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
455bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
456bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
457bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    private final Handler mHandler = new Handler() {
458bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        @Override
459bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        public void handleMessage(Message msg) {
460bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            switch (msg.what) {
461bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            case MESSAGE_SDP_INTENT:
462bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                SdpSearchInstance msgObj = (SdpSearchInstance)msg.obj;
463bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                Log.w(TAG, "Search timedout for UUID " + msgObj.getUuid());
464bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                synchronized (mTrackerLock) {
465bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                    sendSdpIntent(msgObj, null, false);
466bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                }
467bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                break;
468bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            }
469bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
470bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    };
471bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
472bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /**
473bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Create a server side Message Access Profile Service Record.
474bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Create the record once, and reuse it for all connections.
475bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * If changes to a record is needed remove the old record using {@link removeSdpRecord}
476bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * and then create a new one.
477bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param serviceName   The textual name of the service
478bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param masId         The MAS ID to associate with this SDP record
479bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param rfcommChannel The RFCOMM channel that clients can connect to
480bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      (obtain from BluetoothServerSocket)
481bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param l2capPsm      The L2CAP PSM channel that clients can connect to
482bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      (obtain from BluetoothServerSocket)
483bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      Supply -1 to omit the L2CAP PSM from the record.
484bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param version       The Profile version number (As specified in the Bluetooth
485bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      MAP specification)
486bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param msgTypes      The supported message types bit mask (As specified in
487bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      the Bluetooth MAP specification)
488bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param features      The feature bit mask (As specified in the Bluetooth
489bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                       MAP specification)
490bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @return a handle to the record created. The record can be removed again
491bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          using {@link removeSdpRecord}(). The record is not linked to the
492bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          creation/destruction of BluetoothSockets, hence SDP record cleanup
493bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          is a separate process.
494bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     */
495bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public int createMapMasRecord(String serviceName, int masId,
496bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int rfcommChannel, int l2capPsm, int version,
497bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int msgTypes, int features) {
498bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(sNativeAvailable == false) {
499bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            throw new RuntimeException(TAG + " sNativeAvailable == false - native not initialized");
500bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
501bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return sdpCreateMapMasRecordNative(serviceName, masId, rfcommChannel,
502bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                l2capPsm, version, msgTypes, features);
503bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
504bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
505bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /**
506bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Create a client side Message Access Profile Service Record.
507bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Create the record once, and reuse it for all connections.
508bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * If changes to a record is needed remove the old record using {@link removeSdpRecord}
509bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * and then create a new one.
510bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param serviceName   The textual name of the service
511bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param rfcommChannel The RFCOMM channel that clients can connect to
512bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      (obtain from BluetoothServerSocket)
513bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param l2capPsm      The L2CAP PSM channel that clients can connect to
514bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      (obtain from BluetoothServerSocket)
515bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      Supply -1 to omit the L2CAP PSM from the record.
516bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param version       The Profile version number (As specified in the Bluetooth
517bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      MAP specification)
518bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param features      The feature bit mask (As specified in the Bluetooth
519bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                       MAP specification)
520bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @return a handle to the record created. The record can be removed again
521bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          using {@link removeSdpRecord}(). The record is not linked to the
522bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          creation/destruction of BluetoothSockets, hence SDP record cleanup
523bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          is a separate process.
524bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     */
525bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public int createMapMnsRecord(String serviceName, int rfcommChannel,
526bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            int l2capPsm, int version, int features) {
527bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(sNativeAvailable == false) {
528bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            throw new RuntimeException(TAG + " sNativeAvailable == false - native not initialized");
529bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
530bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return sdpCreateMapMnsRecordNative(serviceName, rfcommChannel,
531bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                l2capPsm, version, features);
532bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
533bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
534bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /**
535bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Create a Server side Phone Book Access Profile Service Record.
536bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Create the record once, and reuse it for all connections.
537bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * If changes to a record is needed remove the old record using {@link removeSdpRecord}
538bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * and then create a new one.
539bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param serviceName   The textual name of the service
540bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param rfcommChannel The RFCOMM channel that clients can connect to
541bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      (obtain from BluetoothServerSocket)
542bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param l2capPsm      The L2CAP PSM channel that clients can connect to
543bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      (obtain from BluetoothServerSocket)
544bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      Supply -1 to omit the L2CAP PSM from the record.
545bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param version       The Profile version number (As specified in the Bluetooth
546bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      PBAP specification)
547bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param repositories  The supported repositories bit mask (As specified in
548bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      the Bluetooth PBAP specification)
549bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param features      The feature bit mask (As specified in the Bluetooth
550bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      PBAP specification)
551bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @return a handle to the record created. The record can be removed again
552bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          using {@link removeSdpRecord}(). The record is not linked to the
553bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          creation/destruction of BluetoothSockets, hence SDP record cleanup
554bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          is a separate process.
555bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     */
556bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public int createPbapPseRecord(String serviceName, int rfcommChannel, int l2capPsm,
557bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                   int version, int repositories, int features) {
558bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(sNativeAvailable == false) {
559bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            throw new RuntimeException(TAG + " sNativeAvailable == false - native not initialized");
560bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
561bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return sdpCreatePbapPseRecordNative(serviceName, rfcommChannel,
562bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                l2capPsm, version, repositories, features);
563bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
564bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
565bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    /**
566bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Create a Server side Object Push Profile Service Record.
567bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * Create the record once, and reuse it for all connections.
568bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * If changes to a record is needed remove the old record using {@link removeSdpRecord}
569bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * and then create a new one.
570bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param serviceName   The textual name of the service
571bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param rfcommChannel The RFCOMM channel that clients can connect to
572bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      (obtain from BluetoothServerSocket)
573bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param l2capPsm      The L2CAP PSM channel that clients can connect to
574bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      (obtain from BluetoothServerSocket)
575bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      Supply -1 to omit the L2CAP PSM from the record.
576bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param version       The Profile version number (As specified in the Bluetooth
577bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      OPP specification)
578bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @param formatsList  A list of the supported formats (As specified in
579bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *                      the Bluetooth OPP specification)
580bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     * @return a handle to the record created. The record can be removed again
581bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          using {@link removeSdpRecord}(). The record is not linked to the
582bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          creation/destruction of BluetoothSockets, hence SDP record cleanup
583bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     *          is a separate process.
584bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     */
585bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public int createOppOpsRecord(String serviceName, int rfcommChannel, int l2capPsm,
586bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                                  int version, byte[] formatsList) {
587bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(sNativeAvailable == false) {
588bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            throw new RuntimeException(TAG + " sNativeAvailable == false - native not initialized");
589bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
590bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return sdpCreateOppOpsRecordNative(serviceName, rfcommChannel,
591bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde                 l2capPsm, version, formatsList);
592bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
593bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde
594bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde     /**
595bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde      * Remove a SDP record.
596bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde      * When Bluetooth is disabled all records will be deleted, hence there
597bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde      * is no need to call this function when bluetooth is disabled.
598bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde      * @param recordId The Id returned by on of the createXxxXxxRecord() functions.
599bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde      * @return TRUE if the record removal was initiated successfully. FALSE if the record
600bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde      *         handle is not known/have already been removed.
601bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde      */
602bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    public boolean removeSdpRecord(int recordId){
603bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        if(sNativeAvailable == false) {
604bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde            throw new RuntimeException(TAG + " sNativeAvailable == false - native not initialized");
605bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        }
606bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde        return sdpRemoveSdpRecordNative(recordId);
607bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde    }
608bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde}
609