HandleMap.java revision eb5548e7779933cc99b0c601640be11a07d33fdf
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.bluetooth.gatt;
17
18import android.util.Log;
19import java.util.ArrayList;
20import java.util.HashMap;
21import java.util.Iterator;
22import java.util.List;
23import java.util.Map;
24import java.util.UUID;
25
26class HandleMap {
27    private static final boolean DBG = GattServiceConfig.DBG;
28    private static final String TAG = GattServiceConfig.TAG_PREFIX + "HandleMap";
29
30    public static final int TYPE_UNDEFINED = 0;
31    public static final int TYPE_SERVICE = 1;
32    public static final int TYPE_CHARACTERISTIC = 2;
33    public static final int TYPE_DESCRIPTOR = 3;
34
35    class Entry {
36        int serverIf = 0;
37        int type = TYPE_UNDEFINED;
38        int handle = 0;
39        UUID uuid = null;
40        int instance = 0;
41        int serviceType = 0;
42        int serviceHandle = 0;
43        int charHandle = 0;
44        boolean started = false;
45        boolean advertisePreferred = false;
46
47        Entry(int serverIf, int handle, UUID uuid, int serviceType, int instance) {
48            this.serverIf = serverIf;
49            this.type = TYPE_SERVICE;
50            this.handle = handle;
51            this.uuid = uuid;
52            this.instance = instance;
53            this.serviceType = serviceType;
54        }
55
56        Entry(int serverIf, int handle, UUID uuid, int serviceType, int instance,
57            boolean advertisePreferred) {
58            this.serverIf = serverIf;
59            this.type = TYPE_SERVICE;
60            this.handle = handle;
61            this.uuid = uuid;
62            this.instance = instance;
63            this.serviceType = serviceType;
64            this.advertisePreferred = advertisePreferred;
65        }
66
67        Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle) {
68            this.serverIf = serverIf;
69            this.type = type;
70            this.handle = handle;
71            this.uuid = uuid;
72            this.serviceHandle = serviceHandle;
73        }
74
75        Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle, int charHandle) {
76            this.serverIf = serverIf;
77            this.type = type;
78            this.handle = handle;
79            this.uuid = uuid;
80            this.serviceHandle = serviceHandle;
81            this.charHandle = charHandle;
82        }
83    }
84
85    List<Entry> mEntries = null;
86    Map<Integer, Integer> mRequestMap = null;
87    int mLastCharacteristic = 0;
88
89    HandleMap() {
90        mEntries = new ArrayList<Entry>();
91        mRequestMap = new HashMap<Integer, Integer>();
92    }
93
94    void clear() {
95        mEntries.clear();
96        mRequestMap.clear();
97    }
98
99    void addService(int serverIf, int handle, UUID uuid, int serviceType, int instance,
100        boolean advertisePreferred) {
101        mEntries.add(new Entry(serverIf, handle, uuid, serviceType, instance, advertisePreferred));
102    }
103
104    void addCharacteristic(int serverIf, int handle, UUID uuid, int serviceHandle) {
105        mLastCharacteristic = handle;
106        mEntries.add(new Entry(serverIf, TYPE_CHARACTERISTIC, handle, uuid, serviceHandle));
107    }
108
109    void addDescriptor(int serverIf, int handle, UUID uuid, int serviceHandle) {
110        mEntries.add(new Entry(serverIf, TYPE_DESCRIPTOR, handle, uuid, serviceHandle, mLastCharacteristic));
111    }
112
113    void setStarted(int serverIf, int handle, boolean started) {
114        for(Entry entry : mEntries) {
115            if (entry.type != TYPE_SERVICE ||
116                entry.serverIf != serverIf ||
117                entry.handle != handle)
118                continue;
119
120            entry.started = started;
121            return;
122        }
123    }
124
125    Entry getByHandle(int handle) {
126        for(Entry entry : mEntries) {
127            if (entry.handle == handle)
128                return entry;
129        }
130        Log.e(TAG, "getByHandle() - Handle " + handle + " not found!");
131        return null;
132    }
133
134    boolean checkServiceExists(UUID uuid, int handle) {
135        for(Entry entry : mEntries) {
136            if (entry.type == TYPE_SERVICE && entry.handle == handle && entry.uuid.equals(uuid)) {
137                return true;
138            }
139        }
140        return false;
141    }
142
143    void deleteService(int serverIf, int serviceHandle) {
144        for(Iterator <Entry> it = mEntries.iterator(); it.hasNext();) {
145            Entry entry = it.next();
146            if (entry.serverIf != serverIf) continue;
147
148            if (entry.handle == serviceHandle ||
149                entry.serviceHandle == serviceHandle)
150                it.remove();
151        }
152    }
153
154    List<Entry> getEntries() {
155        return mEntries;
156    }
157
158    void addRequest(int requestId, int handle) {
159        mRequestMap.put(requestId, handle);
160    }
161
162    void deleteRequest(int requestId) {
163        mRequestMap.remove(requestId);
164    }
165
166    Entry getByRequestId(int requestId) {
167        Integer handle = mRequestMap.get(requestId);
168        if (handle == null) {
169            Log.e(TAG, "getByRequestId() - Request ID " + requestId + " not found!");
170            return null;
171        }
172        return getByHandle(handle);
173    }
174
175
176    /**
177     * Logs debug information.
178     */
179    void dump(StringBuilder sb) {
180        sb.append("  Entries: " + mEntries.size() + "\n");
181        sb.append("  Requests: " + mRequestMap.size() + "\n");
182
183        for (Entry entry : mEntries) {
184            sb.append("  " + entry.serverIf + ": [" + entry.handle + "] ");
185            switch(entry.type) {
186                case TYPE_SERVICE:
187                    sb.append("Service " + entry.uuid);
188                    sb.append(", started " + entry.started);
189                    break;
190
191                case TYPE_CHARACTERISTIC:
192                    sb.append("  Characteristic " + entry.uuid);
193                    break;
194
195                case TYPE_DESCRIPTOR:
196                    sb.append("    Descriptor " + entry.uuid);
197                    break;
198            }
199
200            sb.append("\n");
201        }
202    }
203}
204