• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
16 package com.android.bluetooth.gatt;
17 
18 import android.util.Log;
19 
20 import java.util.List;
21 import java.util.Map;
22 import java.util.UUID;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.CopyOnWriteArrayList;
25 
26 class HandleMap {
27     private static final String TAG = GattServiceConfig.TAG_PREFIX + "HandleMap";
28 
29     public static final int TYPE_UNDEFINED = 0;
30     public static final int TYPE_SERVICE = 1;
31     public static final int TYPE_CHARACTERISTIC = 2;
32     public static final int TYPE_DESCRIPTOR = 3;
33 
34     static class Entry {
35         public int serverIf = 0;
36         public int type = TYPE_UNDEFINED;
37         public int handle = 0;
38         public UUID uuid = null;
39         public int instance = 0;
40         public int serviceType = 0;
41         public int serviceHandle = 0;
42         public int charHandle = 0;
43         public boolean started = false;
44         public boolean advertisePreferred = false;
45 
Entry(int serverIf, int handle, UUID uuid, int serviceType, int instance)46         Entry(int serverIf, int handle, UUID uuid, int serviceType, int instance) {
47             this.serverIf = serverIf;
48             this.type = TYPE_SERVICE;
49             this.handle = handle;
50             this.uuid = uuid;
51             this.instance = instance;
52             this.serviceType = serviceType;
53         }
54 
Entry( int serverIf, int handle, UUID uuid, int serviceType, int instance, boolean advertisePreferred)55         Entry(
56                 int serverIf,
57                 int handle,
58                 UUID uuid,
59                 int serviceType,
60                 int instance,
61                 boolean advertisePreferred) {
62             this.serverIf = serverIf;
63             this.type = TYPE_SERVICE;
64             this.handle = handle;
65             this.uuid = uuid;
66             this.instance = instance;
67             this.serviceType = serviceType;
68             this.advertisePreferred = advertisePreferred;
69         }
70 
Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle)71         Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle) {
72             this.serverIf = serverIf;
73             this.type = type;
74             this.handle = handle;
75             this.uuid = uuid;
76             this.serviceHandle = serviceHandle;
77         }
78 
Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle, int charHandle)79         Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle, int charHandle) {
80             this.serverIf = serverIf;
81             this.type = type;
82             this.handle = handle;
83             this.uuid = uuid;
84             this.serviceHandle = serviceHandle;
85             this.charHandle = charHandle;
86         }
87     }
88 
89     List<Entry> mEntries = null;
90     Map<Integer, Integer> mRequestMap = null;
91     int mLastCharacteristic = 0;
92 
HandleMap()93     HandleMap() {
94         mEntries = new CopyOnWriteArrayList<Entry>();
95         mRequestMap = new ConcurrentHashMap<Integer, Integer>();
96     }
97 
clear()98     void clear() {
99         mEntries.clear();
100         mRequestMap.clear();
101     }
102 
addService( int serverIf, int handle, UUID uuid, int serviceType, int instance, boolean advertisePreferred)103     void addService(
104             int serverIf,
105             int handle,
106             UUID uuid,
107             int serviceType,
108             int instance,
109             boolean advertisePreferred) {
110         mEntries.add(new Entry(serverIf, handle, uuid, serviceType, instance, advertisePreferred));
111     }
112 
addCharacteristic(int serverIf, int handle, UUID uuid, int serviceHandle)113     void addCharacteristic(int serverIf, int handle, UUID uuid, int serviceHandle) {
114         mLastCharacteristic = handle;
115         mEntries.add(new Entry(serverIf, TYPE_CHARACTERISTIC, handle, uuid, serviceHandle));
116     }
117 
addDescriptor(int serverIf, int handle, UUID uuid, int serviceHandle)118     void addDescriptor(int serverIf, int handle, UUID uuid, int serviceHandle) {
119         mEntries.add(
120                 new Entry(
121                         serverIf,
122                         TYPE_DESCRIPTOR,
123                         handle,
124                         uuid,
125                         serviceHandle,
126                         mLastCharacteristic));
127     }
128 
setStarted(int serverIf, int handle, boolean started)129     void setStarted(int serverIf, int handle, boolean started) {
130         for (Entry entry : mEntries) {
131             if (entry.type != TYPE_SERVICE
132                     || entry.serverIf != serverIf
133                     || entry.handle != handle) {
134                 continue;
135             }
136 
137             entry.started = started;
138             return;
139         }
140     }
141 
getByHandle(int handle)142     Entry getByHandle(int handle) {
143         for (Entry entry : mEntries) {
144             if (entry.handle == handle) {
145                 return entry;
146             }
147         }
148         Log.e(TAG, "getByHandle() - Handle " + handle + " not found!");
149         return null;
150     }
151 
checkServiceExists(UUID uuid, int handle)152     boolean checkServiceExists(UUID uuid, int handle) {
153         for (Entry entry : mEntries) {
154             if (entry.type == TYPE_SERVICE && entry.handle == handle && entry.uuid.equals(uuid)) {
155                 return true;
156             }
157         }
158         return false;
159     }
160 
deleteService(int serverIf, int serviceHandle)161     void deleteService(int serverIf, int serviceHandle) {
162         mEntries.removeIf(
163                 entry ->
164                         ((entry.serverIf == serverIf)
165                                 && (entry.handle == serviceHandle
166                                         || entry.serviceHandle == serviceHandle)));
167     }
168 
getEntries()169     List<Entry> getEntries() {
170         return mEntries;
171     }
172 
addRequest(int requestId, int handle)173     void addRequest(int requestId, int handle) {
174         mRequestMap.put(requestId, handle);
175     }
176 
deleteRequest(int requestId)177     void deleteRequest(int requestId) {
178         mRequestMap.remove(requestId);
179     }
180 
getByRequestId(int requestId)181     Entry getByRequestId(int requestId) {
182         Integer handle = mRequestMap.get(requestId);
183         if (handle == null) {
184             Log.e(TAG, "getByRequestId() - Request ID " + requestId + " not found!");
185             return null;
186         }
187         return getByHandle(handle);
188     }
189 
190     /** Logs debug information. */
dump(StringBuilder sb)191     void dump(StringBuilder sb) {
192         sb.append("  Entries: " + mEntries.size() + "\n");
193         sb.append("  Requests: " + mRequestMap.size() + "\n");
194 
195         for (Entry entry : mEntries) {
196             sb.append("  " + entry.serverIf + ": [" + entry.handle + "] ");
197             switch (entry.type) {
198                 case TYPE_SERVICE:
199                     sb.append("Service " + entry.uuid);
200                     sb.append(", started " + entry.started);
201                     break;
202 
203                 case TYPE_CHARACTERISTIC:
204                     sb.append("  Characteristic " + entry.uuid);
205                     break;
206 
207                 case TYPE_DESCRIPTOR:
208                     sb.append("    Descriptor " + entry.uuid);
209                     break;
210             }
211 
212             sb.append("\n");
213         }
214     }
215 }
216