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.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     int getServiceHandle(UUID uuid, int serviceType, int instance) {
    135         for(Entry entry : mEntries) {
    136             if (entry.type == TYPE_SERVICE &&
    137                 entry.serviceType == serviceType &&
    138                 entry.instance == instance &&
    139                 entry.uuid.equals(uuid)) {
    140                 return entry.handle;
    141             }
    142         }
    143         Log.e(TAG, "getServiceHandle() - UUID " + uuid + " not found!");
    144         return 0;
    145     }
    146 
    147     int getCharacteristicHandle(int serviceHandle, UUID uuid, int instance) {
    148         for(Entry entry : mEntries) {
    149             if (entry.type == TYPE_CHARACTERISTIC &&
    150                 entry.serviceHandle == serviceHandle &&
    151                 entry.instance == instance &&
    152                 entry.uuid.equals(uuid)) {
    153                 return entry.handle;
    154             }
    155         }
    156         Log.e(TAG, "getCharacteristicHandle() - Service " + serviceHandle
    157                     + ", UUID " + uuid + " not found!");
    158         return 0;
    159     }
    160 
    161     void deleteService(int serverIf, int serviceHandle) {
    162         for(Iterator <Entry> it = mEntries.iterator(); it.hasNext();) {
    163             Entry entry = it.next();
    164             if (entry.serverIf != serverIf) continue;
    165 
    166             if (entry.handle == serviceHandle ||
    167                 entry.serviceHandle == serviceHandle)
    168                 it.remove();
    169         }
    170     }
    171 
    172     List<Entry> getEntries() {
    173         return mEntries;
    174     }
    175 
    176     void addRequest(int requestId, int handle) {
    177         mRequestMap.put(requestId, handle);
    178     }
    179 
    180     void deleteRequest(int requestId) {
    181         mRequestMap.remove(requestId);
    182     }
    183 
    184     Entry getByRequestId(int requestId) {
    185         Integer handle = mRequestMap.get(requestId);
    186         if (handle == null) {
    187             Log.e(TAG, "getByRequestId() - Request ID " + requestId + " not found!");
    188             return null;
    189         }
    190         return getByHandle(handle);
    191     }
    192 
    193 
    194     /**
    195      * Logs debug information.
    196      */
    197     void dump(StringBuilder sb) {
    198         sb.append("  Entries: " + mEntries.size() + "\n");
    199         sb.append("  Requests: " + mRequestMap.size() + "\n");
    200 
    201         for (Entry entry : mEntries) {
    202             sb.append("  " + entry.serverIf + ": [" + entry.handle + "] ");
    203             switch(entry.type) {
    204                 case TYPE_SERVICE:
    205                     sb.append("Service " + entry.uuid);
    206                     sb.append(", started " + entry.started);
    207                     break;
    208 
    209                 case TYPE_CHARACTERISTIC:
    210                     sb.append("  Characteristic " + entry.uuid);
    211                     break;
    212 
    213                 case TYPE_DESCRIPTOR:
    214                     sb.append("    Descriptor " + entry.uuid);
    215                     break;
    216             }
    217 
    218             sb.append("\n");
    219         }
    220     }
    221 }
    222