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 import java.util.ArrayList; 20 import java.util.HashMap; 21 import java.util.Iterator; 22 import java.util.List; 23 import java.util.Map; 24 import java.util.UUID; 25 26 class 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 Entry(int serverIf, int handle, UUID uuid, int serviceType, int instance)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 Entry(int serverIf, int handle, UUID uuid, int serviceType, int instance, boolean advertisePreferred)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 Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle)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.instance = instance; 73 this.serviceHandle = serviceHandle; 74 } 75 Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle, int charHandle)76 Entry(int serverIf, int type, int handle, UUID uuid, int serviceHandle, int charHandle) { 77 this.serverIf = serverIf; 78 this.type = type; 79 this.handle = handle; 80 this.uuid = uuid; 81 this.instance = instance; 82 this.serviceHandle = serviceHandle; 83 this.charHandle = charHandle; 84 } 85 } 86 87 List<Entry> mEntries = null; 88 Map<Integer, Integer> mRequestMap = null; 89 int mLastCharacteristic = 0; 90 HandleMap()91 HandleMap() { 92 mEntries = new ArrayList<Entry>(); 93 mRequestMap = new HashMap<Integer, Integer>(); 94 } 95 clear()96 void clear() { 97 mEntries.clear(); 98 mRequestMap.clear(); 99 } 100 addService(int serverIf, int handle, UUID uuid, int serviceType, int instance, boolean advertisePreferred)101 void addService(int serverIf, int handle, UUID uuid, int serviceType, int instance, 102 boolean advertisePreferred) { 103 mEntries.add(new Entry(serverIf, handle, uuid, serviceType, instance, advertisePreferred)); 104 } 105 addCharacteristic(int serverIf, int handle, UUID uuid, int serviceHandle)106 void addCharacteristic(int serverIf, int handle, UUID uuid, int serviceHandle) { 107 mLastCharacteristic = handle; 108 mEntries.add(new Entry(serverIf, TYPE_CHARACTERISTIC, handle, uuid, serviceHandle)); 109 } 110 addDescriptor(int serverIf, int handle, UUID uuid, int serviceHandle)111 void addDescriptor(int serverIf, int handle, UUID uuid, int serviceHandle) { 112 mEntries.add(new Entry(serverIf, TYPE_DESCRIPTOR, handle, uuid, serviceHandle, mLastCharacteristic)); 113 } 114 setStarted(int serverIf, int handle, boolean started)115 void setStarted(int serverIf, int handle, boolean started) { 116 for(Entry entry : mEntries) { 117 if (entry.type != TYPE_SERVICE || 118 entry.serverIf != serverIf || 119 entry.handle != handle) 120 continue; 121 122 entry.started = started; 123 return; 124 } 125 } 126 getByHandle(int handle)127 Entry getByHandle(int handle) { 128 for(Entry entry : mEntries) { 129 if (entry.handle == handle) 130 return entry; 131 } 132 Log.e(TAG, "getByHandle() - Handle " + handle + " not found!"); 133 return null; 134 } 135 getServiceHandle(UUID uuid, int serviceType, int instance)136 int getServiceHandle(UUID uuid, int serviceType, int instance) { 137 for(Entry entry : mEntries) { 138 if (entry.type == TYPE_SERVICE && 139 entry.serviceType == serviceType && 140 entry.instance == instance && 141 entry.uuid.equals(uuid)) { 142 return entry.handle; 143 } 144 } 145 Log.e(TAG, "getServiceHandle() - UUID " + uuid + " not found!"); 146 return 0; 147 } 148 getCharacteristicHandle(int serviceHandle, UUID uuid, int instance)149 int getCharacteristicHandle(int serviceHandle, UUID uuid, int instance) { 150 for(Entry entry : mEntries) { 151 if (entry.type == TYPE_CHARACTERISTIC && 152 entry.serviceHandle == serviceHandle && 153 entry.instance == instance && 154 entry.uuid.equals(uuid)) { 155 return entry.handle; 156 } 157 } 158 Log.e(TAG, "getCharacteristicHandle() - Service " + serviceHandle 159 + ", UUID " + uuid + " not found!"); 160 return 0; 161 } 162 deleteService(int serverIf, int serviceHandle)163 void deleteService(int serverIf, int serviceHandle) { 164 for(Iterator <Entry> it = mEntries.iterator(); it.hasNext();) { 165 Entry entry = it.next(); 166 if (entry.serverIf != serverIf) continue; 167 168 if (entry.handle == serviceHandle || 169 entry.serviceHandle == serviceHandle) 170 it.remove(); 171 } 172 } 173 getEntries()174 List<Entry> getEntries() { 175 return mEntries; 176 } 177 addRequest(int requestId, int handle)178 void addRequest(int requestId, int handle) { 179 mRequestMap.put(requestId, handle); 180 } 181 deleteRequest(int requestId)182 void deleteRequest(int requestId) { 183 mRequestMap.remove(requestId); 184 } 185 getByRequestId(int requestId)186 Entry getByRequestId(int requestId) { 187 Integer handle = mRequestMap.get(requestId); 188 if (handle == null) { 189 Log.e(TAG, "getByRequestId() - Request ID " + requestId + " not found!"); 190 return null; 191 } 192 return getByHandle(handle); 193 } 194 195 196 /** 197 * Logs debug information. 198 */ dump(StringBuilder sb)199 void dump(StringBuilder sb) { 200 sb.append(" Entries: " + mEntries.size() + "\n"); 201 sb.append(" Requests: " + mRequestMap.size() + "\n"); 202 203 for (Entry entry : mEntries) { 204 sb.append(" " + entry.serverIf + ": [" + entry.handle + "] "); 205 switch(entry.type) { 206 case TYPE_SERVICE: 207 sb.append("Service " + entry.uuid); 208 sb.append(", started " + entry.started); 209 break; 210 211 case TYPE_CHARACTERISTIC: 212 sb.append(" Characteristic " + entry.uuid); 213 break; 214 215 case TYPE_DESCRIPTOR: 216 sb.append(" Descriptor " + entry.uuid); 217 break; 218 } 219 220 sb.append("\n"); 221 } 222 } 223 } 224