Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 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 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
     33 
     34 #include "bta_gatt_api.h"
     35 #include "bte_appl.h"
     36 #include "btif_dm.h"
     37 #include "btif_gatt.h"
     38 #include "btif_gatt_util.h"
     39 #include "btif_storage.h"
     40 #include "gatt_api.h"
     41 #include "osi/include/log.h"
     42 
     43 /*******************************************************************************
     44  * Typedefs & Macros
     45  *******************************************************************************/
     46 
     47 typedef struct
     48 {
     49     tGATT_IF    gatt_if;
     50     UINT16      conn_id;
     51 } btif_test_cb_t;
     52 
     53 /*******************************************************************************
     54  * Static variables
     55  *******************************************************************************/
     56 
     57 static const char * disc_name[GATT_DISC_MAX] =
     58 {
     59     "Unknown",
     60     "GATT_DISC_SRVC_ALL",
     61     "GATT_DISC_SRVC_BY_UUID",
     62     "GATT_DISC_INC_SRVC",
     63     "GATT_DISC_CHAR",
     64     "GATT_DISC_CHAR_DSCPT"
     65 };
     66 
     67 static btif_test_cb_t test_cb;
     68 
     69 /*******************************************************************************
     70  * Callback functions
     71  *******************************************************************************/
     72 
     73 static char * format_uuid(tBT_UUID bt_uuid, char *str_buf)
     74 {
     75     int x = 0;
     76 
     77     if (bt_uuid.len == LEN_UUID_16)
     78     {
     79         sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16);
     80     }
     81     else if (bt_uuid.len == LEN_UUID_128)
     82     {
     83         x += sprintf(&str_buf[x], "%02x%02x%02x%02x-%02x%02x-%02x%02x",
     84                 bt_uuid.uu.uuid128[15], bt_uuid.uu.uuid128[14],
     85                 bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[12],
     86                 bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[10],
     87                 bt_uuid.uu.uuid128[9], bt_uuid.uu.uuid128[8]);
     88         sprintf(&str_buf[x], "%02x%02x-%02x%02x%02x%02x%02x%02x",
     89                 bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[6],
     90                 bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[4],
     91                 bt_uuid.uu.uuid128[3], bt_uuid.uu.uuid128[2],
     92                 bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[0]);
     93     }
     94     else
     95         sprintf(str_buf, "Unknown (len=%d)", bt_uuid.len);
     96 
     97     return str_buf;
     98 }
     99 
    100 static void btif_test_connect_cback(tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
    101                                     BOOLEAN connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport)
    102 {
    103     UNUSED(gatt_if);
    104     UNUSED(bda);
    105     UNUSED(reason);
    106     UNUSED (transport);
    107 
    108     LOG_DEBUG(LOG_TAG, "%s: conn_id=%d, connected=%d", __FUNCTION__, conn_id, connected);
    109     test_cb.conn_id = connected ? conn_id : 0;
    110 }
    111 
    112 static void btif_test_command_complete_cback(UINT16 conn_id, tGATTC_OPTYPE op,
    113                                 tGATT_STATUS status, tGATT_CL_COMPLETE *p_data)
    114 {
    115     LOG_DEBUG(LOG_TAG, "%s: op_code=0x%02x, conn_id=0x%x. status=0x%x",
    116             __FUNCTION__, op, conn_id, status);
    117 
    118     switch (op)
    119     {
    120         case GATTC_OPTYPE_READ:
    121         case GATTC_OPTYPE_WRITE:
    122         case GATTC_OPTYPE_CONFIG:
    123         case GATTC_OPTYPE_EXE_WRITE:
    124         case GATTC_OPTYPE_NOTIFICATION:
    125             break;
    126 
    127         case GATTC_OPTYPE_INDICATION:
    128             GATTC_SendHandleValueConfirm(conn_id, p_data->handle);
    129             break;
    130 
    131         default:
    132             LOG_DEBUG(LOG_TAG, "%s: Unknown op_code (0x%02x)", __FUNCTION__, op);
    133             break;
    134     }
    135 }
    136 
    137 static void btif_test_discovery_result_cback(UINT16 conn_id, tGATT_DISC_TYPE disc_type,
    138                                            tGATT_DISC_RES *p_data)
    139 {
    140     char    str_buf[50];
    141     UNUSED(conn_id);
    142 
    143     LOG_DEBUG(LOG_TAG, "------ GATT Discovery result %-22s -------", disc_name[disc_type]);
    144     LOG_DEBUG(LOG_TAG, "      Attribute handle: 0x%04x (%d)", p_data->handle, p_data->handle);
    145 
    146     if (disc_type != GATT_DISC_CHAR_DSCPT) {
    147         LOG_DEBUG(LOG_TAG, "        Attribute type: %s", format_uuid(p_data->type, str_buf));
    148     }
    149 
    150     switch (disc_type)
    151     {
    152         case GATT_DISC_SRVC_ALL:
    153             LOG_DEBUG(LOG_TAG, "          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
    154                   p_data->handle, p_data->value.group_value.e_handle,
    155                   p_data->handle, p_data->value.group_value.e_handle);
    156             LOG_DEBUG(LOG_TAG, "          Service UUID: %s",
    157                     format_uuid(p_data->value.group_value.service_type, str_buf));
    158             break;
    159 
    160         case GATT_DISC_SRVC_BY_UUID:
    161             LOG_DEBUG(LOG_TAG, "          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
    162                   p_data->handle, p_data->value.handle,
    163                   p_data->handle, p_data->value.handle);
    164             break;
    165 
    166         case GATT_DISC_INC_SRVC:
    167             LOG_DEBUG(LOG_TAG, "          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
    168                   p_data->value.incl_service.s_handle, p_data->value.incl_service.e_handle,
    169                   p_data->value.incl_service.s_handle, p_data->value.incl_service.e_handle);
    170             LOG_DEBUG(LOG_TAG, "          Service UUID: %s",
    171                   format_uuid(p_data->value.incl_service.service_type, str_buf));
    172             break;
    173 
    174         case GATT_DISC_CHAR:
    175             LOG_DEBUG(LOG_TAG, "            Properties: 0x%02x",
    176                   p_data->value.dclr_value.char_prop);
    177             LOG_DEBUG(LOG_TAG, "   Characteristic UUID: %s",
    178                   format_uuid(p_data->value.dclr_value.char_uuid, str_buf));
    179             break;
    180 
    181         case GATT_DISC_CHAR_DSCPT:
    182             LOG_DEBUG(LOG_TAG, "       Descriptor UUID: %s", format_uuid(p_data->type, str_buf));
    183             break;
    184     }
    185 
    186     LOG_DEBUG(LOG_TAG, "-----------------------------------------------------------");
    187 }
    188 
    189 static void btif_test_discovery_complete_cback(UINT16 conn_id,
    190                                                tGATT_DISC_TYPE disc_type,
    191                                                tGATT_STATUS status)
    192 {
    193     UNUSED(conn_id);
    194     UNUSED(disc_type);
    195     LOG_DEBUG(LOG_TAG, "%s: status=%d", __FUNCTION__, status);
    196 }
    197 
    198 static tGATT_CBACK btif_test_callbacks =
    199 {
    200     btif_test_connect_cback ,
    201     btif_test_command_complete_cback,
    202     btif_test_discovery_result_cback,
    203     btif_test_discovery_complete_cback,
    204     NULL,
    205     NULL,
    206     NULL
    207 };
    208 
    209 /*******************************************************************************
    210  * Implementation
    211  *******************************************************************************/
    212 
    213 bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t* params)
    214 {
    215     switch(command) {
    216         case 0x01: /* Enable */
    217         {
    218             LOG_DEBUG(LOG_TAG, "%s: ENABLE - enable=%d", __FUNCTION__, params->u1);
    219             if (params->u1)
    220             {
    221                 tBT_UUID app_uuid = {LEN_UUID_128,{0xAE}};
    222                 test_cb.gatt_if = GATT_Register(&app_uuid, &btif_test_callbacks);
    223                 GATT_StartIf(test_cb.gatt_if);
    224             } else {
    225                 GATT_Deregister(test_cb.gatt_if);
    226                 test_cb.gatt_if = 0;
    227             }
    228             break;
    229         }
    230 
    231         case 0x02: /* Connect */
    232         {
    233             LOG_DEBUG(LOG_TAG, "%s: CONNECT - device=%02x:%02x:%02x:%02x:%02x:%02x (dev_type=%d, addr_type=%d)",
    234                 __FUNCTION__,
    235                 params->bda1->address[0], params->bda1->address[1],
    236                 params->bda1->address[2], params->bda1->address[3],
    237                 params->bda1->address[4], params->bda1->address[5],
    238                 params->u1, params->u2);
    239 
    240             if (params->u1 == BT_DEVICE_TYPE_BLE)
    241                 BTM_SecAddBleDevice(params->bda1->address, NULL, BT_DEVICE_TYPE_BLE, params->u2);
    242 
    243             if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, true, BT_TRANSPORT_LE, false) )
    244             {
    245                 LOG_ERROR(LOG_TAG, "%s: GATT_Connect failed!", __FUNCTION__);
    246             }
    247             break;
    248         }
    249 
    250         case 0x03: /* Disconnect */
    251         {
    252             LOG_DEBUG(LOG_TAG, "%s: DISCONNECT - conn_id=%d", __FUNCTION__, test_cb.conn_id);
    253             GATT_Disconnect(test_cb.conn_id);
    254             break;
    255         }
    256 
    257         case 0x04: /* Discover */
    258         {
    259             char buf[50] = {0};
    260             tGATT_DISC_PARAM        param;
    261             memset(&param, 0, sizeof(tGATT_DISC_PARAM));
    262 
    263             if (params->u1 >= GATT_DISC_MAX)
    264             {
    265                 LOG_ERROR(LOG_TAG, "%s: DISCOVER - Invalid type (%d)!", __FUNCTION__, params->u1);
    266                 return 0;
    267             }
    268 
    269             param.s_handle = params->u2;
    270             param.e_handle = params->u3;
    271             btif_to_bta_uuid(&param.service, params->uuid1);
    272 
    273             LOG_DEBUG(LOG_TAG, "%s: DISCOVER (%s), conn_id=%d, uuid=%s, handles=0x%04x-0x%04x",
    274                   __FUNCTION__, disc_name[params->u1], test_cb.conn_id,
    275                   format_uuid(param.service, buf), params->u2, params->u3);
    276             GATTC_Discover(test_cb.conn_id, params->u1, &param);
    277             break;
    278         }
    279 
    280         case 0xF0: /* Pairing configuration */
    281             LOG_DEBUG(LOG_TAG, "%s: Setting pairing config auth=%d, iocaps=%d, keys=%d/%d/%d",
    282                   __FUNCTION__, params->u1, params->u2, params->u3, params->u4,
    283                   params->u5);
    284 
    285             bte_appl_cfg.ble_auth_req = params->u1;
    286             bte_appl_cfg.ble_io_cap = params->u2;
    287             bte_appl_cfg.ble_init_key = params->u3;
    288             bte_appl_cfg.ble_resp_key = params->u4;
    289             bte_appl_cfg.ble_max_key_size = params->u5;
    290             break;
    291 
    292         default:
    293             LOG_ERROR(LOG_TAG, "%s: UNKNOWN TEST COMMAND 0x%02x", __FUNCTION__, command);
    294             break;
    295     }
    296     return 0;
    297 }
    298 
    299 #endif
    300