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