Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright 2009-2013 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #define LOG_TAG "bt_btif_gatt"
     20 
     21 #include <errno.h>
     22 #include <stdio.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 
     26 #include <hardware/bluetooth.h>
     27 #include <hardware/bt_gatt.h>
     28 
     29 #include "btif_common.h"
     30 #include "btif_util.h"
     31 
     32 #include "bta_gatt_api.h"
     33 #include "bte_appl.h"
     34 #include "btif_dm.h"
     35 #include "btif_gatt.h"
     36 #include "btif_gatt_util.h"
     37 #include "btif_storage.h"
     38 #include "gatt_api.h"
     39 #include "osi/include/log.h"
     40 #include "osi/include/osi.h"
     41 
     42 using bluetooth::Uuid;
     43 /*******************************************************************************
     44  * Typedefs & Macros
     45  ******************************************************************************/
     46 
     47 typedef struct {
     48   tGATT_IF gatt_if;
     49   uint16_t conn_id;
     50 } btif_test_cb_t;
     51 
     52 /*******************************************************************************
     53  * Static variables
     54  ******************************************************************************/
     55 
     56 static const char* disc_name[GATT_DISC_MAX] = {"Unknown",
     57                                                "GATT_DISC_SRVC_ALL",
     58                                                "GATT_DISC_SRVC_BY_UUID",
     59                                                "GATT_DISC_INC_SRVC",
     60                                                "GATT_DISC_CHAR",
     61                                                "GATT_DISC_CHAR_DSCPT"};
     62 
     63 static btif_test_cb_t test_cb;
     64 
     65 /*******************************************************************************
     66  * Callback functions
     67  ******************************************************************************/
     68 
     69 static void btif_test_connect_cback(tGATT_IF, const RawAddress&,
     70                                     uint16_t conn_id, bool connected,
     71                                     tGATT_DISCONN_REASON, tBT_TRANSPORT) {
     72   LOG_DEBUG(LOG_TAG, "%s: conn_id=%d, connected=%d", __func__, conn_id,
     73             connected);
     74   test_cb.conn_id = connected ? conn_id : 0;
     75 }
     76 
     77 static void btif_test_command_complete_cback(uint16_t conn_id, tGATTC_OPTYPE op,
     78                                              tGATT_STATUS status,
     79                                              tGATT_CL_COMPLETE* p_data) {
     80   LOG_DEBUG(LOG_TAG, "%s: op_code=0x%02x, conn_id=0x%x. status=0x%x", __func__,
     81             op, conn_id, status);
     82 
     83   switch (op) {
     84     case GATTC_OPTYPE_READ:
     85     case GATTC_OPTYPE_WRITE:
     86     case GATTC_OPTYPE_CONFIG:
     87     case GATTC_OPTYPE_EXE_WRITE:
     88     case GATTC_OPTYPE_NOTIFICATION:
     89       break;
     90 
     91     case GATTC_OPTYPE_INDICATION:
     92       GATTC_SendHandleValueConfirm(conn_id, p_data->handle);
     93       break;
     94 
     95     default:
     96       LOG_DEBUG(LOG_TAG, "%s: Unknown op_code (0x%02x)", __func__, op);
     97       break;
     98   }
     99 }
    100 
    101 static void btif_test_discovery_result_cback(UNUSED_ATTR uint16_t conn_id,
    102                                              tGATT_DISC_TYPE disc_type,
    103                                              tGATT_DISC_RES* p_data) {
    104   LOG_DEBUG(LOG_TAG, "------ GATT Discovery result %-22s -------",
    105             disc_name[disc_type]);
    106   LOG_DEBUG(LOG_TAG, "      Attribute handle: 0x%04x (%d)", p_data->handle,
    107             p_data->handle);
    108 
    109   if (disc_type != GATT_DISC_CHAR_DSCPT) {
    110     LOG_DEBUG(LOG_TAG, "        Attribute type: %s",
    111               p_data->type.ToString().c_str());
    112   }
    113 
    114   switch (disc_type) {
    115     case GATT_DISC_SRVC_ALL:
    116       LOG_DEBUG(LOG_TAG, "          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
    117                 p_data->handle, p_data->value.group_value.e_handle,
    118                 p_data->handle, p_data->value.group_value.e_handle);
    119       LOG_DEBUG(LOG_TAG, "          Service UUID: %s",
    120                 p_data->value.group_value.service_type.ToString().c_str());
    121       break;
    122 
    123     case GATT_DISC_SRVC_BY_UUID:
    124       LOG_DEBUG(LOG_TAG, "          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
    125                 p_data->handle, p_data->value.handle, p_data->handle,
    126                 p_data->value.handle);
    127       break;
    128 
    129     case GATT_DISC_INC_SRVC:
    130       LOG_DEBUG(LOG_TAG, "          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
    131                 p_data->value.incl_service.s_handle,
    132                 p_data->value.incl_service.e_handle,
    133                 p_data->value.incl_service.s_handle,
    134                 p_data->value.incl_service.e_handle);
    135       LOG_DEBUG(LOG_TAG, "          Service UUID: %s",
    136                 p_data->value.incl_service.service_type.ToString().c_str());
    137       break;
    138 
    139     case GATT_DISC_CHAR:
    140       LOG_DEBUG(LOG_TAG, "            Properties: 0x%02x",
    141                 p_data->value.dclr_value.char_prop);
    142       LOG_DEBUG(LOG_TAG, "   Characteristic UUID: %s",
    143                 p_data->value.dclr_value.char_uuid.ToString().c_str());
    144       break;
    145 
    146     case GATT_DISC_CHAR_DSCPT:
    147       LOG_DEBUG(LOG_TAG, "       Descriptor UUID: %s",
    148                 p_data->type.ToString().c_str());
    149       break;
    150   }
    151 
    152   LOG_DEBUG(LOG_TAG,
    153             "-----------------------------------------------------------");
    154 }
    155 
    156 static void btif_test_discovery_complete_cback(
    157     UNUSED_ATTR uint16_t conn_id, UNUSED_ATTR tGATT_DISC_TYPE disc_type,
    158     tGATT_STATUS status) {
    159   LOG_DEBUG(LOG_TAG, "%s: status=%d", __func__, status);
    160 }
    161 
    162 static tGATT_CBACK btif_test_callbacks = {btif_test_connect_cback,
    163                                           btif_test_command_complete_cback,
    164                                           btif_test_discovery_result_cback,
    165                                           btif_test_discovery_complete_cback,
    166                                           NULL,
    167                                           NULL,
    168                                           NULL,
    169                                           NULL,
    170                                           NULL};
    171 
    172 /*******************************************************************************
    173  * Implementation
    174  ******************************************************************************/
    175 
    176 bt_status_t btif_gattc_test_command_impl(int command,
    177                                          const btgatt_test_params_t* params) {
    178   switch (command) {
    179     case 0x01: /* Enable */
    180     {
    181       LOG_DEBUG(LOG_TAG, "%s: ENABLE - enable=%d", __func__, params->u1);
    182       if (params->u1) {
    183         std::array<uint8_t, Uuid::kNumBytes128> tmp;
    184         tmp.fill(0xAE);
    185         test_cb.gatt_if = GATT_Register(bluetooth::Uuid::From128BitBE(tmp),
    186                                         &btif_test_callbacks);
    187         GATT_StartIf(test_cb.gatt_if);
    188       } else {
    189         GATT_Deregister(test_cb.gatt_if);
    190         test_cb.gatt_if = 0;
    191       }
    192       break;
    193     }
    194 
    195     case 0x02: /* Connect */
    196     {
    197       LOG_DEBUG(LOG_TAG, "%s: CONNECT - device=%s (dev_type=%d, addr_type=%d)",
    198                 __func__, params->bda1->ToString().c_str(), params->u1,
    199                 params->u2);
    200 
    201       if (params->u1 == BT_DEVICE_TYPE_BLE)
    202         BTM_SecAddBleDevice(*params->bda1, NULL, BT_DEVICE_TYPE_BLE,
    203                             params->u2);
    204 
    205       if (!GATT_Connect(test_cb.gatt_if, *params->bda1, true, BT_TRANSPORT_LE,
    206                         false)) {
    207         LOG_ERROR(LOG_TAG, "%s: GATT_Connect failed!", __func__);
    208       }
    209       break;
    210     }
    211 
    212     case 0x03: /* Disconnect */
    213     {
    214       LOG_DEBUG(LOG_TAG, "%s: DISCONNECT - conn_id=%d", __func__,
    215                 test_cb.conn_id);
    216       GATT_Disconnect(test_cb.conn_id);
    217       break;
    218     }
    219 
    220     case 0x04: /* Discover */
    221     {
    222       tGATT_DISC_PARAM param;
    223       memset(&param, 0, sizeof(tGATT_DISC_PARAM));
    224 
    225       if (params->u1 >= GATT_DISC_MAX) {
    226         LOG_ERROR(LOG_TAG, "%s: DISCOVER - Invalid type (%d)!", __func__,
    227                   params->u1);
    228         return (bt_status_t)0;
    229       }
    230 
    231       param.s_handle = params->u2;
    232       param.e_handle = params->u3;
    233       param.service = *params->uuid1;
    234 
    235       LOG_DEBUG(LOG_TAG,
    236                 "%s: DISCOVER (%s), conn_id=%d, uuid=%s, handles=0x%04x-0x%04x",
    237                 __func__, disc_name[params->u1], test_cb.conn_id,
    238                 param.service.ToString().c_str(), params->u2, params->u3);
    239       GATTC_Discover(test_cb.conn_id, params->u1, &param);
    240       break;
    241     }
    242 
    243     case 0xF0: /* Pairing configuration */
    244       LOG_DEBUG(LOG_TAG,
    245                 "%s: Setting pairing config auth=%d, iocaps=%d, keys=%d/%d/%d",
    246                 __func__, params->u1, params->u2, params->u3, params->u4,
    247                 params->u5);
    248 
    249       bte_appl_cfg.ble_auth_req = params->u1;
    250       bte_appl_cfg.ble_io_cap = params->u2;
    251       bte_appl_cfg.ble_init_key = params->u3;
    252       bte_appl_cfg.ble_resp_key = params->u4;
    253       bte_appl_cfg.ble_max_key_size = params->u5;
    254       break;
    255 
    256     default:
    257       LOG_ERROR(LOG_TAG, "%s: UNKNOWN TEST COMMAND 0x%02x", __func__, command);
    258       break;
    259   }
    260   return (bt_status_t)0;
    261 }
    262