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 
     20 /*******************************************************************************
     21  *
     22  *  Filename:      btif_gatt_client.c
     23  *
     24  *  Description:   GATT client implementation
     25  *
     26  *******************************************************************************/
     27 
     28 #include <hardware/bluetooth.h>
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <errno.h>
     32 #include <string.h>
     33 
     34 #define LOG_TAG "BtGatt.btif"
     35 
     36 #include "btif_common.h"
     37 #include "btif_util.h"
     38 
     39 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
     40 
     41 #include "gki.h"
     42 #include <hardware/bt_gatt.h>
     43 #include "bta_api.h"
     44 #include "bta_gatt_api.h"
     45 #include "bd.h"
     46 #include "btif_storage.h"
     47 #include "btif_config.h"
     48 
     49 #include "btif_gatt.h"
     50 #include "btif_gatt_util.h"
     51 #include "btif_dm.h"
     52 #include "btif_storage.h"
     53 
     54 /*******************************************************************************
     55 **  Constants & Macros
     56 ********************************************************************************/
     57 
     58 #define ADV_FLAGS 0x02
     59 
     60 #define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
     61     {\
     62         ALOGW("%s: BTGATT not initialized", __FUNCTION__);\
     63         return BT_STATUS_NOT_READY;\
     64     } else {\
     65         ALOGD("%s", __FUNCTION__);\
     66     }
     67 
     68 
     69 typedef enum {
     70     BTIF_GATTC_REGISTER_APP = 1000,
     71     BTIF_GATTC_UNREGISTER_APP,
     72     BTIF_GATTC_SCAN_START,
     73     BTIF_GATTC_SCAN_STOP,
     74     BTIF_GATTC_OPEN,
     75     BTIF_GATTC_CLOSE,
     76     BTIF_GATTC_SEARCH_SERVICE,
     77     BTIF_GATTC_GET_FIRST_CHAR,
     78     BTIF_GATTC_GET_NEXT_CHAR,
     79     BTIF_GATTC_GET_FIRST_CHAR_DESCR,
     80     BTIF_GATTC_GET_NEXT_CHAR_DESCR,
     81     BTIF_GATTC_GET_FIRST_INCL_SERVICE,
     82     BTIF_GATTC_GET_NEXT_INCL_SERVICE,
     83     BTIF_GATTC_READ_CHAR,
     84     BTIF_GATTC_READ_CHAR_DESCR,
     85     BTIF_GATTC_WRITE_CHAR,
     86     BTIF_GATTC_WRITE_CHAR_DESCR,
     87     BTIF_GATTC_EXECUTE_WRITE,
     88     BTIF_GATTC_REG_FOR_NOTIFICATION,
     89     BTIF_GATTC_DEREG_FOR_NOTIFICATION,
     90     BTIF_GATTC_REFRESH,
     91     BTIF_GATTC_READ_RSSI,
     92     BTIF_GATTC_LISTEN,
     93     BTIF_GATTC_SET_ADV_DATA
     94 } btif_gattc_event_t;
     95 
     96 #define BTIF_GATT_MAX_OBSERVED_DEV 40
     97 
     98 #define BTIF_GATT_OBSERVE_EVT   0x1000
     99 #define BTIF_GATTC_RSSI_EVT     0x1001
    100 
    101 /*******************************************************************************
    102 **  Local type definitions
    103 ********************************************************************************/
    104 
    105 typedef struct
    106 {
    107     tBTM_BLE_AD_MASK mask;
    108     tBTM_BLE_ADV_DATA data;
    109 } btgatt_adv_data;
    110 
    111 typedef struct
    112 {
    113     uint8_t     value[BTGATT_MAX_ATTR_LEN];
    114     btgatt_adv_data adv_data;
    115     bt_bdaddr_t bd_addr;
    116     btgatt_srvc_id_t srvc_id;
    117     btgatt_srvc_id_t incl_srvc_id;
    118     btgatt_gatt_id_t char_id;
    119     btgatt_gatt_id_t descr_id;
    120     bt_uuid_t   uuid;
    121     uint16_t    conn_id;
    122     uint16_t    len;
    123     uint8_t     client_if;
    124     uint8_t     action;
    125     uint8_t     is_direct;
    126     uint8_t     search_all;
    127     uint8_t     auth_req;
    128     uint8_t     write_type;
    129     uint8_t     status;
    130     uint8_t     addr_type;
    131     uint8_t     start;
    132     int8_t      rssi;
    133     tBT_DEVICE_TYPE device_type;
    134 } __attribute__((packed)) btif_gattc_cb_t;
    135 
    136 typedef struct
    137 {
    138     bt_bdaddr_t bd_addr;
    139     BOOLEAN     in_use;
    140 }__attribute__((packed)) btif_gattc_dev_t;
    141 
    142 typedef struct
    143 {
    144     btif_gattc_dev_t remote_dev[BTIF_GATT_MAX_OBSERVED_DEV];
    145     uint8_t        addr_type;
    146     uint8_t        next_storage_idx;
    147 }__attribute__((packed)) btif_gattc_dev_cb_t;
    148 
    149 /*******************************************************************************
    150 **  Static variables
    151 ********************************************************************************/
    152 
    153 extern const btgatt_callbacks_t *bt_gatt_callbacks;
    154 static btif_gattc_dev_cb_t  btif_gattc_dev_cb;
    155 static btif_gattc_dev_cb_t  *p_dev_cb = &btif_gattc_dev_cb;
    156 static uint8_t rssi_request_client_if;
    157 
    158 /*******************************************************************************
    159 **  Static functions
    160 ********************************************************************************/
    161 
    162 static void btapp_gattc_req_data(UINT16 event, char *p_dest, char *p_src)
    163 {
    164     tBTA_GATTC *p_dest_data = (tBTA_GATTC*)p_dest;
    165     tBTA_GATTC *p_src_data = (tBTA_GATTC*)p_src;
    166 
    167     if (!p_src_data || !p_dest_data)
    168        return;
    169 
    170     // Copy basic structure first
    171     memcpy(p_dest_data, p_src_data, sizeof(tBTA_GATTC));
    172 
    173     // Allocate buffer for request data if necessary
    174     switch (event)
    175     {
    176         case BTA_GATTC_READ_CHAR_EVT:
    177         case BTA_GATTC_READ_DESCR_EVT:
    178 
    179             if (p_src_data->read.p_value != NULL)
    180             {
    181                 p_dest_data->read.p_value = GKI_getbuf(sizeof(tBTA_GATT_READ_VAL));
    182 
    183                 if (p_dest_data->read.p_value != NULL)
    184                 {
    185                     memcpy(p_dest_data->read.p_value, p_src_data->read.p_value,
    186                         sizeof(tBTA_GATT_READ_VAL));
    187 
    188                     // Allocate buffer for att value if necessary
    189                     if (get_uuid16(&p_src_data->read.descr_type.uuid) != GATT_UUID_CHAR_AGG_FORMAT
    190                       && p_src_data->read.p_value->unformat.len > 0
    191                       && p_src_data->read.p_value->unformat.p_value != NULL)
    192                     {
    193                         p_dest_data->read.p_value->unformat.p_value =
    194                                        GKI_getbuf(p_src_data->read.p_value->unformat.len);
    195                         if (p_dest_data->read.p_value->unformat.p_value != NULL)
    196                         {
    197                             memcpy(p_dest_data->read.p_value->unformat.p_value,
    198                                    p_src_data->read.p_value->unformat.p_value,
    199                                    p_src_data->read.p_value->unformat.len);
    200                         }
    201                     }
    202                 }
    203             }
    204             else
    205             {
    206                 BTIF_TRACE_WARNING2("%s :Src read.p_value ptr is NULL for event  0x%x",
    207                                     __FUNCTION__, event);
    208                 p_dest_data->read.p_value = NULL;
    209 
    210             }
    211             break;
    212 
    213         default:
    214             break;
    215     }
    216 }
    217 
    218 static void btapp_gattc_free_req_data(UINT16 event, tBTA_GATTC *p_data)
    219 {
    220     switch (event)
    221     {
    222         case BTA_GATTC_READ_CHAR_EVT:
    223         case BTA_GATTC_READ_DESCR_EVT:
    224             if (p_data != NULL && p_data->read.p_value != NULL)
    225             {
    226                 if (get_uuid16 (&p_data->read.descr_type.uuid) != GATT_UUID_CHAR_AGG_FORMAT
    227                   && p_data->read.p_value->unformat.len > 0
    228                   && p_data->read.p_value->unformat.p_value != NULL)
    229                 {
    230                     GKI_freebuf(p_data->read.p_value->unformat.p_value);
    231                 }
    232                 GKI_freebuf(p_data->read.p_value);
    233             }
    234             break;
    235 
    236         default:
    237             break;
    238     }
    239 }
    240 
    241 static void btif_gattc_init_dev_cb(void)
    242 {
    243     memset(p_dev_cb, 0, sizeof(btif_gattc_dev_cb_t));
    244 }
    245 
    246 static void btif_gattc_add_remote_bdaddr (BD_ADDR p_bda, uint8_t addr_type)
    247 {
    248     BOOLEAN found=FALSE;
    249     uint8_t i;
    250     for (i = 0; i < BTIF_GATT_MAX_OBSERVED_DEV; i++)
    251     {
    252         if (!p_dev_cb->remote_dev[i].in_use )
    253         {
    254             memcpy(p_dev_cb->remote_dev[i].bd_addr.address, p_bda, BD_ADDR_LEN);
    255             p_dev_cb->addr_type = addr_type;
    256             p_dev_cb->remote_dev[i].in_use = TRUE;
    257             ALOGD("%s device added idx=%d", __FUNCTION__, i  );
    258             break;
    259         }
    260     }
    261 
    262     if ( i == BTIF_GATT_MAX_OBSERVED_DEV)
    263     {
    264         i= p_dev_cb->next_storage_idx;
    265         memcpy(p_dev_cb->remote_dev[i].bd_addr.address, p_bda, BD_ADDR_LEN);
    266         p_dev_cb->addr_type = addr_type;
    267         p_dev_cb->remote_dev[i].in_use = TRUE;
    268         ALOGD("%s device overwrite idx=%d", __FUNCTION__, i  );
    269         p_dev_cb->next_storage_idx++;
    270         if(p_dev_cb->next_storage_idx >= BTIF_GATT_MAX_OBSERVED_DEV)
    271                p_dev_cb->next_storage_idx = 0;
    272     }
    273 }
    274 
    275 static BOOLEAN btif_gattc_find_bdaddr (BD_ADDR p_bda)
    276 {
    277     uint8_t i;
    278     for (i = 0; i < BTIF_GATT_MAX_OBSERVED_DEV; i++)
    279     {
    280         if (p_dev_cb->remote_dev[i].in_use &&
    281             !memcmp(p_dev_cb->remote_dev[i].bd_addr.address, p_bda, BD_ADDR_LEN))
    282         {
    283             return TRUE;
    284         }
    285     }
    286     return FALSE;
    287 }
    288 
    289 static void btif_gattc_update_properties ( btif_gattc_cb_t *p_btif_cb )
    290 {
    291     uint8_t remote_name_len;
    292     uint8_t *p_eir_remote_name=NULL;
    293     bt_bdname_t bdname;
    294 
    295     p_eir_remote_name = BTA_CheckEirData(p_btif_cb->value,
    296                                          BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
    297 
    298     if(p_eir_remote_name == NULL)
    299     {
    300         p_eir_remote_name = BTA_CheckEirData(p_btif_cb->value,
    301                                 BT_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
    302     }
    303 
    304     if(p_eir_remote_name)
    305     {
    306          memcpy(bdname.name, p_eir_remote_name, remote_name_len);
    307          bdname.name[remote_name_len]='\0';
    308 
    309         ALOGD("%s BLE device name=%s len=%d dev_type=%d", __FUNCTION__, bdname.name,
    310               remote_name_len, p_btif_cb->device_type  );
    311         btif_dm_update_ble_remote_properties( p_btif_cb->bd_addr.address,   bdname.name,
    312                                                p_btif_cb->device_type);
    313     }
    314 
    315     btif_storage_set_remote_addr_type( &p_btif_cb->bd_addr, p_btif_cb->addr_type);
    316 }
    317 
    318 static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
    319 {
    320     ALOGD("%s: Event %d", __FUNCTION__, event);
    321 
    322     tBTA_GATTC *p_data = (tBTA_GATTC*)p_param;
    323     switch (event)
    324     {
    325         case BTA_GATTC_REG_EVT:
    326         {
    327             bt_uuid_t app_uuid;
    328             bta_to_btif_uuid(&app_uuid, &p_data->reg_oper.app_uuid);
    329             HAL_CBACK(bt_gatt_callbacks, client->register_client_cb
    330                 , p_data->reg_oper.status
    331                 , p_data->reg_oper.client_if
    332                 , &app_uuid
    333             );
    334             break;
    335         }
    336 
    337         case BTA_GATTC_DEREG_EVT:
    338             break;
    339 
    340         case BTA_GATTC_READ_CHAR_EVT:
    341         {
    342             btgatt_read_params_t data;
    343             set_read_value(&data, &p_data->read);
    344 
    345             HAL_CBACK(bt_gatt_callbacks, client->read_characteristic_cb
    346                 , p_data->read.conn_id, p_data->read.status, &data);
    347             break;
    348         }
    349 
    350         case BTA_GATTC_WRITE_CHAR_EVT:
    351         case BTA_GATTC_PREP_WRITE_EVT:
    352         {
    353             btgatt_write_params_t data;
    354             bta_to_btif_srvc_id(&data.srvc_id, &p_data->write.srvc_id);
    355             bta_to_btif_gatt_id(&data.char_id, &p_data->write.char_id);
    356 
    357             HAL_CBACK(bt_gatt_callbacks, client->write_characteristic_cb
    358                 , p_data->write.conn_id, p_data->write.status, &data
    359             );
    360             break;
    361         }
    362 
    363         case BTA_GATTC_EXEC_EVT:
    364         {
    365             HAL_CBACK(bt_gatt_callbacks, client->execute_write_cb
    366                 , p_data->exec_cmpl.conn_id, p_data->exec_cmpl.status
    367             );
    368             break;
    369         }
    370 
    371         case BTA_GATTC_SEARCH_CMPL_EVT:
    372         {
    373             HAL_CBACK(bt_gatt_callbacks, client->search_complete_cb
    374                 , p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
    375             break;
    376         }
    377 
    378         case BTA_GATTC_SEARCH_RES_EVT:
    379         {
    380             btgatt_srvc_id_t data;
    381             bta_to_btif_srvc_id(&data, &(p_data->srvc_res.service_uuid));
    382             HAL_CBACK(bt_gatt_callbacks, client->search_result_cb
    383                 , p_data->srvc_res.conn_id, &data);
    384             break;
    385         }
    386 
    387         case BTA_GATTC_READ_DESCR_EVT:
    388         {
    389             btgatt_read_params_t data;
    390             set_read_value(&data, &p_data->read);
    391 
    392             HAL_CBACK(bt_gatt_callbacks, client->read_descriptor_cb
    393                 , p_data->read.conn_id, p_data->read.status, &data);
    394             break;
    395         }
    396 
    397         case BTA_GATTC_WRITE_DESCR_EVT:
    398         {
    399             btgatt_write_params_t data;
    400             bta_to_btif_srvc_id(&data.srvc_id, &p_data->write.srvc_id);
    401             bta_to_btif_gatt_id(&data.char_id, &p_data->write.char_id);
    402             bta_to_btif_gatt_id(&data.descr_id, &p_data->write.descr_type);
    403 
    404             HAL_CBACK(bt_gatt_callbacks, client->write_descriptor_cb
    405                 , p_data->write.conn_id, p_data->write.status, &data);
    406             break;
    407         }
    408 
    409         case BTA_GATTC_NOTIF_EVT:
    410         {
    411             btgatt_notify_params_t data;
    412 
    413             bdcpy(data.bda.address, p_data->notify.bda);
    414 
    415             bta_to_btif_srvc_id(&data.srvc_id, &p_data->notify.char_id.srvc_id);
    416             bta_to_btif_gatt_id(&data.char_id, &p_data->notify.char_id.char_id);
    417             memcpy(data.value, p_data->notify.value, p_data->notify.len);
    418 
    419             data.is_notify = p_data->notify.is_notify;
    420             data.len = p_data->notify.len;
    421 
    422             HAL_CBACK(bt_gatt_callbacks, client->notify_cb
    423                 , p_data->notify.conn_id, &data);
    424 
    425             if (p_data->notify.is_notify == FALSE)
    426             {
    427                 BTA_GATTC_SendIndConfirm(p_data->notify.conn_id,
    428                                          &p_data->notify.char_id);
    429             }
    430             break;
    431         }
    432 
    433         case BTA_GATTC_OPEN_EVT:
    434         {
    435             bt_bdaddr_t bda;
    436             bdcpy(bda.address, p_data->open.remote_bda);
    437 
    438             HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id
    439                 , p_data->open.status, p_data->open.client_if, &bda);
    440 
    441             if (p_data->open.status == BTA_GATT_OK)
    442                 btif_gatt_check_encrypted_link(p_data->open.remote_bda);
    443             break;
    444         }
    445 
    446         case BTA_GATTC_CLOSE_EVT:
    447         {
    448             bt_bdaddr_t bda;
    449             bdcpy(bda.address, p_data->close.remote_bda);
    450             HAL_CBACK(bt_gatt_callbacks, client->close_cb, p_data->close.conn_id
    451                 , p_data->status, p_data->close.client_if, &bda);
    452             break;
    453         }
    454 
    455         case BTA_GATTC_ACL_EVT:
    456             ALOGD("BTA_GATTC_ACL_EVT: status = %d", p_data->status);
    457             /* Ignore for now */
    458             break;
    459 
    460         case BTA_GATTC_CANCEL_OPEN_EVT:
    461             break;
    462 
    463         case BTIF_GATT_OBSERVE_EVT:
    464         {
    465             btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param;
    466             if (!btif_gattc_find_bdaddr(p_btif_cb->bd_addr.address))
    467             {
    468                 btif_gattc_add_remote_bdaddr(p_btif_cb->bd_addr.address, p_btif_cb->addr_type);
    469                 btif_gattc_update_properties(p_btif_cb);
    470             }
    471             HAL_CBACK(bt_gatt_callbacks, client->scan_result_cb,
    472                       &p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->value);
    473             break;
    474         }
    475 
    476         case BTIF_GATTC_RSSI_EVT:
    477         {
    478             btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param;
    479             HAL_CBACK(bt_gatt_callbacks, client->read_remote_rssi_cb, p_btif_cb->client_if,
    480                       &p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->status);
    481             break;
    482         }
    483 
    484         case BTA_GATTC_LISTEN_EVT:
    485         {
    486             HAL_CBACK(bt_gatt_callbacks, client->listen_cb
    487                 , p_data->reg_oper.status
    488                 , p_data->reg_oper.client_if
    489             );
    490             break;
    491         }
    492         default:
    493             ALOGE("%s: Unhandled event (%d)!", __FUNCTION__, event);
    494             break;
    495     }
    496 
    497     btapp_gattc_free_req_data(event, p_data);
    498 }
    499 
    500 static void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
    501 {
    502     bt_status_t status = btif_transfer_context(btif_gattc_upstreams_evt,
    503                     (uint16_t) event, (void*)p_data, sizeof(tBTA_GATTC), btapp_gattc_req_data);
    504     ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
    505 }
    506 
    507 static void bta_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
    508 {
    509     btif_gattc_cb_t btif_cb;
    510     uint8_t len;
    511 
    512     switch (event)
    513     {
    514         case BTA_DM_INQ_RES_EVT:
    515         {
    516             bdcpy(btif_cb.bd_addr.address, p_data->inq_res.bd_addr);
    517             btif_cb.device_type = p_data->inq_res.device_type;
    518             btif_cb.rssi = p_data->inq_res.rssi;
    519             btif_cb.addr_type = p_data->inq_res.ble_addr_type;
    520             if (p_data->inq_res.p_eir)
    521             {
    522                 memcpy(btif_cb.value, p_data->inq_res.p_eir, 62);
    523                 if (BTA_CheckEirData(p_data->inq_res.p_eir, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE,
    524                                       &len))
    525                 {
    526                     p_data->inq_res.remt_name_not_required  = TRUE;
    527                 }
    528             }
    529         }
    530         break;
    531 
    532         case BTA_DM_INQ_CMPL_EVT:
    533         {
    534             BTIF_TRACE_DEBUG2("%s  BLE observe complete. Num Resp %d",
    535                               __FUNCTION__,p_data->inq_cmpl.num_resps);
    536             return;
    537         }
    538 
    539         default:
    540         BTIF_TRACE_WARNING2("%s : Unknown event 0x%x", __FUNCTION__, event);
    541         return;
    542     }
    543     btif_transfer_context(btif_gattc_upstreams_evt, BTIF_GATT_OBSERVE_EVT,
    544                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    545 }
    546 
    547 static void btm_read_rssi_cb (tBTM_RSSI_RESULTS *p_result)
    548 {
    549     btif_gattc_cb_t btif_cb;
    550 
    551     bdcpy(btif_cb.bd_addr.address, p_result->rem_bda);
    552     btif_cb.rssi = p_result->rssi;
    553     btif_cb.status = p_result->status;
    554     btif_cb.client_if = rssi_request_client_if;
    555     btif_transfer_context(btif_gattc_upstreams_evt, BTIF_GATTC_RSSI_EVT,
    556                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    557 }
    558 
    559 
    560 static void btgattc_handle_event(uint16_t event, char* p_param)
    561 {
    562     tBTA_GATT_STATUS           status;
    563     tBT_UUID                   uuid;
    564     tBTA_GATT_SRVC_ID          srvc_id;
    565     tGATT_CHAR_PROP            out_char_prop;
    566     tBTA_GATTC_CHAR_ID         in_char_id;
    567     tBTA_GATTC_CHAR_ID         out_char_id;
    568     tBTA_GATTC_CHAR_DESCR_ID   in_char_descr_id;
    569     tBTA_GATTC_CHAR_DESCR_ID   out_char_descr_id;
    570     tBTA_GATTC_INCL_SVC_ID     in_incl_svc_id;
    571     tBTA_GATTC_INCL_SVC_ID     out_incl_svc_id;
    572     tBTA_GATT_UNFMT            descr_val;
    573 
    574     btif_gattc_cb_t* p_cb = (btif_gattc_cb_t*)p_param;
    575     if (!p_cb) return;
    576 
    577     ALOGD("%s: Event %d", __FUNCTION__, event);
    578 
    579     switch (event)
    580     {
    581         case BTIF_GATTC_REGISTER_APP:
    582             btif_to_bta_uuid(&uuid, &p_cb->uuid);
    583             BTA_GATTC_AppRegister(&uuid, bta_gattc_cback);
    584             break;
    585 
    586         case BTIF_GATTC_UNREGISTER_APP:
    587             BTA_GATTC_AppDeregister(p_cb->client_if);
    588             break;
    589 
    590         case BTIF_GATTC_SCAN_START:
    591             btif_gattc_init_dev_cb();
    592             BTA_DmBleObserve(TRUE, 0, bta_scan_results_cb);
    593             break;
    594 
    595         case BTIF_GATTC_SCAN_STOP:
    596             BTA_DmBleObserve(FALSE, 0, 0);
    597             break;
    598 
    599         case BTIF_GATTC_OPEN:
    600         {
    601             // Ensure device is in inquiry database
    602             int addr_type = 0;
    603             int device_type = 0;
    604 
    605             if (btif_get_device_type(p_cb->bd_addr.address, &addr_type, &device_type) == TRUE
    606                   && device_type != BT_DEVICE_TYPE_BREDR)
    607                 BTA_DmAddBleDevice(p_cb->bd_addr.address, addr_type, device_type);
    608 
    609             // Mark background connections
    610             if (!p_cb->is_direct)
    611                 BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
    612 
    613             // Connect!
    614             BTA_GATTC_Open(p_cb->client_if, p_cb->bd_addr.address, p_cb->is_direct);
    615             break;
    616         }
    617 
    618         case BTIF_GATTC_CLOSE:
    619             // Disconnect established connections
    620             if (p_cb->conn_id != 0)
    621                 BTA_GATTC_Close(p_cb->conn_id);
    622             else
    623                 BTA_GATTC_CancelOpen(p_cb->client_if, p_cb->bd_addr.address, TRUE);
    624 
    625             // Cancel pending background connections (remove from whitelist)
    626             BTA_GATTC_CancelOpen(p_cb->client_if, p_cb->bd_addr.address, FALSE);
    627             break;
    628 
    629         case BTIF_GATTC_SEARCH_SERVICE:
    630         {
    631             if (p_cb->search_all)
    632             {
    633                 BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, NULL);
    634             } else {
    635                 btif_to_bta_uuid(&uuid, &p_cb->uuid);
    636                 BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, &uuid);
    637             }
    638             break;
    639         }
    640 
    641         case BTIF_GATTC_GET_FIRST_CHAR:
    642         {
    643             btgatt_gatt_id_t char_id;
    644             btif_to_bta_srvc_id(&srvc_id, &p_cb->srvc_id);
    645             status = BTA_GATTC_GetFirstChar(p_cb->conn_id, &srvc_id, NULL,
    646                                             &out_char_id, &out_char_prop);
    647 
    648             if (status == 0)
    649                 bta_to_btif_gatt_id(&char_id, &out_char_id.char_id);
    650 
    651             HAL_CBACK(bt_gatt_callbacks, client->get_characteristic_cb,
    652                 p_cb->conn_id, status, &p_cb->srvc_id,
    653                 &char_id, out_char_prop);
    654             break;
    655         }
    656 
    657         case BTIF_GATTC_GET_NEXT_CHAR:
    658         {
    659             btgatt_gatt_id_t char_id;
    660             btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id);
    661             btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id);
    662 
    663             status = BTA_GATTC_GetNextChar(p_cb->conn_id, &in_char_id, NULL,
    664                                             &out_char_id, &out_char_prop);
    665 
    666             if (status == 0)
    667                 bta_to_btif_gatt_id(&char_id, &out_char_id.char_id);
    668 
    669             HAL_CBACK(bt_gatt_callbacks, client->get_characteristic_cb,
    670                 p_cb->conn_id, status, &p_cb->srvc_id,
    671                 &char_id, out_char_prop);
    672             break;
    673         }
    674 
    675         case BTIF_GATTC_GET_FIRST_CHAR_DESCR:
    676         {
    677             btgatt_gatt_id_t descr_id;
    678             btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id);
    679             btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id);
    680 
    681             status = BTA_GATTC_GetFirstCharDescr(p_cb->conn_id, &in_char_id, NULL,
    682                                                     &out_char_descr_id);
    683 
    684             if (status == 0)
    685                 bta_to_btif_gatt_id(&descr_id, &out_char_descr_id.descr_id);
    686 
    687             HAL_CBACK(bt_gatt_callbacks, client->get_descriptor_cb,
    688                 p_cb->conn_id, status, &p_cb->srvc_id,
    689                 &p_cb->char_id, &descr_id);
    690             break;
    691         }
    692 
    693         case BTIF_GATTC_GET_NEXT_CHAR_DESCR:
    694         {
    695             btgatt_gatt_id_t descr_id;
    696             btif_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &p_cb->srvc_id);
    697             btif_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &p_cb->char_id);
    698             btif_to_bta_gatt_id(&in_char_descr_id.descr_id, &p_cb->descr_id);
    699 
    700             status = BTA_GATTC_GetNextCharDescr(p_cb->conn_id, &in_char_descr_id
    701                                         , NULL, &out_char_descr_id);
    702 
    703             if (status == 0)
    704                 bta_to_btif_gatt_id(&descr_id, &out_char_descr_id.descr_id);
    705 
    706             HAL_CBACK(bt_gatt_callbacks, client->get_descriptor_cb,
    707                 p_cb->conn_id, status, &p_cb->srvc_id,
    708                 &p_cb->char_id, &descr_id);
    709             break;
    710         }
    711 
    712         case BTIF_GATTC_GET_FIRST_INCL_SERVICE:
    713         {
    714             btgatt_srvc_id_t incl_srvc_id;
    715             btif_to_bta_srvc_id(&srvc_id, &p_cb->srvc_id);
    716 
    717             status = BTA_GATTC_GetFirstIncludedService(p_cb->conn_id,
    718                         &srvc_id, NULL, &out_incl_svc_id);
    719 
    720             bta_to_btif_srvc_id(&incl_srvc_id, &out_incl_svc_id.incl_svc_id);
    721 
    722             HAL_CBACK(bt_gatt_callbacks, client->get_included_service_cb,
    723                 p_cb->conn_id, status, &p_cb->srvc_id,
    724                 &incl_srvc_id);
    725             break;
    726         }
    727 
    728         case BTIF_GATTC_GET_NEXT_INCL_SERVICE:
    729         {
    730             btgatt_srvc_id_t incl_srvc_id;
    731             btif_to_bta_srvc_id(&in_incl_svc_id.srvc_id, &p_cb->srvc_id);
    732             btif_to_bta_srvc_id(&in_incl_svc_id.incl_svc_id, &p_cb->incl_srvc_id);
    733 
    734             status = BTA_GATTC_GetNextIncludedService(p_cb->conn_id,
    735                         &in_incl_svc_id, NULL, &out_incl_svc_id);
    736 
    737             bta_to_btif_srvc_id(&incl_srvc_id, &out_incl_svc_id.incl_svc_id);
    738 
    739             HAL_CBACK(bt_gatt_callbacks, client->get_included_service_cb,
    740                 p_cb->conn_id, status, &p_cb->srvc_id,
    741                 &incl_srvc_id);
    742             break;
    743         }
    744 
    745         case BTIF_GATTC_READ_CHAR:
    746             btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id);
    747             btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id);
    748 
    749             BTA_GATTC_ReadCharacteristic(p_cb->conn_id, &in_char_id, p_cb->auth_req);
    750             break;
    751 
    752         case BTIF_GATTC_READ_CHAR_DESCR:
    753             btif_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &p_cb->srvc_id);
    754             btif_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &p_cb->char_id);
    755             btif_to_bta_gatt_id(&in_char_descr_id.descr_id, &p_cb->descr_id);
    756 
    757             BTA_GATTC_ReadCharDescr(p_cb->conn_id, &in_char_descr_id, p_cb->auth_req);
    758             break;
    759 
    760         case BTIF_GATTC_WRITE_CHAR:
    761             btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id);
    762             btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id);
    763 
    764             BTA_GATTC_WriteCharValue(p_cb->conn_id, &in_char_id,
    765                                      p_cb->write_type,
    766                                      p_cb->len,
    767                                      p_cb->value,
    768                                      p_cb->auth_req);
    769             break;
    770 
    771         case BTIF_GATTC_WRITE_CHAR_DESCR:
    772             btif_to_bta_srvc_id(&in_char_descr_id.char_id.srvc_id, &p_cb->srvc_id);
    773             btif_to_bta_gatt_id(&in_char_descr_id.char_id.char_id, &p_cb->char_id);
    774             btif_to_bta_gatt_id(&in_char_descr_id.descr_id, &p_cb->descr_id);
    775 
    776             descr_val.len = p_cb->len;
    777             descr_val.p_value = p_cb->value;
    778 
    779             BTA_GATTC_WriteCharDescr(p_cb->conn_id, &in_char_descr_id,
    780                                      p_cb->write_type, &descr_val,
    781                                      p_cb->auth_req);
    782             break;
    783 
    784         case BTIF_GATTC_EXECUTE_WRITE:
    785             BTA_GATTC_ExecuteWrite(p_cb->conn_id, p_cb->action);
    786             break;
    787 
    788         case BTIF_GATTC_REG_FOR_NOTIFICATION:
    789             btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id);
    790             btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id);
    791 
    792             status = BTA_GATTC_RegisterForNotifications(p_cb->client_if,
    793                                     p_cb->bd_addr.address, &in_char_id);
    794 
    795             HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
    796                 p_cb->conn_id, 1, status, &p_cb->srvc_id,
    797                 &p_cb->char_id);
    798             break;
    799 
    800         case BTIF_GATTC_DEREG_FOR_NOTIFICATION:
    801             btif_to_bta_srvc_id(&in_char_id.srvc_id, &p_cb->srvc_id);
    802             btif_to_bta_gatt_id(&in_char_id.char_id, &p_cb->char_id);
    803 
    804             status = BTA_GATTC_DeregisterForNotifications(p_cb->client_if,
    805                                         p_cb->bd_addr.address, &in_char_id);
    806 
    807             HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
    808                 p_cb->conn_id, 0, status, &p_cb->srvc_id,
    809                 &p_cb->char_id);
    810             break;
    811 
    812         case BTIF_GATTC_REFRESH:
    813             BTA_GATTC_Refresh(p_cb->bd_addr.address);
    814             break;
    815 
    816         case BTIF_GATTC_READ_RSSI:
    817             rssi_request_client_if = p_cb->client_if;
    818             BTM_ReadRSSI (p_cb->bd_addr.address, (tBTM_CMPL_CB *)btm_read_rssi_cb);
    819             break;
    820 
    821         case BTIF_GATTC_LISTEN:
    822             BTA_GATTC_Listen(p_cb->client_if, p_cb->start, NULL);
    823             break;
    824 
    825         case BTIF_GATTC_SET_ADV_DATA:
    826         {
    827             if (p_cb->start == 0)
    828                 BTM_BleWriteAdvData(p_cb->adv_data.mask, &p_cb->adv_data.data);
    829             else
    830                 BTM_BleWriteScanRsp(p_cb->adv_data.mask, &p_cb->adv_data.data);
    831             if (p_cb->adv_data.data.manu.p_val != NULL)
    832                 GKI_freebuf(p_cb->adv_data.data.manu.p_val);
    833             break;
    834         }
    835 
    836         default:
    837             ALOGE("%s: Unknown event (%d)!", __FUNCTION__, event);
    838             break;
    839     }
    840 }
    841 
    842 /*******************************************************************************
    843 **  Client API Functions
    844 ********************************************************************************/
    845 
    846 static bt_status_t btif_gattc_register_app(bt_uuid_t *uuid)
    847 {
    848     CHECK_BTGATT_INIT();
    849     btif_gattc_cb_t btif_cb;
    850     memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
    851     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_REGISTER_APP,
    852                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    853 }
    854 
    855 static bt_status_t btif_gattc_unregister_app(int client_if )
    856 {
    857     CHECK_BTGATT_INIT();
    858     btif_gattc_cb_t btif_cb;
    859     btif_cb.client_if = (uint8_t) client_if;
    860     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_UNREGISTER_APP,
    861                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    862 }
    863 
    864 static bt_status_t btif_gattc_scan( int client_if, bool start )
    865 {
    866     CHECK_BTGATT_INIT();
    867     btif_gattc_cb_t btif_cb;
    868     btif_cb.client_if = (uint8_t) client_if;
    869     return btif_transfer_context(btgattc_handle_event, start ? BTIF_GATTC_SCAN_START : BTIF_GATTC_SCAN_STOP,
    870                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    871 }
    872 
    873 static bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t *bd_addr, bool is_direct )
    874 {
    875     CHECK_BTGATT_INIT();
    876     btif_gattc_cb_t btif_cb;
    877     btif_cb.client_if = (uint8_t) client_if;
    878     btif_cb.is_direct = is_direct ? 1 : 0;
    879     bdcpy(btif_cb.bd_addr.address, bd_addr->address);
    880     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_OPEN,
    881                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    882 }
    883 
    884 static bt_status_t btif_gattc_close( int client_if, const bt_bdaddr_t *bd_addr, int conn_id)
    885 {
    886     CHECK_BTGATT_INIT();
    887     btif_gattc_cb_t btif_cb;
    888     btif_cb.client_if = (uint8_t) client_if;
    889     btif_cb.conn_id = (uint16_t) conn_id;
    890     bdcpy(btif_cb.bd_addr.address, bd_addr->address);
    891     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_CLOSE,
    892                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    893 }
    894 
    895 static bt_status_t btif_gattc_listen(int client_if, bool start)
    896 {
    897     CHECK_BTGATT_INIT();
    898     btif_gattc_cb_t btif_cb;
    899     btif_cb.client_if = (uint8_t) client_if;
    900     btif_cb.start = start ? 1 : 0;
    901     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_LISTEN,
    902                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    903 }
    904 
    905 static bt_status_t btif_gattc_set_adv_data(int client_if, bool set_scan_rsp, bool include_name,
    906                 bool include_txpower, int min_interval, int max_interval, int appearance,
    907                 uint16_t manufacturer_len, char* manufacturer_data)
    908 {
    909     CHECK_BTGATT_INIT();
    910     btif_gattc_cb_t btif_cb;
    911     memset(&btif_cb, 0, sizeof(btif_gattc_cb_t));
    912     memset(&btif_cb.adv_data, 0, sizeof(btgatt_adv_data));
    913 
    914     btif_cb.client_if = (uint8_t) client_if;
    915     btif_cb.start = set_scan_rsp ? 1 : 0;
    916 
    917     if (!set_scan_rsp)
    918     {
    919         btif_cb.adv_data.mask = BTM_BLE_AD_BIT_FLAGS;
    920         btif_cb.adv_data.data.flag = ADV_FLAGS;
    921     }
    922 
    923     if (include_name)
    924         btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_DEV_NAME;
    925 
    926     if (include_txpower)
    927         btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_TX_PWR;
    928 
    929     if (min_interval > 0 && max_interval > 0 && max_interval > min_interval)
    930     {
    931         btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_INT_RANGE;
    932         btif_cb.adv_data.data.int_range.low = min_interval;
    933         btif_cb.adv_data.data.int_range.hi = max_interval;
    934     }
    935 
    936     if (appearance != 0)
    937     {
    938         btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_APPEARANCE;
    939         btif_cb.adv_data.data.appearance = appearance;
    940     }
    941 
    942     if (manufacturer_len > 0 && manufacturer_data != NULL)
    943     {
    944         btif_cb.adv_data.data.manu.p_val = GKI_getbuf(manufacturer_len);
    945         if (btif_cb.adv_data.data.manu.p_val != NULL)
    946         {
    947             btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_MANU;
    948             btif_cb.adv_data.data.manu.len = manufacturer_len;
    949             memcpy(btif_cb.adv_data.data.manu.p_val, manufacturer_data, manufacturer_len);
    950         }
    951     }
    952 
    953     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SET_ADV_DATA,
    954                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    955 }
    956 
    957 static bt_status_t btif_gattc_refresh( int client_if, const bt_bdaddr_t *bd_addr )
    958 {
    959     CHECK_BTGATT_INIT();
    960     btif_gattc_cb_t btif_cb;
    961     btif_cb.client_if = (uint8_t) client_if;
    962     bdcpy(btif_cb.bd_addr.address, bd_addr->address);
    963     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_REFRESH,
    964                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    965 }
    966 
    967 static bt_status_t btif_gattc_search_service(int conn_id, bt_uuid_t *filter_uuid )
    968 {
    969     CHECK_BTGATT_INIT();
    970     btif_gattc_cb_t btif_cb;
    971     btif_cb.conn_id = (uint16_t) conn_id;
    972     btif_cb.search_all = filter_uuid ? 0 : 1;
    973     if (filter_uuid)
    974         memcpy(&btif_cb.uuid, filter_uuid, sizeof(bt_uuid_t));
    975     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SEARCH_SERVICE,
    976                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    977 }
    978 
    979 static bt_status_t btif_gattc_get_characteristic( int conn_id
    980         , btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *start_char_id)
    981 {
    982     CHECK_BTGATT_INIT();
    983     btif_gattc_cb_t btif_cb;
    984     btif_cb.conn_id = (uint16_t) conn_id;
    985     memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
    986     if (start_char_id)
    987     {
    988         memcpy(&btif_cb.char_id, start_char_id, sizeof(btgatt_gatt_id_t));
    989         return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_GET_NEXT_CHAR,
    990                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    991     }
    992     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_GET_FIRST_CHAR,
    993                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
    994 }
    995 
    996 static bt_status_t btif_gattc_get_descriptor( int conn_id
    997         , btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id
    998         , btgatt_gatt_id_t *start_descr_id)
    999 {
   1000     CHECK_BTGATT_INIT();
   1001     btif_gattc_cb_t btif_cb;
   1002     btif_cb.conn_id = (uint16_t) conn_id;
   1003     memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
   1004     memcpy(&btif_cb.char_id, char_id, sizeof(btgatt_gatt_id_t));
   1005     if (start_descr_id)
   1006     {
   1007         memcpy(&btif_cb.descr_id, start_descr_id, sizeof(btgatt_gatt_id_t));
   1008         return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_GET_NEXT_CHAR_DESCR,
   1009                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1010     }
   1011 
   1012     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_GET_FIRST_CHAR_DESCR,
   1013                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1014 }
   1015 
   1016 static bt_status_t btif_gattc_get_included_service(int conn_id, btgatt_srvc_id_t *srvc_id,
   1017                                                    btgatt_srvc_id_t *start_incl_srvc_id)
   1018 {
   1019     CHECK_BTGATT_INIT();
   1020     btif_gattc_cb_t btif_cb;
   1021     btif_cb.conn_id = (uint16_t) conn_id;
   1022     memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
   1023     if (start_incl_srvc_id)
   1024     {
   1025         memcpy(&btif_cb.incl_srvc_id, start_incl_srvc_id, sizeof(btgatt_srvc_id_t));
   1026         return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_GET_NEXT_INCL_SERVICE,
   1027                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1028     }
   1029     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_GET_FIRST_INCL_SERVICE,
   1030                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1031 }
   1032 
   1033 static bt_status_t btif_gattc_read_char(int conn_id, btgatt_srvc_id_t* srvc_id,
   1034                                         btgatt_gatt_id_t* char_id, int auth_req )
   1035 {
   1036     CHECK_BTGATT_INIT();
   1037     btif_gattc_cb_t btif_cb;
   1038     btif_cb.conn_id = (uint16_t) conn_id;
   1039     btif_cb.auth_req = (uint8_t) auth_req;
   1040     memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
   1041     memcpy(&btif_cb.char_id, char_id, sizeof(btgatt_gatt_id_t));
   1042     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_READ_CHAR,
   1043                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1044 }
   1045 
   1046 static bt_status_t btif_gattc_read_char_descr(int conn_id, btgatt_srvc_id_t* srvc_id,
   1047                                               btgatt_gatt_id_t* char_id,
   1048                                               btgatt_gatt_id_t* descr_id,
   1049                                               int auth_req )
   1050 {
   1051     CHECK_BTGATT_INIT();
   1052     btif_gattc_cb_t btif_cb;
   1053     btif_cb.conn_id = (uint16_t) conn_id;
   1054     btif_cb.auth_req = (uint8_t) auth_req;
   1055     memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
   1056     memcpy(&btif_cb.char_id, char_id, sizeof(btgatt_gatt_id_t));
   1057     memcpy(&btif_cb.descr_id, descr_id, sizeof(btgatt_gatt_id_t));
   1058     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_READ_CHAR_DESCR,
   1059                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1060 }
   1061 
   1062 static bt_status_t btif_gattc_write_char(int conn_id, btgatt_srvc_id_t* srvc_id,
   1063                                          btgatt_gatt_id_t* char_id, int write_type,
   1064                                          int len, int auth_req, char* p_value)
   1065 {
   1066     CHECK_BTGATT_INIT();
   1067     btif_gattc_cb_t btif_cb;
   1068     btif_cb.conn_id = (uint16_t) conn_id;
   1069     btif_cb.auth_req = (uint8_t) auth_req;
   1070     btif_cb.write_type = (uint8_t) write_type;
   1071     btif_cb.len = len > BTGATT_MAX_ATTR_LEN ? BTGATT_MAX_ATTR_LEN : len;
   1072     memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
   1073     memcpy(&btif_cb.char_id, char_id, sizeof(btgatt_gatt_id_t));
   1074     memcpy(btif_cb.value, p_value, btif_cb.len);
   1075     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_WRITE_CHAR,
   1076                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1077 }
   1078 
   1079 static bt_status_t btif_gattc_write_char_descr(int conn_id, btgatt_srvc_id_t* srvc_id,
   1080                                                btgatt_gatt_id_t* char_id,
   1081                                                btgatt_gatt_id_t* descr_id,
   1082                                                int write_type, int len, int auth_req,
   1083                                                char* p_value)
   1084 {
   1085     CHECK_BTGATT_INIT();
   1086     btif_gattc_cb_t btif_cb;
   1087     btif_cb.conn_id = (uint16_t) conn_id;
   1088     btif_cb.auth_req = (uint8_t) auth_req;
   1089     btif_cb.write_type = (uint8_t) write_type;
   1090     btif_cb.len = len > BTGATT_MAX_ATTR_LEN ? BTGATT_MAX_ATTR_LEN : len;
   1091     memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
   1092     memcpy(&btif_cb.char_id, char_id, sizeof(btgatt_gatt_id_t));
   1093     memcpy(&btif_cb.descr_id, descr_id, sizeof(btgatt_gatt_id_t));
   1094     memcpy(btif_cb.value, p_value, btif_cb.len);
   1095     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_WRITE_CHAR_DESCR,
   1096                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1097 }
   1098 
   1099 static bt_status_t btif_gattc_execute_write(int conn_id, int execute)
   1100 {
   1101     CHECK_BTGATT_INIT();
   1102     btif_gattc_cb_t btif_cb;
   1103     btif_cb.conn_id = (uint16_t) conn_id;
   1104     btif_cb.action = (uint8_t) execute;
   1105     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_EXECUTE_WRITE,
   1106                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1107 }
   1108 
   1109 static bt_status_t btif_gattc_reg_for_notification(int client_if, const bt_bdaddr_t *bd_addr,
   1110                                                    btgatt_srvc_id_t* srvc_id,
   1111                                                    btgatt_gatt_id_t* char_id)
   1112 {
   1113     CHECK_BTGATT_INIT();
   1114     btif_gattc_cb_t btif_cb;
   1115     btif_cb.client_if = (uint8_t) client_if;
   1116     bdcpy(btif_cb.bd_addr.address, bd_addr->address);
   1117     memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
   1118     memcpy(&btif_cb.char_id, char_id, sizeof(btgatt_gatt_id_t));
   1119     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_REG_FOR_NOTIFICATION,
   1120                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1121 }
   1122 
   1123 static bt_status_t btif_gattc_dereg_for_notification(int client_if, const bt_bdaddr_t *bd_addr,
   1124                                                      btgatt_srvc_id_t* srvc_id,
   1125                                                      btgatt_gatt_id_t* char_id)
   1126 {
   1127     CHECK_BTGATT_INIT();
   1128     btif_gattc_cb_t btif_cb;
   1129     btif_cb.client_if = (uint8_t) client_if;
   1130     bdcpy(btif_cb.bd_addr.address, bd_addr->address);
   1131     memcpy(&btif_cb.srvc_id, srvc_id, sizeof(btgatt_srvc_id_t));
   1132     memcpy(&btif_cb.char_id, char_id, sizeof(btgatt_gatt_id_t));
   1133     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_DEREG_FOR_NOTIFICATION,
   1134                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1135 }
   1136 
   1137 static bt_status_t btif_gattc_read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr)
   1138 {
   1139     CHECK_BTGATT_INIT();
   1140     btif_gattc_cb_t btif_cb;
   1141     btif_cb.client_if = (uint8_t) client_if;
   1142     bdcpy(btif_cb.bd_addr.address, bd_addr->address);
   1143     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_READ_RSSI,
   1144                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
   1145 }
   1146 
   1147 static int btif_gattc_get_device_type( const bt_bdaddr_t *bd_addr )
   1148 {
   1149     int device_type = 0;
   1150     char bd_addr_str[18] = {0};
   1151 
   1152     bd2str(bd_addr, &bd_addr_str);
   1153     if (btif_config_get_int("Remote", bd_addr_str, "DevType", &device_type))
   1154         return device_type;
   1155     return 0;
   1156 }
   1157 
   1158 extern bt_status_t btif_gattc_test_command_impl(int command, btgatt_test_params_t* params);
   1159 
   1160 static bt_status_t btif_gattc_test_command(int command, btgatt_test_params_t* params)
   1161 {
   1162     return btif_gattc_test_command_impl(command, params);
   1163 }
   1164 
   1165 
   1166 const btgatt_client_interface_t btgattClientInterface = {
   1167     btif_gattc_register_app,
   1168     btif_gattc_unregister_app,
   1169     btif_gattc_scan,
   1170     btif_gattc_open,
   1171     btif_gattc_close,
   1172     btif_gattc_listen,
   1173     btif_gattc_refresh,
   1174     btif_gattc_search_service,
   1175     btif_gattc_get_included_service,
   1176     btif_gattc_get_characteristic,
   1177     btif_gattc_get_descriptor,
   1178     btif_gattc_read_char,
   1179     btif_gattc_write_char,
   1180     btif_gattc_read_char_descr,
   1181     btif_gattc_write_char_descr,
   1182     btif_gattc_execute_write,
   1183     btif_gattc_reg_for_notification,
   1184     btif_gattc_dereg_for_notification,
   1185     btif_gattc_read_remote_rssi,
   1186     btif_gattc_get_device_type,
   1187     btif_gattc_set_adv_data,
   1188     btif_gattc_test_command
   1189 };
   1190 
   1191 #endif
   1192