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 
     17 package com.android.bluetooth.gatt;
     18 
     19 import android.content.Intent;
     20 import android.os.Bundle;
     21 import android.util.Log;
     22 import java.util.UUID;
     23 
     24 /**
     25  * Helper class containing useful tools for GATT service debugging.
     26  */
     27 /*package*/ class GattDebugUtils {
     28     private static final String TAG = GattServiceConfig.TAG_PREFIX + "DebugUtils";
     29     private static final boolean DEBUG_ADMIN = GattServiceConfig.DEBUG_ADMIN;
     30 
     31     private static final String ACTION_DEBUG_DUMP_CLIENTMAP =
     32                                 "android.bluetooth.action.DEBUG_DUMP_CLIENTMAP";
     33     private static final String ACTION_DEBUG_DUMP_SERVERMAP =
     34                                 "android.bluetooth.action.DEBUG_DUMP_SERVERMAP";
     35     private static final String ACTION_DEBUG_DUMP_HANDLEMAP =
     36                                 "android.bluetooth.action.DEBUG_DUMP_HANDLEMAP";
     37 
     38     private static final String ACTION_GATT_PAIRING_CONFIG =
     39                                 "android.bluetooth.action.GATT_PAIRING_CONFIG";
     40 
     41     private static final String ACTION_GATT_TEST_USAGE =
     42                                 "android.bluetooth.action.GATT_TEST_USAGE";
     43     private static final String ACTION_GATT_TEST_ENABLE =
     44                                 "android.bluetooth.action.GATT_TEST_ENABLE";
     45     private static final String ACTION_GATT_TEST_CONNECT =
     46                                 "android.bluetooth.action.GATT_TEST_CONNECT";
     47     private static final String ACTION_GATT_TEST_DISCONNECT =
     48                                 "android.bluetooth.action.GATT_TEST_DISCONNECT";
     49     private static final String ACTION_GATT_TEST_DISCOVER =
     50                                 "android.bluetooth.action.GATT_TEST_DISCOVER";
     51 
     52     private static final String EXTRA_ENABLE = "enable";
     53     private static final String EXTRA_ADDRESS = "address";
     54     private static final String EXTRA_UUID = "uuid";
     55     private static final String EXTRA_TYPE = "type";
     56     private static final String EXTRA_ADDR_TYPE = "addr_type";
     57     private static final String EXTRA_SHANDLE = "start";
     58     private static final String EXTRA_EHANDLE = "end";
     59     private static final String EXTRA_AUTH_REQ = "auth_req";
     60     private static final String EXTRA_IO_CAP = "io_cap";
     61     private static final String EXTRA_INIT_KEY = "init_key";
     62     private static final String EXTRA_RESP_KEY = "resp_key";
     63     private static final String EXTRA_MAX_KEY = "max_key";
     64 
     65     /**
     66      * Handles intents passed in via GattService.onStartCommand().
     67      * This allows sending debug actions to the running service.
     68      * To trigger a debug action, invoke the following shell command:
     69      *
     70      *   adb shell am startservice -a <action> <component>
     71      *
     72      * Where <action> represents one of the ACTION_* constants defines above
     73      * and  <component> identifies the GATT service.
     74      *
     75      * For example:
     76      *   import com.android.bluetooth.gatt.GattService;
     77      */
     78     static boolean handleDebugAction(GattService svc, Intent intent) {
     79         if (!DEBUG_ADMIN) return false;
     80 
     81         String action = intent.getAction();
     82         Log.d(TAG, "handleDebugAction() action=" + action);
     83 
     84         /*
     85          * Debug log functinos
     86          */
     87 
     88         if (ACTION_DEBUG_DUMP_CLIENTMAP.equals(action)) {
     89             svc.mClientMap.dump();
     90 
     91         } else if (ACTION_DEBUG_DUMP_SERVERMAP.equals(action)) {
     92             svc.mServerMap.dump();
     93 
     94         } else if (ACTION_DEBUG_DUMP_HANDLEMAP.equals(action)) {
     95             svc.mHandleMap.dump();
     96 
     97         /*
     98          * PTS test commands
     99          */
    100 
    101         } else if (ACTION_GATT_TEST_USAGE.equals(action)) {
    102             logUsageInfo();
    103 
    104         } else if (ACTION_GATT_TEST_ENABLE.equals(action)) {
    105             boolean bEnable = intent.getBooleanExtra(EXTRA_ENABLE, true);
    106             svc.gattTestCommand( 0x01, null,null, bEnable ? 1 : 0, 0,0,0,0);
    107 
    108         } else if (ACTION_GATT_TEST_CONNECT.equals(action)) {
    109             String address = intent.getStringExtra(EXTRA_ADDRESS);
    110             int type = intent.getIntExtra(EXTRA_TYPE, 2 /* LE device */);
    111             int addr_type = intent.getIntExtra(EXTRA_ADDR_TYPE, 0 /* Static */);
    112             svc.gattTestCommand( 0x02, null, address, type, addr_type, 0,0,0);
    113 
    114         } else if (ACTION_GATT_TEST_DISCONNECT.equals(action)) {
    115             svc.gattTestCommand( 0x03, null, null, 0,0,0,0,0);
    116 
    117         } else if (ACTION_GATT_TEST_DISCOVER.equals(action)) {
    118             UUID uuid = getUuidExtra(intent);
    119             int type = intent.getIntExtra(EXTRA_TYPE, 1 /* All services */);
    120             int shdl = getHandleExtra(intent, EXTRA_SHANDLE, 1);
    121             int ehdl = getHandleExtra(intent, EXTRA_EHANDLE, 0xFFFF);
    122             svc.gattTestCommand( 0x04, uuid, null, type, shdl, ehdl, 0,0);
    123 
    124         } else if (ACTION_GATT_PAIRING_CONFIG.equals(action)) {
    125             int auth_req = intent.getIntExtra(EXTRA_AUTH_REQ, 5);
    126             int io_cap = intent.getIntExtra(EXTRA_IO_CAP, 4);
    127             int init_key = intent.getIntExtra(EXTRA_INIT_KEY, 7);
    128             int resp_key = intent.getIntExtra(EXTRA_RESP_KEY, 7);
    129             int max_key = intent.getIntExtra(EXTRA_MAX_KEY, 16);
    130             svc.gattTestCommand( 0xF0, null, null, auth_req, io_cap, init_key,
    131                                  resp_key, max_key);
    132 
    133         } else {
    134             return false;
    135         }
    136 
    137         return true;
    138     }
    139 
    140     /**
    141      * Attempts to retrieve an extra from an intent first as hex value,
    142      * then as an ineger.
    143      * @hide
    144      */
    145     static private int getHandleExtra(Intent intent, String extra, int default_value) {
    146         Bundle extras = intent.getExtras();
    147         Object uuid = extras != null ? extras.get(extra) : null;
    148         if (uuid != null && uuid.getClass().getName().equals("java.lang.String")) {
    149             try
    150             {
    151                 return Integer.parseInt(extras.getString(extra), 16);
    152             } catch (NumberFormatException e) {
    153                 return default_value;
    154             }
    155         }
    156 
    157         return intent.getIntExtra(extra, default_value);
    158     }
    159 
    160     /**
    161      * Retrieves the EXTRA_UUID parameter.
    162      * If a string of length 4 is detected, a 16-bit hex UUID is assumed and
    163      * the default Bluetooth UUID is appended.
    164      * @hide
    165      */
    166     static private UUID getUuidExtra(Intent intent) {
    167         String uuidStr = intent.getStringExtra(EXTRA_UUID);
    168         if (uuidStr != null && uuidStr.length() == 4) {
    169             uuidStr = String.format("0000%s-0000-1000-8000-00805f9b34fb", uuidStr);
    170         }
    171         return (uuidStr != null) ? UUID.fromString(uuidStr) : null;
    172     }
    173 
    174     /**
    175      * Log usage information.
    176      * @hide
    177      */
    178     static private void logUsageInfo() {
    179         StringBuilder b = new StringBuilder();
    180         b.append(  "------------ GATT TEST ACTIONS  ----------------");
    181         b.append("\nGATT_TEST_ENABLE");
    182         b.append("\n  [--ez enable <bool>] Enable or disable,");
    183         b.append("\n                       defaults to true (enable).\n");
    184         b.append("\nGATT_TEST_CONNECT");
    185         b.append("\n   --es address <bda>");
    186         b.append("\n  [--ei addr_type <type>] Possible values:");
    187         b.append("\n                         0 = Static (default)");
    188         b.append("\n                         1 = Random\n");
    189         b.append("\n  [--ei type <type>]   Default is 2 (LE Only)\n");
    190         b.append("\nGATT_TEST_DISCONNECT\n");
    191         b.append("\nGATT_TEST_DISCOVER");
    192         b.append("\n  [--ei type <type>]   Possible values:");
    193         b.append("\n                         1 = Discover all services (default)");
    194         b.append("\n                         2 = Discover services by UUID");
    195         b.append("\n                         3 = Discover included services");
    196         b.append("\n                         4 = Discover characteristics");
    197         b.append("\n                         5 = Discover descriptors\n");
    198         b.append("\n  [--es uuid <uuid>]   Optional; Can be either full 128-bit");
    199         b.append("\n                       UUID hex string, or 4 hex characters");
    200         b.append("\n                       for 16-bit UUIDs.\n");
    201         b.append("\n  [--ei start <hdl>]   Start of handle range (default 1)");
    202         b.append("\n  [--ei end <hdl>]     End of handle range (default 65355)");
    203         b.append("\n    or");
    204         b.append("\n  [--es start <hdl>]   Start of handle range (hex format)");
    205         b.append("\n  [--es end <hdl>]     End of handle range (hex format)\n");
    206         b.append("\nGATT_PAIRING_CONFIG");
    207         b.append("\n  [--ei auth_req]      Authentication flag (default 5)");
    208         b.append("\n  [--ei io_cap]        IO capabilities (default 4)");
    209         b.append("\n  [--ei init_key]      Initial key size (default 7)");
    210         b.append("\n  [--ei resp_key]      Response key size (default 7)");
    211         b.append("\n  [--ei max_key]       Maximum key size (default 16)");
    212         b.append("\n------------------------------------------------");
    213         Log.i(TAG, b.toString());
    214     }
    215 }
    216