Home | History | Annotate | Download | only in gatt
      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 
     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.instance = instance;
     73             this.serviceHandle = serviceHandle;
     74         }
     75 
     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 
     91     HandleMap() {
     92         mEntries = new ArrayList<Entry>();
     93         mRequestMap = new HashMap<Integer, Integer>();
     94     }
     95 
     96     void clear() {
     97         mEntries.clear();
     98         mRequestMap.clear();
     99     }
    100 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    174     List<Entry> getEntries() {
    175         return mEntries;
    176     }
    177 
    178     void addRequest(int requestId, int handle) {
    179         mRequestMap.put(requestId, handle);
    180     }
    181 
    182     void deleteRequest(int requestId) {
    183         mRequestMap.remove(requestId);
    184     }
    185 
    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      */
    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