1/******************************************************************************
2 *
3 *  Copyright (C) 2009-2014 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 *  Filename:      btif_gatt_client.c
22 *
23 *  Description:   GATT client implementation
24 *
25 *******************************************************************************/
26
27#define LOG_TAG "bt_btif_gattc"
28
29#include <errno.h>
30#include <hardware/bluetooth.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include "device/include/controller.h"
35
36
37#include "btcore/include/bdaddr.h"
38#include "btif_common.h"
39#include "btif_util.h"
40
41#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
42
43#include <hardware/bt_gatt.h>
44
45#include "bta_api.h"
46#include "bta_gatt_api.h"
47#include "btif_config.h"
48#include "btif_dm.h"
49#include "btif_gatt.h"
50#include "btif_gatt_multi_adv_util.h"
51#include "btif_gatt_util.h"
52#include "btif_storage.h"
53#include "btif_storage.h"
54#include "osi/include/log.h"
55#include "vendor_api.h"
56
57/*******************************************************************************
58**  Constants & Macros
59********************************************************************************/
60
61#define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
62    {\
63        LOG_WARN(LOG_TAG, "%s: BTGATT not initialized", __FUNCTION__);\
64        return BT_STATUS_NOT_READY;\
65    } else {\
66        LOG_VERBOSE(LOG_TAG, "%s", __FUNCTION__);\
67    }
68
69#define BLE_RESOLVE_ADDR_MSB                 0x40   /* bit7, bit6 is 01 to be resolvable random */
70#define BLE_RESOLVE_ADDR_MASK                0xc0   /* bit 6, and bit7 */
71#define BTM_BLE_IS_RESOLVE_BDA(x)           ((x[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)
72
73typedef enum {
74    BTIF_GATTC_REGISTER_APP = 1000,
75    BTIF_GATTC_UNREGISTER_APP,
76    BTIF_GATTC_SCAN_START,
77    BTIF_GATTC_SCAN_STOP,
78    BTIF_GATTC_OPEN,
79    BTIF_GATTC_CLOSE,
80    BTIF_GATTC_SEARCH_SERVICE,
81    BTIF_GATTC_READ_CHAR,
82    BTIF_GATTC_READ_CHAR_DESCR,
83    BTIF_GATTC_WRITE_CHAR,
84    BTIF_GATTC_WRITE_CHAR_DESCR,
85    BTIF_GATTC_EXECUTE_WRITE,
86    BTIF_GATTC_REG_FOR_NOTIFICATION,
87    BTIF_GATTC_DEREG_FOR_NOTIFICATION,
88    BTIF_GATTC_REFRESH,
89    BTIF_GATTC_READ_RSSI,
90    BTIF_GATTC_LISTEN,
91    BTIF_GATTC_SET_ADV_DATA,
92    BTIF_GATTC_CONFIGURE_MTU,
93    BTIF_GATTC_CONN_PARAM_UPDT,
94    BTIF_GATTC_SCAN_FILTER_PARAM_SETUP,
95    BTIF_GATTC_SCAN_FILTER_CONFIG,
96    BTIF_GATTC_SCAN_FILTER_CLEAR,
97    BTIF_GATTC_SCAN_FILTER_ENABLE,
98    BTIF_GATTC_SET_SCAN_PARAMS,
99    BTIF_GATTC_ADV_INSTANCE_ENABLE,
100    BTIF_GATTC_ADV_INSTANCE_UPDATE,
101    BTIF_GATTC_ADV_INSTANCE_SET_DATA,
102    BTIF_GATTC_ADV_INSTANCE_DISABLE,
103    BTIF_GATTC_CONFIG_STORAGE_PARAMS,
104    BTIF_GATTC_ENABLE_BATCH_SCAN,
105    BTIF_GATTC_READ_BATCH_SCAN_REPORTS,
106    BTIF_GATTC_DISABLE_BATCH_SCAN,
107    BTIF_GATTC_GET_GATT_DB
108} btif_gattc_event_t;
109
110#define BTIF_GATT_MAX_OBSERVED_DEV 40
111
112#define BTIF_GATT_OBSERVE_EVT   0x1000
113#define BTIF_GATTC_RSSI_EVT     0x1001
114#define BTIF_GATTC_SCAN_FILTER_EVT  0x1003
115#define BTIF_GATTC_SCAN_PARAM_EVT   0x1004
116
117#define ENABLE_BATCH_SCAN 1
118#define DISABLE_BATCH_SCAN 0
119
120/*******************************************************************************
121**  Local type definitions
122********************************************************************************/
123typedef struct
124{
125    uint8_t report_format;
126    uint16_t data_len;
127    uint8_t num_records;
128    uint8_t *p_rep_data;
129} btgatt_batch_reports;
130
131typedef struct
132{
133    uint8_t  status;
134    uint8_t  client_if;
135    uint8_t  action;
136    uint8_t  avbl_space;
137    uint8_t  lost_timeout;
138    tBLE_ADDR_TYPE addr_type;
139    uint8_t  batch_scan_full_max;
140    uint8_t  batch_scan_trunc_max;
141    uint8_t  batch_scan_notify_threshold;
142    tBTA_BLE_BATCH_SCAN_MODE scan_mode;
143    uint32_t scan_interval;
144    uint32_t scan_window;
145    tBTA_BLE_DISCARD_RULE discard_rule;
146    btgatt_batch_reports  read_reports;
147} btgatt_batch_track_cb_t;
148
149typedef tBTA_DM_BLE_PF_FILT_PARAMS btgatt_adv_filt_param_t;
150
151typedef struct
152{
153    uint8_t     client_if;
154    uint8_t     action;
155    tBTA_DM_BLE_PF_COND_TYPE filt_type;
156    bt_bdaddr_t bd_addr;
157    uint8_t     value[BTGATT_MAX_ATTR_LEN];
158    uint8_t     value_len;
159    uint8_t     filt_index;
160    uint16_t    conn_id;
161    uint16_t    company_id_mask;
162    bt_uuid_t   uuid;
163    bt_uuid_t   uuid_mask;
164    uint8_t     value_mask[BTGATT_MAX_ATTR_LEN];
165    uint8_t     value_mask_len;
166    uint8_t     has_mask;
167    uint8_t     addr_type;
168    uint8_t     status;
169    tBTA_DM_BLE_PF_AVBL_SPACE avbl_space;
170    tBTA_DM_BLE_SCAN_COND_OP cond_op;
171    btgatt_adv_filt_param_t adv_filt_param;
172} btgatt_adv_filter_cb_t;
173
174typedef struct
175{
176    uint8_t     value[BTGATT_MAX_ATTR_LEN];
177    uint8_t     inst_id;
178    bt_bdaddr_t bd_addr;
179    btgatt_srvc_id_t srvc_id;
180    btgatt_srvc_id_t incl_srvc_id;
181    btgatt_gatt_id_t char_id;
182    btgatt_gatt_id_t descr_id;
183    uint16_t    handle;
184    bt_uuid_t   uuid;
185    bt_uuid_t   uuid_mask;
186    uint16_t    conn_id;
187    uint16_t    len;
188    uint16_t    mask;
189    uint32_t    scan_interval;
190    uint32_t    scan_window;
191    uint8_t     client_if;
192    uint8_t     action;
193    uint8_t     is_direct;
194    uint8_t     search_all;
195    uint8_t     auth_req;
196    uint8_t     write_type;
197    uint8_t     status;
198    uint8_t     addr_type;
199    uint8_t     start;
200    uint8_t     has_mask;
201    int8_t      rssi;
202    uint8_t     flag;
203    tBT_DEVICE_TYPE device_type;
204    btgatt_transport_t transport;
205} __attribute__((packed)) btif_gattc_cb_t;
206
207typedef struct
208{
209    bt_bdaddr_t bd_addr;
210    uint16_t    min_interval;
211    uint16_t    max_interval;
212    uint16_t    timeout;
213    uint16_t    latency;
214} btif_conn_param_cb_t;
215
216typedef struct
217{
218    bt_bdaddr_t bd_addr;
219    BOOLEAN     in_use;
220}__attribute__((packed)) btif_gattc_dev_t;
221
222typedef struct
223{
224    btif_gattc_dev_t remote_dev[BTIF_GATT_MAX_OBSERVED_DEV];
225    uint8_t            addr_type;
226    uint8_t            next_storage_idx;
227}__attribute__((packed)) btif_gattc_dev_cb_t;
228
229/*******************************************************************************
230**  Static variables
231********************************************************************************/
232
233extern const btgatt_callbacks_t *bt_gatt_callbacks;
234static btif_gattc_dev_cb_t  btif_gattc_dev_cb;
235static btif_gattc_dev_cb_t  *p_dev_cb = &btif_gattc_dev_cb;
236static uint8_t rssi_request_client_if;
237
238/*******************************************************************************
239**  Static functions
240********************************************************************************/
241
242static bt_status_t btif_gattc_multi_adv_disable(int client_if);
243static void btif_multi_adv_stop_cb(void *data)
244{
245    int client_if = PTR_TO_INT(data);
246    btif_gattc_multi_adv_disable(client_if); // Does context switch
247}
248
249static btgattc_error_t btif_gattc_translate_btm_status(tBTM_STATUS status)
250{
251    switch(status)
252    {
253       case BTM_SUCCESS:
254       case BTM_SUCCESS_NO_SECURITY:
255            return BT_GATTC_COMMAND_SUCCESS;
256
257       case BTM_CMD_STARTED:
258            return BT_GATTC_COMMAND_STARTED;
259
260       case BTM_BUSY:
261            return BT_GATTC_COMMAND_BUSY;
262
263       case BTM_CMD_STORED:
264            return BT_GATTC_COMMAND_STORED;
265
266       case BTM_NO_RESOURCES:
267            return BT_GATTC_NO_RESOURCES;
268
269       case BTM_MODE_UNSUPPORTED:
270       case BTM_WRONG_MODE:
271       case BTM_MODE4_LEVEL4_NOT_SUPPORTED:
272            return BT_GATTC_MODE_UNSUPPORTED;
273
274       case BTM_ILLEGAL_VALUE:
275       case BTM_SCO_BAD_LENGTH:
276            return BT_GATTC_ILLEGAL_VALUE;
277
278       case BTM_UNKNOWN_ADDR:
279            return BT_GATTC_UNKNOWN_ADDR;
280
281       case BTM_DEVICE_TIMEOUT:
282            return BT_GATTC_DEVICE_TIMEOUT;
283
284       case BTM_FAILED_ON_SECURITY:
285       case BTM_REPEATED_ATTEMPTS:
286       case BTM_NOT_AUTHORIZED:
287            return BT_GATTC_SECURITY_ERROR;
288
289       case BTM_DEV_RESET:
290       case BTM_ILLEGAL_ACTION:
291            return BT_GATTC_INCORRECT_STATE;
292
293       case BTM_BAD_VALUE_RET:
294            return BT_GATTC_INVALID_CONTROLLER_OUTPUT;
295
296       case BTM_DELAY_CHECK:
297            return BT_GATTC_DELAYED_ENCRYPTION_CHECK;
298
299       case BTM_ERR_PROCESSING:
300       default:
301          return BT_GATTC_ERR_PROCESSING;
302    }
303}
304
305static void btapp_gattc_req_data(UINT16 event, char *p_dest, char *p_src)
306{
307    tBTA_GATTC *p_dest_data = (tBTA_GATTC*) p_dest;
308    tBTA_GATTC *p_src_data = (tBTA_GATTC*) p_src;
309
310    if (!p_src_data || !p_dest_data)
311       return;
312
313    // Copy basic structure first
314    maybe_non_aligned_memcpy(p_dest_data, p_src_data, sizeof(*p_src_data));
315
316    // Allocate buffer for request data if necessary
317    switch (event)
318    {
319        case BTA_GATTC_READ_CHAR_EVT:
320        case BTA_GATTC_READ_DESCR_EVT:
321
322            if (p_src_data->read.p_value != NULL)
323            {
324                p_dest_data->read.p_value = osi_malloc(sizeof(tBTA_GATT_UNFMT));
325
326                memcpy(p_dest_data->read.p_value, p_src_data->read.p_value,
327                       sizeof(tBTA_GATT_UNFMT));
328
329                // Allocate buffer for att value if necessary
330                if (p_src_data->read.p_value->len > 0 &&
331                    p_src_data->read.p_value->p_value != NULL) {
332                    p_dest_data->read.p_value->p_value =
333                        osi_malloc(p_src_data->read.p_value->len);
334                    memcpy(p_dest_data->read.p_value->p_value,
335                           p_src_data->read.p_value->p_value,
336                           p_src_data->read.p_value->len);
337                }
338            } else {
339                BTIF_TRACE_WARNING("%s :Src read.p_value ptr is NULL for event  0x%x",
340                                    __FUNCTION__, event);
341                p_dest_data->read.p_value = NULL;
342
343            }
344            break;
345
346        default:
347            break;
348    }
349}
350
351static void btapp_gattc_free_req_data(UINT16 event, tBTA_GATTC *p_data)
352{
353    switch (event)
354    {
355        case BTA_GATTC_READ_CHAR_EVT:
356        case BTA_GATTC_READ_DESCR_EVT:
357            if (p_data != NULL && p_data->read.p_value != NULL)
358            {
359                if (p_data->read.p_value->len > 0)
360                    osi_free_and_reset((void **)&p_data->read.p_value->p_value);
361
362                osi_free_and_reset((void **)&p_data->read.p_value);
363            }
364            break;
365
366        default:
367            break;
368    }
369}
370
371static void btif_gattc_init_dev_cb(void)
372{
373    memset(p_dev_cb, 0, sizeof(btif_gattc_dev_cb_t));
374}
375
376static void btif_gattc_add_remote_bdaddr (BD_ADDR p_bda, uint8_t addr_type)
377{
378    uint8_t i;
379    for (i = 0; i < BTIF_GATT_MAX_OBSERVED_DEV; i++)
380    {
381        if (!p_dev_cb->remote_dev[i].in_use )
382        {
383            memcpy(p_dev_cb->remote_dev[i].bd_addr.address, p_bda, BD_ADDR_LEN);
384            p_dev_cb->addr_type = addr_type;
385            p_dev_cb->remote_dev[i].in_use = TRUE;
386            LOG_VERBOSE(LOG_TAG, "%s device added idx=%d", __FUNCTION__, i  );
387            break;
388        }
389    }
390
391    if ( i == BTIF_GATT_MAX_OBSERVED_DEV)
392    {
393        i= p_dev_cb->next_storage_idx;
394        memcpy(p_dev_cb->remote_dev[i].bd_addr.address, p_bda, BD_ADDR_LEN);
395        p_dev_cb->addr_type = addr_type;
396        p_dev_cb->remote_dev[i].in_use = TRUE;
397        LOG_VERBOSE(LOG_TAG, "%s device overwrite idx=%d", __FUNCTION__, i  );
398        p_dev_cb->next_storage_idx++;
399        if (p_dev_cb->next_storage_idx >= BTIF_GATT_MAX_OBSERVED_DEV)
400               p_dev_cb->next_storage_idx = 0;
401    }
402}
403
404static BOOLEAN btif_gattc_find_bdaddr (BD_ADDR p_bda)
405{
406    uint8_t i;
407    for (i = 0; i < BTIF_GATT_MAX_OBSERVED_DEV; i++)
408    {
409        if (p_dev_cb->remote_dev[i].in_use &&
410            !memcmp(p_dev_cb->remote_dev[i].bd_addr.address, p_bda, BD_ADDR_LEN))
411        {
412            return TRUE;
413        }
414    }
415    return FALSE;
416}
417
418static void btif_gattc_update_properties ( btif_gattc_cb_t *p_btif_cb )
419{
420    uint8_t remote_name_len;
421    uint8_t *p_eir_remote_name=NULL;
422    bt_bdname_t bdname;
423
424    p_eir_remote_name = BTM_CheckEirData(p_btif_cb->value,
425                                         BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
426
427    if (p_eir_remote_name == NULL)
428    {
429        p_eir_remote_name = BTM_CheckEirData(p_btif_cb->value,
430                                BT_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
431    }
432
433    if (p_eir_remote_name)
434    {
435        memcpy(bdname.name, p_eir_remote_name, remote_name_len);
436        bdname.name[remote_name_len]='\0';
437
438        LOG_VERBOSE(LOG_TAG, "%s BLE device name=%s len=%d dev_type=%d", __FUNCTION__, bdname.name,
439              remote_name_len, p_btif_cb->device_type  );
440        btif_dm_update_ble_remote_properties( p_btif_cb->bd_addr.address,   bdname.name,
441                                               p_btif_cb->device_type);
442    }
443}
444
445static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
446{
447    LOG_VERBOSE(LOG_TAG, "%s: Event %d", __FUNCTION__, event);
448
449    tBTA_GATTC *p_data = (tBTA_GATTC*) p_param;
450    switch (event)
451    {
452        case BTA_GATTC_REG_EVT:
453        {
454            bt_uuid_t app_uuid;
455            bta_to_btif_uuid(&app_uuid, &p_data->reg_oper.app_uuid);
456            HAL_CBACK(bt_gatt_callbacks, client->register_client_cb
457                , p_data->reg_oper.status
458                , p_data->reg_oper.client_if
459                , &app_uuid
460            );
461            break;
462        }
463
464        case BTA_GATTC_DEREG_EVT:
465            break;
466
467        case BTA_GATTC_READ_CHAR_EVT:
468        {
469            btgatt_read_params_t data;
470            set_read_value(&data, &p_data->read);
471
472            HAL_CBACK(bt_gatt_callbacks, client->read_characteristic_cb
473                , p_data->read.conn_id, p_data->read.status, &data);
474            break;
475        }
476
477        case BTA_GATTC_WRITE_CHAR_EVT:
478        case BTA_GATTC_PREP_WRITE_EVT:
479        {
480            HAL_CBACK(bt_gatt_callbacks, client->write_characteristic_cb,
481                p_data->write.conn_id, p_data->write.status, p_data->write.handle);
482            break;
483        }
484
485        case BTA_GATTC_EXEC_EVT:
486        {
487            HAL_CBACK(bt_gatt_callbacks, client->execute_write_cb
488                , p_data->exec_cmpl.conn_id, p_data->exec_cmpl.status
489            );
490            break;
491        }
492
493        case BTA_GATTC_SEARCH_CMPL_EVT:
494        {
495            HAL_CBACK(bt_gatt_callbacks, client->search_complete_cb
496                , p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
497            break;
498        }
499
500        case BTA_GATTC_SEARCH_RES_EVT:
501        {
502            /* Do nothing */
503            break;
504        }
505
506        case BTA_GATTC_READ_DESCR_EVT:
507        {
508            btgatt_read_params_t data;
509            set_read_value(&data, &p_data->read);
510
511            HAL_CBACK(bt_gatt_callbacks, client->read_descriptor_cb
512                , p_data->read.conn_id, p_data->read.status, &data);
513            break;
514        }
515
516        case BTA_GATTC_WRITE_DESCR_EVT:
517        {
518            HAL_CBACK(bt_gatt_callbacks, client->write_descriptor_cb,
519                p_data->write.conn_id, p_data->write.status, p_data->write.handle);
520            break;
521        }
522
523        case BTA_GATTC_NOTIF_EVT:
524        {
525            btgatt_notify_params_t data;
526
527            bdcpy(data.bda.address, p_data->notify.bda);
528            memcpy(data.value, p_data->notify.value, p_data->notify.len);
529
530            data.handle = p_data->notify.handle;
531            data.is_notify = p_data->notify.is_notify;
532            data.len = p_data->notify.len;
533
534            HAL_CBACK(bt_gatt_callbacks, client->notify_cb, p_data->notify.conn_id, &data);
535
536            if (p_data->notify.is_notify == FALSE)
537                BTA_GATTC_SendIndConfirm(p_data->notify.conn_id, p_data->notify.handle);
538
539            break;
540        }
541
542        case BTA_GATTC_OPEN_EVT:
543        {
544            bt_bdaddr_t bda;
545            bdcpy(bda.address, p_data->open.remote_bda);
546
547            HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id
548                , p_data->open.status, p_data->open.client_if, &bda);
549
550            if (GATT_DEF_BLE_MTU_SIZE != p_data->open.mtu && p_data->open.mtu)
551            {
552                HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb, p_data->open.conn_id
553                    , p_data->open.status , p_data->open.mtu);
554            }
555
556            if (p_data->open.status == BTA_GATT_OK)
557                btif_gatt_check_encrypted_link(p_data->open.remote_bda, p_data->open.transport);
558            break;
559        }
560
561        case BTA_GATTC_CLOSE_EVT:
562        {
563            bt_bdaddr_t bda;
564            bdcpy(bda.address, p_data->close.remote_bda);
565            HAL_CBACK(bt_gatt_callbacks, client->close_cb, p_data->close.conn_id
566                , p_data->status, p_data->close.client_if, &bda);
567            break;
568        }
569
570        case BTA_GATTC_ACL_EVT:
571            LOG_DEBUG(LOG_TAG, "BTA_GATTC_ACL_EVT: status = %d", p_data->status);
572            /* Ignore for now */
573            break;
574
575        case BTA_GATTC_CANCEL_OPEN_EVT:
576            break;
577
578        case BTIF_GATT_OBSERVE_EVT:
579        {
580            btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param;
581            uint8_t remote_name_len;
582            uint8_t *p_eir_remote_name=NULL;
583            bt_device_type_t dev_type;
584            bt_property_t properties;
585
586            p_eir_remote_name = BTM_CheckEirData(p_btif_cb->value,
587                                         BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
588
589            if (p_eir_remote_name == NULL)
590            {
591                p_eir_remote_name = BTM_CheckEirData(p_btif_cb->value,
592                                BT_EIR_SHORTENED_LOCAL_NAME_TYPE, &remote_name_len);
593            }
594
595            if ((p_btif_cb->addr_type != BLE_ADDR_RANDOM) || (p_eir_remote_name))
596            {
597               if (!btif_gattc_find_bdaddr(p_btif_cb->bd_addr.address))
598               {
599                  btif_gattc_add_remote_bdaddr(p_btif_cb->bd_addr.address, p_btif_cb->addr_type);
600                  btif_gattc_update_properties(p_btif_cb);
601               }
602            }
603
604             dev_type =  p_btif_cb->device_type;
605             BTIF_STORAGE_FILL_PROPERTY(&properties,
606                        BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type), &dev_type);
607             btif_storage_set_remote_device_property(&(p_btif_cb->bd_addr), &properties);
608
609            btif_storage_set_remote_addr_type( &p_btif_cb->bd_addr, p_btif_cb->addr_type);
610
611            HAL_CBACK(bt_gatt_callbacks, client->scan_result_cb,
612                      &p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->value);
613            break;
614        }
615
616        case BTIF_GATTC_RSSI_EVT:
617        {
618            btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param;
619            HAL_CBACK(bt_gatt_callbacks, client->read_remote_rssi_cb, p_btif_cb->client_if,
620                      &p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->status);
621            break;
622        }
623
624        case BTA_GATTC_LISTEN_EVT:
625        {
626            HAL_CBACK(bt_gatt_callbacks, client->listen_cb
627                , p_data->reg_oper.status
628                , p_data->reg_oper.client_if
629            );
630            break;
631        }
632
633        case BTA_GATTC_CFG_MTU_EVT:
634        {
635            HAL_CBACK(bt_gatt_callbacks, client->configure_mtu_cb, p_data->cfg_mtu.conn_id
636                , p_data->cfg_mtu.status , p_data->cfg_mtu.mtu);
637            break;
638        }
639
640        case BTA_GATTC_MULT_ADV_ENB_EVT:
641        {
642            btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param;
643            if (0xFF != p_btif_cb->inst_id)
644                btif_multi_adv_add_instid_map(p_btif_cb->client_if, p_btif_cb->inst_id, false);
645            HAL_CBACK(bt_gatt_callbacks, client->multi_adv_enable_cb
646                    , p_btif_cb->client_if
647                    , p_btif_cb->status
648                );
649            btif_multi_adv_timer_ctrl(p_btif_cb->client_if,
650                                      (p_btif_cb->status == BTA_GATT_OK) ?
651                                      btif_multi_adv_stop_cb : NULL);
652            break;
653        }
654
655        case BTA_GATTC_MULT_ADV_UPD_EVT:
656        {
657            btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param;
658            HAL_CBACK(bt_gatt_callbacks, client->multi_adv_update_cb
659                , p_btif_cb->client_if
660                , p_btif_cb->status
661            );
662            btif_multi_adv_timer_ctrl(p_btif_cb->client_if,
663                                      (p_btif_cb->status == BTA_GATT_OK) ?
664                                      btif_multi_adv_stop_cb : NULL);
665            break;
666        }
667
668        case BTA_GATTC_MULT_ADV_DATA_EVT:
669         {
670            btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param;
671            btif_gattc_clear_clientif(p_btif_cb->client_if, FALSE);
672            HAL_CBACK(bt_gatt_callbacks, client->multi_adv_data_cb
673                , p_btif_cb->client_if
674                , p_btif_cb->status
675            );
676            break;
677        }
678
679        case BTA_GATTC_MULT_ADV_DIS_EVT:
680        {
681            btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param;
682            btif_gattc_clear_clientif(p_btif_cb->client_if, TRUE);
683            HAL_CBACK(bt_gatt_callbacks, client->multi_adv_disable_cb
684                , p_btif_cb->client_if
685                , p_btif_cb->status
686            );
687            break;
688        }
689
690        case BTA_GATTC_ADV_DATA_EVT:
691        {
692            btif_gattc_cleanup_inst_cb(STD_ADV_INSTID, FALSE);
693            /* No HAL callback available */
694            break;
695        }
696
697        case BTA_GATTC_CONGEST_EVT:
698            HAL_CBACK(bt_gatt_callbacks, client->congestion_cb
699                , p_data->congest.conn_id
700                , p_data->congest.congested
701            );
702            break;
703
704        case BTA_GATTC_BTH_SCAN_CFG_EVT:
705        {
706            btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*) p_param;
707            HAL_CBACK(bt_gatt_callbacks, client->batchscan_cfg_storage_cb
708                , p_data->client_if
709                , p_data->status
710            );
711            break;
712        }
713
714        case BTA_GATTC_BTH_SCAN_ENB_EVT:
715        {
716            btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*) p_param;
717            HAL_CBACK(bt_gatt_callbacks, client->batchscan_enb_disable_cb
718                    , ENABLE_BATCH_SCAN
719                    , p_data->client_if
720                    , p_data->status);
721            break;
722        }
723
724        case BTA_GATTC_BTH_SCAN_DIS_EVT:
725        {
726            btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*) p_param;
727            HAL_CBACK(bt_gatt_callbacks, client->batchscan_enb_disable_cb
728                    , DISABLE_BATCH_SCAN
729                    , p_data->client_if
730                    , p_data->status);
731            break;
732        }
733
734        case BTA_GATTC_BTH_SCAN_THR_EVT:
735        {
736            btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*) p_param;
737            HAL_CBACK(bt_gatt_callbacks, client->batchscan_threshold_cb
738                    , p_data->client_if);
739            break;
740        }
741
742        case BTA_GATTC_BTH_SCAN_RD_EVT:
743        {
744            btgatt_batch_track_cb_t *p_data = (btgatt_batch_track_cb_t*) p_param;
745            uint8_t *p_rep_data = NULL;
746
747            if (p_data->read_reports.data_len > 0 && NULL != p_data->read_reports.p_rep_data)
748            {
749                p_rep_data = osi_malloc(p_data->read_reports.data_len);
750                memcpy(p_rep_data, p_data->read_reports.p_rep_data, p_data->read_reports.data_len);
751            }
752
753            HAL_CBACK(bt_gatt_callbacks, client->batchscan_reports_cb
754                    , p_data->client_if, p_data->status, p_data->read_reports.report_format
755                    , p_data->read_reports.num_records, p_data->read_reports.data_len, p_rep_data);
756            osi_free(p_rep_data);
757            break;
758        }
759
760        case BTA_GATTC_SCAN_FLT_CFG_EVT:
761        {
762            btgatt_adv_filter_cb_t *p_btif_cb = (btgatt_adv_filter_cb_t*) p_param;
763            HAL_CBACK(bt_gatt_callbacks, client->scan_filter_cfg_cb, p_btif_cb->action,
764                      p_btif_cb->client_if, p_btif_cb->status, p_btif_cb->cond_op,
765                      p_btif_cb->avbl_space);
766            break;
767        }
768
769        case BTA_GATTC_SCAN_FLT_PARAM_EVT:
770        {
771            btgatt_adv_filter_cb_t *p_data = (btgatt_adv_filter_cb_t*) p_param;
772            BTIF_TRACE_DEBUG("BTA_GATTC_SCAN_FLT_PARAM_EVT: %d, %d, %d, %d",p_data->client_if,
773                p_data->action, p_data->avbl_space, p_data->status);
774            HAL_CBACK(bt_gatt_callbacks, client->scan_filter_param_cb
775                    , p_data->action, p_data->client_if, p_data->status
776                    , p_data->avbl_space);
777            break;
778        }
779
780        case BTA_GATTC_SCAN_FLT_STATUS_EVT:
781        {
782            btgatt_adv_filter_cb_t *p_data = (btgatt_adv_filter_cb_t*) p_param;
783            BTIF_TRACE_DEBUG("BTA_GATTC_SCAN_FLT_STATUS_EVT: %d, %d, %d",p_data->client_if,
784                p_data->action, p_data->status);
785            HAL_CBACK(bt_gatt_callbacks, client->scan_filter_status_cb
786                    , p_data->action, p_data->client_if, p_data->status);
787            break;
788        }
789
790        case BTA_GATTC_ADV_VSC_EVT:
791        {
792            btgatt_track_adv_info_t *p_data = (btgatt_track_adv_info_t*)p_param;
793            btgatt_track_adv_info_t adv_info_data;
794
795            memset(&adv_info_data, 0, sizeof(btgatt_track_adv_info_t));
796
797            btif_gatt_move_track_adv_data(&adv_info_data, p_data);
798            HAL_CBACK(bt_gatt_callbacks, client->track_adv_event_cb, &adv_info_data);
799            break;
800        }
801
802        case BTIF_GATTC_SCAN_PARAM_EVT:
803        {
804            btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t *)p_param;
805            HAL_CBACK(bt_gatt_callbacks, client->scan_parameter_setup_completed_cb,
806                      p_btif_cb->client_if, btif_gattc_translate_btm_status(p_btif_cb->status));
807            break;
808        }
809
810        default:
811            LOG_ERROR(LOG_TAG, "%s: Unhandled event (%d)!", __FUNCTION__, event);
812            break;
813    }
814
815    btapp_gattc_free_req_data(event, p_data);
816}
817
818static void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
819{
820    bt_status_t status = btif_transfer_context(btif_gattc_upstreams_evt,
821                    (uint16_t) event, (void*) p_data, sizeof(tBTA_GATTC), btapp_gattc_req_data);
822    ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
823}
824
825static void bta_gattc_multi_adv_cback(tBTA_BLE_MULTI_ADV_EVT event, UINT8 inst_id,
826                                    void *p_ref, tBTA_STATUS call_status)
827{
828    btif_gattc_cb_t btif_cb;
829    tBTA_GATTC_EVT upevt;
830    uint8_t client_if = 0;
831
832    if (NULL == p_ref)
833    {
834        BTIF_TRACE_WARNING("%s Invalid p_ref received",__FUNCTION__);
835    }
836    else
837    {
838        client_if = *(UINT8 *) p_ref;
839    }
840
841    BTIF_TRACE_DEBUG("%s -Inst ID %d, Status:%x, client_if:%d",__FUNCTION__,inst_id, call_status,
842                       client_if);
843    btif_cb.status = call_status;
844    btif_cb.client_if = client_if;
845    btif_cb.inst_id = inst_id;
846
847    switch(event)
848    {
849        case BTA_BLE_MULTI_ADV_ENB_EVT:
850            upevt = BTA_GATTC_MULT_ADV_ENB_EVT;
851            break;
852
853        case BTA_BLE_MULTI_ADV_DISABLE_EVT:
854            upevt = BTA_GATTC_MULT_ADV_DIS_EVT;
855            break;
856
857        case BTA_BLE_MULTI_ADV_PARAM_EVT:
858            upevt = BTA_GATTC_MULT_ADV_UPD_EVT;
859            break;
860
861        case BTA_BLE_MULTI_ADV_DATA_EVT:
862            upevt = BTA_GATTC_MULT_ADV_DATA_EVT;
863            break;
864
865        default:
866            return;
867    }
868
869    bt_status_t status = btif_transfer_context(btif_gattc_upstreams_evt, (uint16_t) upevt,
870                        (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
871    ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
872}
873
874static void bta_gattc_set_adv_data_cback(tBTA_STATUS call_status)
875{
876    UNUSED(call_status);
877    btif_gattc_cb_t btif_cb;
878    btif_cb.status = call_status;
879    btif_cb.action = 0;
880    btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_ADV_DATA_EVT,
881                          (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
882}
883
884static void bta_batch_scan_setup_cb (tBTA_BLE_BATCH_SCAN_EVT evt,
885                                            tBTA_DM_BLE_REF_VALUE ref_value, tBTA_STATUS status)
886{
887    UINT8 upevt = 0;
888    btgatt_batch_track_cb_t btif_scan_track_cb;
889
890    btif_scan_track_cb.status = status;
891    btif_scan_track_cb.client_if = ref_value;
892    BTIF_TRACE_DEBUG("bta_batch_scan_setup_cb-Status:%x, client_if:%d, evt=%d",
893            status, ref_value, evt);
894
895    switch(evt)
896    {
897        case BTA_BLE_BATCH_SCAN_ENB_EVT:
898        {
899           upevt = BTA_GATTC_BTH_SCAN_ENB_EVT;
900           break;
901        }
902
903        case BTA_BLE_BATCH_SCAN_DIS_EVT:
904        {
905           upevt = BTA_GATTC_BTH_SCAN_DIS_EVT;
906           break;
907        }
908
909        case BTA_BLE_BATCH_SCAN_CFG_STRG_EVT:
910        {
911           upevt = BTA_GATTC_BTH_SCAN_CFG_EVT;
912           break;
913        }
914
915        case BTA_BLE_BATCH_SCAN_DATA_EVT:
916        {
917           upevt = BTA_GATTC_BTH_SCAN_RD_EVT;
918           break;
919        }
920
921        case BTA_BLE_BATCH_SCAN_THRES_EVT:
922        {
923           upevt = BTA_GATTC_BTH_SCAN_THR_EVT;
924           break;
925        }
926
927        default:
928            return;
929    }
930
931    btif_transfer_context(btif_gattc_upstreams_evt, upevt,(char*) &btif_scan_track_cb,
932                          sizeof(btgatt_batch_track_cb_t), NULL);
933
934}
935
936static void bta_batch_scan_threshold_cb(tBTA_DM_BLE_REF_VALUE ref_value)
937{
938    btgatt_batch_track_cb_t btif_scan_track_cb;
939    btif_scan_track_cb.status = 0;
940    btif_scan_track_cb.client_if = ref_value;
941
942    BTIF_TRACE_DEBUG("%s - client_if:%d",__FUNCTION__, ref_value);
943
944    btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_BTH_SCAN_THR_EVT,
945                          (char*) &btif_scan_track_cb, sizeof(btif_gattc_cb_t), NULL);
946}
947
948static void bta_batch_scan_reports_cb(tBTA_DM_BLE_REF_VALUE ref_value, UINT8 report_format,
949                                            UINT8 num_records, UINT16 data_len,
950                                            UINT8* p_rep_data, tBTA_STATUS status)
951{
952    btgatt_batch_track_cb_t btif_scan_track_cb;
953    memset(&btif_scan_track_cb, 0, sizeof(btgatt_batch_track_cb_t));
954    BTIF_TRACE_DEBUG("%s - client_if:%d, %d, %d, %d",__FUNCTION__, ref_value, status, num_records,
955                                    data_len);
956
957    btif_scan_track_cb.status = status;
958
959    btif_scan_track_cb.client_if = ref_value;
960    btif_scan_track_cb.read_reports.report_format = report_format;
961    btif_scan_track_cb.read_reports.data_len = data_len;
962    btif_scan_track_cb.read_reports.num_records = num_records;
963
964    if (data_len > 0)
965    {
966        btif_scan_track_cb.read_reports.p_rep_data = osi_malloc(data_len);
967        memcpy(btif_scan_track_cb.read_reports.p_rep_data, p_rep_data, data_len);
968        osi_free(p_rep_data);
969    }
970
971    btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_BTH_SCAN_RD_EVT,
972        (char*) &btif_scan_track_cb, sizeof(btgatt_batch_track_cb_t), NULL);
973
974    if (data_len > 0)
975        osi_free_and_reset((void **)&btif_scan_track_cb.read_reports.p_rep_data);
976}
977
978static void bta_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
979{
980    btif_gattc_cb_t btif_cb;
981    uint8_t len;
982
983    switch (event)
984    {
985        case BTA_DM_INQ_RES_EVT:
986        {
987            bdcpy(btif_cb.bd_addr.address, p_data->inq_res.bd_addr);
988            btif_cb.device_type = p_data->inq_res.device_type;
989            btif_cb.rssi = p_data->inq_res.rssi;
990            btif_cb.addr_type = p_data->inq_res.ble_addr_type;
991            btif_cb.flag = p_data->inq_res.flag;
992            if (p_data->inq_res.p_eir)
993            {
994                memcpy(btif_cb.value, p_data->inq_res.p_eir, 62);
995                if (BTM_CheckEirData(p_data->inq_res.p_eir, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE,
996                                      &len))
997                {
998                    p_data->inq_res.remt_name_not_required  = TRUE;
999                }
1000            }
1001        }
1002        break;
1003
1004        case BTA_DM_INQ_CMPL_EVT:
1005        {
1006            BTIF_TRACE_DEBUG("%s  BLE observe complete. Num Resp %d",
1007                              __FUNCTION__,p_data->inq_cmpl.num_resps);
1008            return;
1009        }
1010
1011        default:
1012        BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event);
1013        return;
1014    }
1015    btif_transfer_context(btif_gattc_upstreams_evt, BTIF_GATT_OBSERVE_EVT,
1016                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1017}
1018
1019static void bta_track_adv_event_cb(tBTA_DM_BLE_TRACK_ADV_DATA *p_track_adv_data)
1020{
1021    btgatt_track_adv_info_t btif_scan_track_cb;
1022    BTIF_TRACE_DEBUG("%s",__FUNCTION__);
1023    btif_gatt_move_track_adv_data(&btif_scan_track_cb,
1024                (btgatt_track_adv_info_t*)p_track_adv_data);
1025
1026    btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_ADV_VSC_EVT,
1027                          (char*) &btif_scan_track_cb, sizeof(btgatt_track_adv_info_t), NULL);
1028}
1029
1030static void btm_read_rssi_cb (tBTM_RSSI_RESULTS *p_result)
1031{
1032    if (!p_result)
1033      return;
1034
1035    btif_gattc_cb_t btif_cb;
1036
1037    bdcpy(btif_cb.bd_addr.address, p_result->rem_bda);
1038    btif_cb.rssi = p_result->rssi;
1039    btif_cb.status = p_result->status;
1040    btif_cb.client_if = rssi_request_client_if;
1041    btif_transfer_context(btif_gattc_upstreams_evt, BTIF_GATTC_RSSI_EVT,
1042                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1043}
1044
1045static void bta_scan_param_setup_cb(tGATT_IF client_if, tBTM_STATUS status)
1046{
1047    btif_gattc_cb_t btif_cb;
1048
1049    btif_cb.status = status;
1050    btif_cb.client_if = client_if;
1051    btif_transfer_context(btif_gattc_upstreams_evt, BTIF_GATTC_SCAN_PARAM_EVT,
1052                          (char *)&btif_cb, sizeof(btif_gattc_cb_t), NULL);
1053}
1054
1055static void bta_scan_filt_cfg_cb(tBTA_DM_BLE_PF_ACTION action, tBTA_DM_BLE_SCAN_COND_OP cfg_op,
1056                                tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, tBTA_STATUS status,
1057                                tBTA_DM_BLE_REF_VALUE ref_value)
1058{
1059    btgatt_adv_filter_cb_t btif_cb;
1060    btif_cb.status = status;
1061    btif_cb.action = action;
1062    btif_cb.cond_op = cfg_op;
1063    btif_cb.avbl_space = avbl_space;
1064    btif_cb.client_if = ref_value;
1065    btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_SCAN_FLT_CFG_EVT,
1066                          (char*) &btif_cb, sizeof(btgatt_adv_filter_cb_t), NULL);
1067}
1068
1069static void bta_scan_filt_param_setup_cb(UINT8 action_type,
1070                                        tBTA_DM_BLE_PF_AVBL_SPACE avbl_space,
1071                                        tBTA_DM_BLE_REF_VALUE ref_value, tBTA_STATUS status)
1072{
1073    btgatt_adv_filter_cb_t btif_cb;
1074
1075    btif_cb.status = status;
1076    btif_cb.action = action_type;
1077    btif_cb.client_if = ref_value;
1078    btif_cb.avbl_space = avbl_space;
1079    btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_SCAN_FLT_PARAM_EVT,
1080                          (char*) &btif_cb, sizeof(btgatt_adv_filter_cb_t), NULL);
1081}
1082
1083static void bta_scan_filt_status_cb(UINT8 action, tBTA_STATUS status,
1084                                    tBTA_DM_BLE_REF_VALUE ref_value)
1085{
1086    btgatt_adv_filter_cb_t btif_cb;
1087
1088    btif_cb.status = status;
1089    btif_cb.action = action;
1090    btif_cb.client_if = ref_value;
1091    btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_SCAN_FLT_STATUS_EVT,
1092                          (char*) &btif_cb, sizeof(btgatt_adv_filter_cb_t), NULL);
1093}
1094
1095static void btgattc_free_event_data(UINT16 event, char *event_data)
1096{
1097    switch (event)
1098    {
1099        case BTIF_GATTC_ADV_INSTANCE_SET_DATA:
1100        case BTIF_GATTC_SET_ADV_DATA:
1101        {
1102            btif_adv_data_t *adv_data = (btif_adv_data_t *)event_data;
1103            btif_gattc_adv_data_cleanup(adv_data);
1104            break;
1105        }
1106
1107        default:
1108            break;
1109    }
1110}
1111
1112static void btgattc_handle_event(uint16_t event, char* p_param)
1113{
1114    tBTA_GATT_STATUS           status;
1115    tBT_UUID                   uuid;
1116    tBTA_GATT_UNFMT            descr_val;
1117
1118    btif_gattc_cb_t* p_cb = (btif_gattc_cb_t*) p_param;
1119    if (!p_cb) return;
1120
1121    LOG_VERBOSE(LOG_TAG, "%s: Event %d", __FUNCTION__, event);
1122
1123    switch (event)
1124    {
1125        case BTIF_GATTC_REGISTER_APP:
1126            btif_to_bta_uuid(&uuid, &p_cb->uuid);
1127            btif_gattc_incr_app_count();
1128            BTA_GATTC_AppRegister(&uuid, bta_gattc_cback);
1129            break;
1130
1131        case BTIF_GATTC_UNREGISTER_APP:
1132            btif_gattc_clear_clientif(p_cb->client_if, TRUE);
1133            btif_gattc_decr_app_count();
1134            BTA_GATTC_AppDeregister(p_cb->client_if);
1135            break;
1136
1137        case BTIF_GATTC_SCAN_START:
1138            btif_gattc_init_dev_cb();
1139            BTA_DmBleObserve(TRUE, 0, bta_scan_results_cb);
1140            break;
1141
1142        case BTIF_GATTC_SCAN_STOP:
1143            BTA_DmBleObserve(FALSE, 0, 0);
1144            break;
1145
1146        case BTIF_GATTC_OPEN:
1147        {
1148            // Ensure device is in inquiry database
1149            int addr_type = 0;
1150            int device_type = 0;
1151            tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
1152
1153            if (btif_get_address_type(p_cb->bd_addr.address, &addr_type) &&
1154                btif_get_device_type(p_cb->bd_addr.address, &device_type) &&
1155                device_type != BT_DEVICE_TYPE_BREDR)
1156            {
1157                BTA_DmAddBleDevice(p_cb->bd_addr.address, addr_type, device_type);
1158            }
1159
1160            // Check for background connections
1161            if (!p_cb->is_direct)
1162            {
1163                // Check for privacy 1.0 and 1.1 controller and do not start background
1164                // connection if RPA offloading is not supported, since it will not
1165                // connect after change of random address
1166                if (!controller_get_interface()->supports_ble_privacy() &&
1167                   (p_cb->addr_type == BLE_ADDR_RANDOM) &&
1168                   BTM_BLE_IS_RESOLVE_BDA(p_cb->bd_addr.address))
1169                {
1170                    tBTM_BLE_VSC_CB vnd_capabilities;
1171                    BTM_BleGetVendorCapabilities(&vnd_capabilities);
1172                    if (!vnd_capabilities.rpa_offloading)
1173                    {
1174                        HAL_CBACK(bt_gatt_callbacks, client->open_cb, 0, BT_STATUS_UNSUPPORTED,
1175                                        p_cb->client_if, &p_cb->bd_addr);
1176                        return;
1177                    }
1178                }
1179                BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
1180            }
1181
1182            // Determine transport
1183            if (p_cb->transport != GATT_TRANSPORT_AUTO)
1184            {
1185                transport = p_cb->transport;
1186            } else {
1187                switch(device_type)
1188                {
1189                    case BT_DEVICE_TYPE_BREDR:
1190                        transport = BTA_GATT_TRANSPORT_BR_EDR;
1191                        break;
1192
1193                    case BT_DEVICE_TYPE_BLE:
1194                        transport = BTA_GATT_TRANSPORT_LE;
1195                        break;
1196
1197                    case BT_DEVICE_TYPE_DUMO:
1198                        if (p_cb->transport == GATT_TRANSPORT_LE)
1199                            transport = BTA_GATT_TRANSPORT_LE;
1200                        else
1201                            transport = BTA_GATT_TRANSPORT_BR_EDR;
1202                        break;
1203                }
1204            }
1205
1206            // Connect!
1207            BTIF_TRACE_DEBUG ("%s Transport=%d, device type=%d",
1208                                __func__, transport, device_type);
1209            BTA_GATTC_Open(p_cb->client_if, p_cb->bd_addr.address, p_cb->is_direct, transport);
1210            break;
1211        }
1212
1213        case BTIF_GATTC_CLOSE:
1214            // Disconnect established connections
1215            if (p_cb->conn_id != 0)
1216                BTA_GATTC_Close(p_cb->conn_id);
1217            else
1218                BTA_GATTC_CancelOpen(p_cb->client_if, p_cb->bd_addr.address, TRUE);
1219
1220            // Cancel pending background connections (remove from whitelist)
1221            BTA_GATTC_CancelOpen(p_cb->client_if, p_cb->bd_addr.address, FALSE);
1222            break;
1223
1224        case BTIF_GATTC_SEARCH_SERVICE:
1225        {
1226            if (p_cb->search_all)
1227            {
1228                BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, NULL);
1229            } else {
1230                btif_to_bta_uuid(&uuid, &p_cb->uuid);
1231                BTA_GATTC_ServiceSearchRequest(p_cb->conn_id, &uuid);
1232            }
1233            break;
1234        }
1235
1236        case BTIF_GATTC_GET_GATT_DB:
1237        {
1238            btgatt_db_element_t *db = NULL;
1239            int count = 0;
1240            BTA_GATTC_GetGattDb(p_cb->conn_id, 0x0000, 0xFFFF, &db, &count);
1241
1242            HAL_CBACK(bt_gatt_callbacks, client->get_gatt_db_cb,
1243                p_cb->conn_id, db, count);
1244            osi_free(db);
1245            break;
1246        }
1247
1248        case BTIF_GATTC_READ_CHAR:
1249            BTA_GATTC_ReadCharacteristic(p_cb->conn_id, p_cb->handle, p_cb->auth_req);
1250            break;
1251
1252        case BTIF_GATTC_READ_CHAR_DESCR:
1253            BTA_GATTC_ReadCharDescr(p_cb->conn_id, p_cb->handle, p_cb->auth_req);
1254            break;
1255
1256        case BTIF_GATTC_WRITE_CHAR:
1257            BTA_GATTC_WriteCharValue(p_cb->conn_id, p_cb->handle, p_cb->write_type,
1258                                     p_cb->len, p_cb->value, p_cb->auth_req);
1259            break;
1260
1261        case BTIF_GATTC_WRITE_CHAR_DESCR:
1262            descr_val.len = p_cb->len;
1263            descr_val.p_value = p_cb->value;
1264
1265            BTA_GATTC_WriteCharDescr(p_cb->conn_id, p_cb->handle,
1266                                     p_cb->write_type, &descr_val,
1267                                     p_cb->auth_req);
1268            break;
1269
1270        case BTIF_GATTC_EXECUTE_WRITE:
1271            BTA_GATTC_ExecuteWrite(p_cb->conn_id, p_cb->action);
1272            break;
1273
1274        case BTIF_GATTC_REG_FOR_NOTIFICATION:
1275            status = BTA_GATTC_RegisterForNotifications(p_cb->client_if,
1276                                    p_cb->bd_addr.address, p_cb->handle);
1277
1278            HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
1279                p_cb->conn_id, 1, status, p_cb->handle);
1280            break;
1281
1282        case BTIF_GATTC_DEREG_FOR_NOTIFICATION:
1283            status = BTA_GATTC_DeregisterForNotifications(p_cb->client_if,
1284                                        p_cb->bd_addr.address, p_cb->handle);
1285
1286            HAL_CBACK(bt_gatt_callbacks, client->register_for_notification_cb,
1287                p_cb->conn_id, 0, status, p_cb->handle);
1288            break;
1289
1290        case BTIF_GATTC_REFRESH:
1291            BTA_GATTC_Refresh(p_cb->bd_addr.address);
1292            break;
1293
1294        case BTIF_GATTC_READ_RSSI:
1295            rssi_request_client_if = p_cb->client_if;
1296            BTM_ReadRSSI (p_cb->bd_addr.address, (tBTM_CMPL_CB *)btm_read_rssi_cb);
1297            break;
1298
1299        case BTIF_GATTC_SCAN_FILTER_PARAM_SETUP:
1300        {
1301            btgatt_adv_filter_cb_t *p_adv_filt_cb = (btgatt_adv_filter_cb_t *) p_param;
1302            if (1 == p_adv_filt_cb->adv_filt_param.dely_mode)
1303               BTA_DmBleTrackAdvertiser(p_adv_filt_cb->client_if, bta_track_adv_event_cb);
1304            BTA_DmBleScanFilterSetup(p_adv_filt_cb->action, p_adv_filt_cb->filt_index,
1305                &p_adv_filt_cb->adv_filt_param, NULL, bta_scan_filt_param_setup_cb,
1306                p_adv_filt_cb->client_if);
1307            break;
1308        }
1309
1310        case BTIF_GATTC_SCAN_FILTER_CONFIG:
1311        {
1312            btgatt_adv_filter_cb_t *p_adv_filt_cb = (btgatt_adv_filter_cb_t *) p_param;
1313            tBTA_DM_BLE_PF_COND_PARAM cond;
1314            memset(&cond, 0, sizeof(cond));
1315
1316            switch (p_adv_filt_cb->filt_type)
1317            {
1318                case BTA_DM_BLE_PF_ADDR_FILTER: // 0
1319                    bdcpy(cond.target_addr.bda, p_adv_filt_cb->bd_addr.address);
1320                    cond.target_addr.type = p_adv_filt_cb->addr_type;
1321                    BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action,
1322                                              p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index,
1323                                              &cond, bta_scan_filt_cfg_cb,
1324                                              p_adv_filt_cb->client_if);
1325                    break;
1326
1327                case BTA_DM_BLE_PF_SRVC_DATA: // 1
1328                    BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action,
1329                                            p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index,
1330                                            NULL, bta_scan_filt_cfg_cb, p_adv_filt_cb->client_if);
1331                    break;
1332
1333                case BTA_DM_BLE_PF_SRVC_UUID: // 2
1334                {
1335                    tBTA_DM_BLE_PF_COND_MASK uuid_mask;
1336
1337                    cond.srvc_uuid.p_target_addr = NULL;
1338                    cond.srvc_uuid.cond_logic = BTA_DM_BLE_PF_LOGIC_AND;
1339                    btif_to_bta_uuid(&cond.srvc_uuid.uuid, &p_adv_filt_cb->uuid);
1340
1341                    cond.srvc_uuid.p_uuid_mask = NULL;
1342                    if (p_adv_filt_cb->has_mask)
1343                    {
1344                        btif_to_bta_uuid_mask(&uuid_mask, &p_adv_filt_cb->uuid_mask);
1345                        cond.srvc_uuid.p_uuid_mask = &uuid_mask;
1346                    }
1347                    BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action,
1348                                              p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index,
1349                                              &cond, bta_scan_filt_cfg_cb,
1350                                              p_adv_filt_cb->client_if);
1351                    break;
1352                }
1353
1354                case BTA_DM_BLE_PF_SRVC_SOL_UUID: // 3
1355                {
1356                    cond.solicitate_uuid.p_target_addr = NULL;
1357                    cond.solicitate_uuid.cond_logic = BTA_DM_BLE_PF_LOGIC_AND;
1358                    btif_to_bta_uuid(&cond.solicitate_uuid.uuid, &p_adv_filt_cb->uuid);
1359                    BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action,
1360                                              p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index,
1361                                              &cond, bta_scan_filt_cfg_cb,
1362                                              p_adv_filt_cb->client_if);
1363                    break;
1364                }
1365
1366                case BTA_DM_BLE_PF_LOCAL_NAME: // 4
1367                {
1368                    cond.local_name.data_len = p_adv_filt_cb->value_len;
1369                    cond.local_name.p_data = p_adv_filt_cb->value;
1370                    BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action,
1371                                              p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index,
1372                                              &cond, bta_scan_filt_cfg_cb,
1373                                              p_adv_filt_cb->client_if);
1374                    break;
1375                }
1376
1377                case BTA_DM_BLE_PF_MANU_DATA: // 5
1378                {
1379                    cond.manu_data.company_id = p_adv_filt_cb->conn_id;
1380                    cond.manu_data.company_id_mask = p_adv_filt_cb->company_id_mask;
1381                    cond.manu_data.data_len = p_adv_filt_cb->value_len;
1382                    cond.manu_data.p_pattern = p_adv_filt_cb->value;
1383                    cond.manu_data.p_pattern_mask = p_adv_filt_cb->value_mask;
1384                    BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action,
1385                                              p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index,
1386                                              &cond, bta_scan_filt_cfg_cb,
1387                                              p_adv_filt_cb->client_if);
1388                    break;
1389                }
1390
1391                case BTA_DM_BLE_PF_SRVC_DATA_PATTERN: //6
1392                {
1393                    cond.srvc_data.data_len = p_adv_filt_cb->value_len;
1394                    cond.srvc_data.p_pattern = p_adv_filt_cb->value;
1395                    cond.srvc_data.p_pattern_mask = p_adv_filt_cb->value_mask;
1396                    BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action,
1397                                                p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index,
1398                                                &cond, bta_scan_filt_cfg_cb,
1399                                                p_adv_filt_cb->client_if);
1400                   break;
1401                }
1402
1403                default:
1404                    LOG_ERROR(LOG_TAG, "%s: Unknown filter type (%d)!", __FUNCTION__, p_cb->action);
1405                    break;
1406            }
1407            break;
1408        }
1409
1410        case BTIF_GATTC_SCAN_FILTER_CLEAR:
1411        {
1412            btgatt_adv_filter_cb_t *p_adv_filt_cb = (btgatt_adv_filter_cb_t *) p_param;
1413            BTA_DmBleCfgFilterCondition(BTA_DM_BLE_SCAN_COND_CLEAR, BTA_DM_BLE_PF_TYPE_ALL,
1414                                        p_adv_filt_cb->filt_index, NULL, bta_scan_filt_cfg_cb,
1415                                        p_adv_filt_cb->client_if);
1416            break;
1417        }
1418
1419        case BTIF_GATTC_SCAN_FILTER_ENABLE:
1420        {
1421            btgatt_adv_filter_cb_t *p_adv_filt_cb = (btgatt_adv_filter_cb_t *) p_param;
1422            BTA_DmEnableScanFilter(p_adv_filt_cb->action, bta_scan_filt_status_cb,
1423                                   p_adv_filt_cb->client_if);
1424            break;
1425        }
1426
1427        case BTIF_GATTC_LISTEN:
1428#if (defined(BLE_PERIPHERAL_MODE_SUPPORT) && (BLE_PERIPHERAL_MODE_SUPPORT == TRUE))
1429            BTA_GATTC_Listen(p_cb->client_if, p_cb->start, NULL);
1430#else
1431            BTA_GATTC_Broadcast(p_cb->client_if, p_cb->start);
1432#endif
1433            break;
1434
1435        case BTIF_GATTC_SET_ADV_DATA:
1436        {
1437            const btif_adv_data_t *p_adv_data = (btif_adv_data_t*) p_param;
1438            const int cbindex = CLNT_IF_IDX;
1439            if (cbindex >= 0 && btif_gattc_copy_datacb(cbindex, p_adv_data, false))
1440            {
1441                btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
1442                if (!p_adv_data->set_scan_rsp)
1443                {
1444                    BTA_DmBleSetAdvConfig(p_multi_adv_data_cb->inst_cb[cbindex].mask,
1445                        &p_multi_adv_data_cb->inst_cb[cbindex].data, bta_gattc_set_adv_data_cback);
1446                }
1447                else
1448                {
1449                    BTA_DmBleSetScanRsp(p_multi_adv_data_cb->inst_cb[cbindex].mask,
1450                        &p_multi_adv_data_cb->inst_cb[cbindex].data, bta_gattc_set_adv_data_cback);
1451                }
1452            }
1453            else
1454            {
1455                BTIF_TRACE_ERROR("%s:%s: failed to get instance data cbindex: %d",
1456                                 __func__, "BTIF_GATTC_SET_ADV_DATA", cbindex);
1457            }
1458            break;
1459        }
1460
1461        case BTIF_GATTC_ADV_INSTANCE_ENABLE:
1462        {
1463            btgatt_multi_adv_inst_cb *p_inst_cb = (btgatt_multi_adv_inst_cb*) p_param;
1464
1465            int cbindex = -1, arrindex = -1;
1466
1467            arrindex = btif_multi_adv_add_instid_map(p_inst_cb->client_if,INVALID_ADV_INST, true);
1468            if (arrindex >= 0)
1469                cbindex = btif_gattc_obtain_idx_for_datacb(p_inst_cb->client_if, CLNT_IF_IDX);
1470
1471            if (cbindex >= 0 && arrindex >= 0)
1472            {
1473                btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
1474                memcpy(&p_multi_adv_data_cb->inst_cb[cbindex].param,
1475                       &p_inst_cb->param, sizeof(tBTA_BLE_ADV_PARAMS));
1476                p_multi_adv_data_cb->inst_cb[cbindex].timeout_s = p_inst_cb->timeout_s;
1477                BTIF_TRACE_DEBUG("%s, client_if value: %d", __FUNCTION__,
1478                            p_multi_adv_data_cb->clntif_map[arrindex + arrindex]);
1479                BTA_BleEnableAdvInstance(&(p_multi_adv_data_cb->inst_cb[cbindex].param),
1480                    bta_gattc_multi_adv_cback,
1481                    &(p_multi_adv_data_cb->clntif_map[arrindex + arrindex]));
1482            }
1483            else
1484            {
1485                /* let the error propagate up from BTA layer */
1486                BTIF_TRACE_ERROR("%s invalid index in BTIF_GATTC_ENABLE_ADV",__FUNCTION__);
1487                BTA_BleEnableAdvInstance(&p_inst_cb->param, bta_gattc_multi_adv_cback, NULL);
1488            }
1489            break;
1490        }
1491
1492        case BTIF_GATTC_ADV_INSTANCE_UPDATE:
1493        {
1494            btgatt_multi_adv_inst_cb *p_inst_cb = (btgatt_multi_adv_inst_cb*) p_param;
1495            int inst_id = btif_multi_adv_instid_for_clientif(p_inst_cb->client_if);
1496            int cbindex = btif_gattc_obtain_idx_for_datacb(p_inst_cb->client_if, CLNT_IF_IDX);
1497            if (inst_id >= 0 && cbindex >= 0 && NULL != p_inst_cb)
1498            {
1499                btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
1500                memcpy(&p_multi_adv_data_cb->inst_cb[cbindex].param, &p_inst_cb->param,
1501                        sizeof(tBTA_BLE_ADV_PARAMS));
1502                BTA_BleUpdateAdvInstParam((UINT8)inst_id,
1503                    &(p_multi_adv_data_cb->inst_cb[cbindex].param));
1504            }
1505            else
1506                BTIF_TRACE_ERROR("%s invalid index in BTIF_GATTC_UPDATE_ADV", __FUNCTION__);
1507            break;
1508        }
1509
1510        case BTIF_GATTC_ADV_INSTANCE_SET_DATA:
1511        {
1512            btif_adv_data_t *p_adv_data = (btif_adv_data_t*) p_param;
1513            int cbindex = btif_gattc_obtain_idx_for_datacb(p_adv_data->client_if, CLNT_IF_IDX);
1514            int inst_id = btif_multi_adv_instid_for_clientif(p_adv_data->client_if);
1515            if (inst_id >= 0 && cbindex >= 0 && btif_gattc_copy_datacb(cbindex, p_adv_data, true))
1516            {
1517                btgatt_multi_adv_common_data *p_multi_adv_data_cb =
1518                    btif_obtain_multi_adv_data_cb();
1519                BTA_BleCfgAdvInstData(
1520                    (UINT8)inst_id,
1521                    p_adv_data->set_scan_rsp,
1522                    p_multi_adv_data_cb->inst_cb[cbindex].mask,
1523                    &p_multi_adv_data_cb->inst_cb[cbindex].data);
1524            }
1525            else
1526            {
1527                BTIF_TRACE_ERROR(
1528                    "%s:%s: failed to get invalid instance data: inst_id:%d "
1529                    "cbindex:%d",
1530                    __func__, "BTIF_GATTC_ADV_INSTANCE_SET_DATA", inst_id, cbindex);
1531            }
1532            break;
1533        }
1534
1535        case BTIF_GATTC_ADV_INSTANCE_DISABLE:
1536        {
1537            btgatt_multi_adv_inst_cb *p_inst_cb = (btgatt_multi_adv_inst_cb*) p_param;
1538            int inst_id = btif_multi_adv_instid_for_clientif(p_inst_cb->client_if);
1539            if (inst_id >=0)
1540                BTA_BleDisableAdvInstance((UINT8)inst_id);
1541            else
1542                BTIF_TRACE_ERROR("%s invalid instance ID in BTIF_GATTC_DISABLE_ADV",__FUNCTION__);
1543            break;
1544        }
1545
1546        case BTIF_GATTC_CONFIGURE_MTU:
1547            BTA_GATTC_ConfigureMTU(p_cb->conn_id, p_cb->len);
1548            break;
1549
1550        case BTIF_GATTC_CONN_PARAM_UPDT:
1551        {
1552            btif_conn_param_cb_t *p_conn_param_cb = (btif_conn_param_cb_t*) p_param;
1553            if (BTA_DmGetConnectionState(p_conn_param_cb->bd_addr.address))
1554            {
1555                BTA_DmBleUpdateConnectionParams(p_conn_param_cb->bd_addr.address,
1556                               p_conn_param_cb->min_interval, p_conn_param_cb->max_interval,
1557                               p_conn_param_cb->latency, p_conn_param_cb->timeout);
1558            } else {
1559                BTA_DmSetBlePrefConnParams(p_conn_param_cb->bd_addr.address,
1560                               p_conn_param_cb->min_interval, p_conn_param_cb->max_interval,
1561                               p_conn_param_cb->latency, p_conn_param_cb->timeout);
1562            }
1563            break;
1564        }
1565
1566        case BTIF_GATTC_SET_SCAN_PARAMS:
1567        {
1568            BTA_DmSetBleScanParams(p_cb->client_if, p_cb->scan_interval, p_cb->scan_window,
1569                                   BTM_BLE_SCAN_MODE_ACTI, bta_scan_param_setup_cb);
1570            break;
1571        }
1572
1573        case BTIF_GATTC_CONFIG_STORAGE_PARAMS:
1574        {
1575            btgatt_batch_track_cb_t *p_scan_track_cb = (btgatt_batch_track_cb_t *) p_param;
1576            BTA_DmBleSetStorageParams(p_scan_track_cb->batch_scan_full_max,
1577               p_scan_track_cb->batch_scan_trunc_max, p_scan_track_cb->batch_scan_notify_threshold,
1578               bta_batch_scan_setup_cb, bta_batch_scan_threshold_cb, bta_batch_scan_reports_cb,
1579               (tBTA_DM_BLE_REF_VALUE) p_scan_track_cb->client_if);
1580            break;
1581        }
1582
1583        case BTIF_GATTC_ENABLE_BATCH_SCAN:
1584        {
1585            btgatt_batch_track_cb_t *p_scan_track_cb = (btgatt_batch_track_cb_t *) p_param;
1586            BTA_DmBleEnableBatchScan(p_scan_track_cb->scan_mode, p_scan_track_cb->scan_interval,
1587               p_scan_track_cb->scan_window, p_scan_track_cb->discard_rule,
1588               p_scan_track_cb->addr_type, p_scan_track_cb->client_if);
1589            break;
1590        }
1591
1592        case BTIF_GATTC_DISABLE_BATCH_SCAN:
1593        {
1594            btgatt_batch_track_cb_t *p_scan_track_cb = (btgatt_batch_track_cb_t *) p_param;
1595            BTA_DmBleDisableBatchScan(p_scan_track_cb->client_if);
1596            break;
1597        }
1598
1599        case BTIF_GATTC_READ_BATCH_SCAN_REPORTS:
1600        {
1601            btgatt_batch_track_cb_t *p_scan_track_cb = (btgatt_batch_track_cb_t *) p_param;
1602            BTA_DmBleReadScanReports(p_scan_track_cb->scan_mode, p_scan_track_cb->client_if);
1603            break;
1604        }
1605
1606        default:
1607            LOG_ERROR(LOG_TAG, "%s: Unknown event (%d)!", __FUNCTION__, event);
1608            break;
1609    }
1610
1611    btgattc_free_event_data(event, p_param);
1612}
1613
1614/*******************************************************************************
1615**  Client API Functions
1616********************************************************************************/
1617
1618static bt_status_t btif_gattc_register_app(bt_uuid_t *uuid)
1619{
1620    CHECK_BTGATT_INIT();
1621    btif_gattc_cb_t btif_cb;
1622    memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
1623    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_REGISTER_APP,
1624                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1625}
1626
1627static bt_status_t btif_gattc_unregister_app(int client_if )
1628{
1629    CHECK_BTGATT_INIT();
1630    btif_gattc_cb_t btif_cb;
1631    btif_cb.client_if = (uint8_t) client_if;
1632    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_UNREGISTER_APP,
1633                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1634}
1635
1636static bt_status_t btif_gattc_scan( bool start )
1637{
1638    CHECK_BTGATT_INIT();
1639    btif_gattc_cb_t btif_cb;
1640    return btif_transfer_context(btgattc_handle_event, start ? BTIF_GATTC_SCAN_START : BTIF_GATTC_SCAN_STOP,
1641                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1642}
1643
1644static bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t *bd_addr,
1645                                        bool is_direct,int transport)
1646{
1647    CHECK_BTGATT_INIT();
1648    btif_gattc_cb_t btif_cb;
1649    btif_cb.client_if = (uint8_t) client_if;
1650    btif_cb.is_direct = is_direct ? 1 : 0;
1651    btif_cb.transport = (btgatt_transport_t)transport;
1652    bdcpy(btif_cb.bd_addr.address, bd_addr->address);
1653    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_OPEN,
1654                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1655}
1656
1657static bt_status_t btif_gattc_close( int client_if, const bt_bdaddr_t *bd_addr, int conn_id)
1658{
1659    CHECK_BTGATT_INIT();
1660    btif_gattc_cb_t btif_cb;
1661    btif_cb.client_if = (uint8_t) client_if;
1662    btif_cb.conn_id = (uint16_t) conn_id;
1663    bdcpy(btif_cb.bd_addr.address, bd_addr->address);
1664    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_CLOSE,
1665                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1666}
1667
1668static bt_status_t btif_gattc_listen(int client_if, bool start)
1669{
1670    CHECK_BTGATT_INIT();
1671    btif_gattc_cb_t btif_cb;
1672    btif_cb.client_if = (uint8_t) client_if;
1673    btif_cb.start = start ? 1 : 0;
1674    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_LISTEN,
1675                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1676}
1677
1678static void btif_gattc_deep_copy(UINT16 event, char *p_dest, char *p_src)
1679{
1680    switch (event)
1681    {
1682        case BTIF_GATTC_ADV_INSTANCE_SET_DATA:
1683        case BTIF_GATTC_SET_ADV_DATA:
1684        {
1685            const btif_adv_data_t *src = (btif_adv_data_t*) p_src;
1686            btif_adv_data_t *dst = (btif_adv_data_t*) p_dest;
1687            maybe_non_aligned_memcpy(dst, src, sizeof(*src));
1688
1689            if (src->p_manufacturer_data)
1690            {
1691                dst->p_manufacturer_data = osi_malloc(src->manufacturer_len);
1692                memcpy(dst->p_manufacturer_data, src->p_manufacturer_data,
1693                       src->manufacturer_len);
1694            }
1695
1696            if (src->p_service_data)
1697            {
1698                dst->p_service_data = osi_malloc(src->service_data_len);
1699                memcpy(dst->p_service_data, src->p_service_data, src->service_data_len);
1700            }
1701
1702            if (src->p_service_uuid)
1703            {
1704                dst->p_service_uuid = osi_malloc(src->service_uuid_len);
1705                memcpy(dst->p_service_uuid, src->p_service_uuid, src->service_uuid_len);
1706            }
1707            break;
1708        }
1709
1710        default:
1711            ASSERTC(false, "Unhandled deep copy", event);
1712            break;
1713    }
1714}
1715
1716static bt_status_t btif_gattc_set_adv_data(int client_if, bool set_scan_rsp, bool include_name,
1717                bool include_txpower, int min_interval, int max_interval, int appearance,
1718                uint16_t manufacturer_len, char* manufacturer_data,
1719                uint16_t service_data_len, char* service_data,
1720                uint16_t service_uuid_len, char* service_uuid)
1721{
1722    CHECK_BTGATT_INIT();
1723    btif_adv_data_t adv_data;
1724
1725    btif_gattc_adv_data_packager(client_if, set_scan_rsp, include_name,
1726        include_txpower, min_interval, max_interval, appearance, manufacturer_len,
1727        manufacturer_data, service_data_len, service_data, service_uuid_len, service_uuid,
1728        &adv_data);
1729
1730    bt_status_t status = btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SET_ADV_DATA,
1731                       (char*) &adv_data, sizeof(adv_data), btif_gattc_deep_copy);
1732    btif_gattc_adv_data_cleanup(&adv_data);
1733    return status;
1734}
1735
1736static bt_status_t btif_gattc_refresh( int client_if, const bt_bdaddr_t *bd_addr )
1737{
1738    CHECK_BTGATT_INIT();
1739    btif_gattc_cb_t btif_cb;
1740    btif_cb.client_if = (uint8_t) client_if;
1741    bdcpy(btif_cb.bd_addr.address, bd_addr->address);
1742    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_REFRESH,
1743                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1744}
1745
1746static bt_status_t btif_gattc_search_service(int conn_id, bt_uuid_t *filter_uuid )
1747{
1748    CHECK_BTGATT_INIT();
1749    btif_gattc_cb_t btif_cb;
1750    btif_cb.conn_id = (uint16_t) conn_id;
1751    btif_cb.search_all = filter_uuid ? 0 : 1;
1752    if (filter_uuid)
1753        memcpy(&btif_cb.uuid, filter_uuid, sizeof(bt_uuid_t));
1754    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SEARCH_SERVICE,
1755                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1756}
1757
1758static bt_status_t btif_gattc_get_gatt_db(int conn_id)
1759{
1760    CHECK_BTGATT_INIT();
1761    btif_gattc_cb_t btif_cb;
1762    btif_cb.conn_id = (uint16_t) conn_id;
1763
1764    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_GET_GATT_DB,
1765                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1766}
1767
1768
1769static bt_status_t btif_gattc_read_char(int conn_id, uint16_t handle, int auth_req)
1770{
1771    CHECK_BTGATT_INIT();
1772    btif_gattc_cb_t btif_cb;
1773    btif_cb.conn_id = (uint16_t) conn_id;
1774    btif_cb.handle = (uint16_t) handle;
1775    btif_cb.auth_req = (uint8_t) auth_req;
1776    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_READ_CHAR,
1777                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1778}
1779
1780static bt_status_t btif_gattc_read_char_descr(int conn_id, uint16_t handle, int auth_req)
1781{
1782    CHECK_BTGATT_INIT();
1783    btif_gattc_cb_t btif_cb;
1784    btif_cb.conn_id = (uint16_t) conn_id;
1785    btif_cb.handle = (uint16_t) handle;
1786    btif_cb.auth_req = (uint8_t) auth_req;
1787    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_READ_CHAR_DESCR,
1788                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1789}
1790
1791static bt_status_t btif_gattc_write_char(int conn_id, uint16_t handle, int write_type,
1792                                         int len, int auth_req, char* p_value)
1793{
1794    CHECK_BTGATT_INIT();
1795    btif_gattc_cb_t btif_cb;
1796    btif_cb.conn_id = (uint16_t) conn_id;
1797    btif_cb.handle = (uint16_t) handle;
1798    btif_cb.auth_req = (uint8_t) auth_req;
1799    btif_cb.write_type = (uint8_t) write_type;
1800    btif_cb.len = len > BTGATT_MAX_ATTR_LEN ? BTGATT_MAX_ATTR_LEN : len;
1801    memcpy(btif_cb.value, p_value, btif_cb.len);
1802    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_WRITE_CHAR,
1803                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1804}
1805
1806static bt_status_t btif_gattc_write_char_descr(int conn_id, uint16_t handle,
1807                                               int write_type, int len, int auth_req,
1808                                               char* p_value)
1809{
1810    CHECK_BTGATT_INIT();
1811    btif_gattc_cb_t btif_cb;
1812    btif_cb.conn_id = (uint16_t) conn_id;
1813    btif_cb.handle = (uint16_t) handle;
1814    btif_cb.auth_req = (uint8_t) auth_req;
1815    btif_cb.write_type = (uint8_t) write_type;
1816    btif_cb.len = len > BTGATT_MAX_ATTR_LEN ? BTGATT_MAX_ATTR_LEN : len;
1817    memcpy(btif_cb.value, p_value, btif_cb.len);
1818    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_WRITE_CHAR_DESCR,
1819                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1820}
1821
1822static bt_status_t btif_gattc_execute_write(int conn_id, int execute)
1823{
1824    CHECK_BTGATT_INIT();
1825    btif_gattc_cb_t btif_cb;
1826    btif_cb.conn_id = (uint16_t) conn_id;
1827    btif_cb.action = (uint8_t) execute;
1828    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_EXECUTE_WRITE,
1829                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1830}
1831
1832static bt_status_t btif_gattc_reg_for_notification(int client_if, const bt_bdaddr_t *bd_addr,
1833                                                   uint16_t handle)
1834{
1835    CHECK_BTGATT_INIT();
1836    btif_gattc_cb_t btif_cb;
1837    btif_cb.client_if = (uint8_t) client_if;
1838    bdcpy(btif_cb.bd_addr.address, bd_addr->address);
1839    btif_cb.handle = handle;
1840    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_REG_FOR_NOTIFICATION,
1841                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1842}
1843
1844static bt_status_t btif_gattc_dereg_for_notification(int client_if, const bt_bdaddr_t *bd_addr,
1845                                                     uint16_t handle)
1846{
1847    CHECK_BTGATT_INIT();
1848    btif_gattc_cb_t btif_cb;
1849    btif_cb.client_if = (uint8_t) client_if;
1850    bdcpy(btif_cb.bd_addr.address, bd_addr->address);
1851    btif_cb.handle = handle;
1852    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_DEREG_FOR_NOTIFICATION,
1853                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1854}
1855
1856static bt_status_t btif_gattc_read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr)
1857{
1858    CHECK_BTGATT_INIT();
1859    btif_gattc_cb_t btif_cb;
1860    btif_cb.client_if = (uint8_t) client_if;
1861    bdcpy(btif_cb.bd_addr.address, bd_addr->address);
1862    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_READ_RSSI,
1863                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1864}
1865
1866static bt_status_t btif_gattc_configure_mtu(int conn_id, int mtu)
1867{
1868    CHECK_BTGATT_INIT();
1869    btif_gattc_cb_t btif_cb;
1870    btif_cb.conn_id = conn_id;
1871    btif_cb.len = mtu; // Re-use len field
1872    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_CONFIGURE_MTU,
1873                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1874}
1875
1876static bt_status_t btif_gattc_conn_parameter_update(const bt_bdaddr_t *bd_addr, int min_interval,
1877                    int max_interval, int latency, int timeout)
1878{
1879    CHECK_BTGATT_INIT();
1880    btif_conn_param_cb_t btif_cb;
1881    btif_cb.min_interval = min_interval;
1882    btif_cb.max_interval = max_interval;
1883    btif_cb.latency = latency;
1884    btif_cb.timeout = timeout;
1885    bdcpy(btif_cb.bd_addr.address, bd_addr->address);
1886    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_CONN_PARAM_UPDT,
1887                                 (char*) &btif_cb, sizeof(btif_conn_param_cb_t), NULL);
1888}
1889
1890static bt_status_t btif_gattc_scan_filter_param_setup(btgatt_filt_param_setup_t
1891                                                      filt_param)
1892{
1893    CHECK_BTGATT_INIT();
1894    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
1895    btgatt_adv_filter_cb_t btif_filt_cb;
1896    memset(&btif_filt_cb, 0, sizeof(btgatt_adv_filter_cb_t));
1897    btif_filt_cb.client_if = filt_param.client_if;
1898    btif_filt_cb.action = filt_param.action;
1899    btif_filt_cb.filt_index = filt_param.filt_index;
1900    btif_filt_cb.adv_filt_param.feat_seln = filt_param.feat_seln;
1901    btif_filt_cb.adv_filt_param.list_logic_type = filt_param.list_logic_type;
1902    btif_filt_cb.adv_filt_param.filt_logic_type = filt_param.filt_logic_type;
1903    btif_filt_cb.adv_filt_param.rssi_high_thres = filt_param.rssi_high_thres;
1904    btif_filt_cb.adv_filt_param.rssi_low_thres = filt_param.rssi_low_thres;
1905    btif_filt_cb.adv_filt_param.dely_mode = filt_param.dely_mode;
1906    btif_filt_cb.adv_filt_param.found_timeout = filt_param.found_timeout;
1907    btif_filt_cb.adv_filt_param.lost_timeout = filt_param.lost_timeout;
1908    btif_filt_cb.adv_filt_param.found_timeout_cnt = filt_param.found_timeout_cnt;
1909    btif_filt_cb.adv_filt_param.num_of_tracking_entries = filt_param.num_of_tracking_entries;
1910    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_PARAM_SETUP,
1911                                 (char*) &btif_filt_cb, sizeof(btgatt_adv_filter_cb_t), NULL);
1912}
1913
1914static bt_status_t btif_gattc_scan_filter_add_remove(int client_if, int action,
1915                              int filt_type, int filt_index, int company_id,
1916                              int company_id_mask, const bt_uuid_t *p_uuid,
1917                              const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr,
1918                              char addr_type, int data_len, char* p_data, int mask_len,
1919                              char* p_mask)
1920{
1921    CHECK_BTGATT_INIT();
1922    btgatt_adv_filter_cb_t btif_filt_cb;
1923    memset(&btif_filt_cb, 0, sizeof(btgatt_adv_filter_cb_t));
1924    BTIF_TRACE_DEBUG("%s, %d, %d", __FUNCTION__, action, filt_type);
1925
1926    /* If data is passed, both mask and data have to be the same length */
1927    if (data_len != mask_len && NULL != p_data && NULL != p_mask)
1928        return BT_STATUS_PARM_INVALID;
1929
1930    btif_filt_cb.client_if = client_if;
1931    btif_filt_cb.action = action;
1932    btif_filt_cb.filt_index = filt_index;
1933    btif_filt_cb.filt_type = filt_type;
1934    btif_filt_cb.conn_id = company_id;
1935    btif_filt_cb.company_id_mask = company_id_mask ? company_id_mask : 0xFFFF;
1936    if (bd_addr)
1937        bdcpy(btif_filt_cb.bd_addr.address, bd_addr->address);
1938
1939    btif_filt_cb.addr_type = addr_type;
1940    btif_filt_cb.has_mask = (p_uuid_mask != NULL);
1941
1942    if (p_uuid != NULL)
1943        memcpy(&btif_filt_cb.uuid, p_uuid, sizeof(bt_uuid_t));
1944    if (p_uuid_mask != NULL)
1945        memcpy(&btif_filt_cb.uuid_mask, p_uuid_mask, sizeof(bt_uuid_t));
1946    if (p_data != NULL && data_len != 0)
1947    {
1948        memcpy(btif_filt_cb.value, p_data, data_len);
1949        btif_filt_cb.value_len = data_len;
1950        memcpy(btif_filt_cb.value_mask, p_mask, mask_len);
1951        btif_filt_cb.value_mask_len = mask_len;
1952    }
1953    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_CONFIG,
1954                                 (char*) &btif_filt_cb, sizeof(btgatt_adv_filter_cb_t), NULL);
1955}
1956
1957static bt_status_t btif_gattc_scan_filter_clear(int client_if, int filt_index)
1958{
1959    CHECK_BTGATT_INIT();
1960    BTIF_TRACE_DEBUG("%s, %d", __FUNCTION__, filt_index);
1961
1962    btgatt_adv_filter_cb_t btif_filt_cb;
1963    memset(&btif_filt_cb, 0, sizeof(btgatt_adv_filter_cb_t));
1964    btif_filt_cb.client_if = client_if;
1965    btif_filt_cb.filt_index = filt_index;
1966    btif_filt_cb.action = BTA_DM_BLE_SCAN_COND_CLEAR;
1967    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_CONFIG,
1968                                 (char*) &btif_filt_cb, sizeof(btgatt_adv_filter_cb_t), NULL);
1969}
1970
1971static bt_status_t btif_gattc_scan_filter_enable(int client_if, bool enable)
1972{
1973    int action = 0;
1974    CHECK_BTGATT_INIT();
1975    BTIF_TRACE_DEBUG("%s, %d", __FUNCTION__, enable);
1976
1977    btgatt_adv_filter_cb_t btif_filt_cb;
1978    memset(&btif_filt_cb, 0, sizeof(btgatt_adv_filter_cb_t));
1979    btif_filt_cb.client_if = client_if;
1980    if (true == enable)
1981        action = 1;
1982    btif_filt_cb.action = action;
1983    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_ENABLE,
1984                                 (char*) &btif_filt_cb, sizeof(btgatt_adv_filter_cb_t), NULL);
1985}
1986
1987static bt_status_t btif_gattc_set_scan_parameters(int client_if, int scan_interval,
1988                                                  int scan_window)
1989{
1990    CHECK_BTGATT_INIT();
1991    btif_gattc_cb_t btif_cb;
1992    btif_cb.client_if = client_if;
1993    btif_cb.scan_interval = scan_interval;
1994    btif_cb.scan_window = scan_window;
1995    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SET_SCAN_PARAMS,
1996                                 (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
1997}
1998
1999static int btif_gattc_get_device_type( const bt_bdaddr_t *bd_addr )
2000{
2001    int device_type = 0;
2002    char bd_addr_str[18] = {0};
2003
2004    bdaddr_to_string(bd_addr, bd_addr_str, sizeof(bd_addr_str));
2005    if (btif_config_get_int(bd_addr_str, "DevType", &device_type))
2006        return device_type;
2007    return 0;
2008}
2009
2010static bt_status_t btif_gattc_multi_adv_enable(int client_if, int min_interval, int max_interval,
2011                                            int adv_type, int chnl_map, int tx_power, int timeout_s)
2012{
2013    CHECK_BTGATT_INIT();
2014    btgatt_multi_adv_inst_cb adv_cb;
2015    memset(&adv_cb, 0, sizeof(btgatt_multi_adv_inst_cb));
2016    adv_cb.client_if = (uint8_t) client_if;
2017
2018    adv_cb.param.adv_int_min = min_interval;
2019    adv_cb.param.adv_int_max = max_interval;
2020    adv_cb.param.adv_type = adv_type;
2021    adv_cb.param.channel_map = chnl_map;
2022    adv_cb.param.adv_filter_policy = 0;
2023    adv_cb.param.tx_power = tx_power;
2024    adv_cb.timeout_s = timeout_s;
2025    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_ENABLE,
2026                             (char*) &adv_cb, sizeof(btgatt_multi_adv_inst_cb), NULL);
2027}
2028
2029static bt_status_t btif_gattc_multi_adv_update(int client_if, int min_interval, int max_interval,
2030                                            int adv_type, int chnl_map,int tx_power, int timeout_s)
2031{
2032    CHECK_BTGATT_INIT();
2033    btgatt_multi_adv_inst_cb adv_cb;
2034    memset(&adv_cb, 0, sizeof(btgatt_multi_adv_inst_cb));
2035    adv_cb.client_if = (uint8_t) client_if;
2036
2037    adv_cb.param.adv_int_min = min_interval;
2038    adv_cb.param.adv_int_max = max_interval;
2039    adv_cb.param.adv_type = adv_type;
2040    adv_cb.param.channel_map = chnl_map;
2041    adv_cb.param.adv_filter_policy = 0;
2042    adv_cb.param.tx_power = tx_power;
2043    adv_cb.timeout_s = timeout_s;
2044    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_UPDATE,
2045                         (char*) &adv_cb, sizeof(btgatt_multi_adv_inst_cb), NULL);
2046}
2047
2048static bt_status_t btif_gattc_multi_adv_setdata(int client_if, bool set_scan_rsp,
2049                bool include_name, bool incl_txpower, int appearance,
2050                int manufacturer_len, char* manufacturer_data,
2051                int service_data_len, char* service_data,
2052                int service_uuid_len, char* service_uuid)
2053{
2054    CHECK_BTGATT_INIT();
2055
2056    btif_adv_data_t multi_adv_data_inst;
2057    memset(&multi_adv_data_inst, 0, sizeof(multi_adv_data_inst));
2058
2059    const int min_interval = 0;
2060    const int max_interval = 0;
2061
2062    btif_gattc_adv_data_packager(client_if, set_scan_rsp, include_name, incl_txpower,
2063        min_interval, max_interval, appearance, manufacturer_len, manufacturer_data,
2064        service_data_len, service_data, service_uuid_len, service_uuid, &multi_adv_data_inst);
2065
2066    bt_status_t status = btif_transfer_context(
2067        btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_SET_DATA,
2068        (char *)&multi_adv_data_inst, sizeof(multi_adv_data_inst),
2069        btif_gattc_deep_copy);
2070    btif_gattc_adv_data_cleanup(&multi_adv_data_inst);
2071    return status;
2072}
2073
2074static bt_status_t btif_gattc_multi_adv_disable(int client_if)
2075{
2076    CHECK_BTGATT_INIT();
2077    btgatt_multi_adv_inst_cb adv_cb;
2078    memset(&adv_cb, 0, sizeof(btgatt_multi_adv_inst_cb));
2079    adv_cb.client_if = (uint8_t) client_if;
2080
2081    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_DISABLE,
2082                           (char*) &adv_cb, sizeof(btgatt_multi_adv_inst_cb), NULL);
2083}
2084
2085static bt_status_t btif_gattc_cfg_storage(int client_if,int batch_scan_full_max,
2086    int batch_scan_trunc_max, int batch_scan_notify_threshold)
2087{
2088    CHECK_BTGATT_INIT();
2089    btgatt_batch_track_cb_t bt_scan_cb;
2090    memset(&bt_scan_cb, 0, sizeof(btgatt_batch_track_cb_t));
2091    bt_scan_cb.client_if = (uint8_t) client_if;
2092    bt_scan_cb.batch_scan_full_max = batch_scan_full_max;
2093    bt_scan_cb.batch_scan_trunc_max = batch_scan_trunc_max;
2094    bt_scan_cb.batch_scan_notify_threshold = batch_scan_notify_threshold;
2095    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_CONFIG_STORAGE_PARAMS,
2096                                 (char*) &bt_scan_cb, sizeof(btgatt_batch_track_cb_t), NULL);
2097}
2098
2099static bt_status_t btif_gattc_enb_batch_scan(int client_if,int scan_mode, int scan_interval,
2100                int scan_window, int addr_type, int discard_rule)
2101{
2102    CHECK_BTGATT_INIT();
2103    btgatt_batch_track_cb_t bt_scan_cb;
2104    memset(&bt_scan_cb, 0, sizeof(btgatt_batch_track_cb_t));
2105    bt_scan_cb.client_if = (uint8_t) client_if;
2106    bt_scan_cb.scan_mode = scan_mode;
2107    bt_scan_cb.scan_interval = scan_interval;
2108    bt_scan_cb.scan_window = scan_window;
2109    bt_scan_cb.discard_rule = discard_rule;
2110    bt_scan_cb.addr_type = addr_type;
2111    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ENABLE_BATCH_SCAN,
2112                                 (char*) &bt_scan_cb, sizeof(btgatt_batch_track_cb_t), NULL);
2113}
2114
2115static bt_status_t btif_gattc_dis_batch_scan(int client_if)
2116{
2117    CHECK_BTGATT_INIT();
2118    btgatt_batch_track_cb_t bt_scan_cb;
2119    memset(&bt_scan_cb, 0, sizeof(btgatt_batch_track_cb_t));
2120    bt_scan_cb.client_if = (uint8_t) client_if;
2121    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_DISABLE_BATCH_SCAN,
2122                                 (char*) &bt_scan_cb, sizeof(btgatt_batch_track_cb_t), NULL);
2123}
2124
2125static bt_status_t btif_gattc_read_batch_scan_reports(int client_if, int scan_mode)
2126{
2127    CHECK_BTGATT_INIT();
2128    btgatt_batch_track_cb_t bt_scan_cb;
2129    memset(&bt_scan_cb, 0, sizeof(btgatt_batch_track_cb_t));
2130    bt_scan_cb.client_if = (uint8_t) client_if;
2131    bt_scan_cb.scan_mode = scan_mode;
2132    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_READ_BATCH_SCAN_REPORTS,
2133                                 (char*) &bt_scan_cb, sizeof(btgatt_batch_track_cb_t), NULL);
2134}
2135
2136extern bt_status_t btif_gattc_test_command_impl(int command, btgatt_test_params_t* params);
2137
2138static bt_status_t btif_gattc_test_command(int command, btgatt_test_params_t* params)
2139{
2140    return btif_gattc_test_command_impl(command, params);
2141}
2142
2143const btgatt_client_interface_t btgattClientInterface = {
2144    btif_gattc_register_app,
2145    btif_gattc_unregister_app,
2146    btif_gattc_scan,
2147    btif_gattc_open,
2148    btif_gattc_close,
2149    btif_gattc_listen,
2150    btif_gattc_refresh,
2151    btif_gattc_search_service,
2152    btif_gattc_read_char,
2153    btif_gattc_write_char,
2154    btif_gattc_read_char_descr,
2155    btif_gattc_write_char_descr,
2156    btif_gattc_execute_write,
2157    btif_gattc_reg_for_notification,
2158    btif_gattc_dereg_for_notification,
2159    btif_gattc_read_remote_rssi,
2160    btif_gattc_scan_filter_param_setup,
2161    btif_gattc_scan_filter_add_remove,
2162    btif_gattc_scan_filter_clear,
2163    btif_gattc_scan_filter_enable,
2164    btif_gattc_get_device_type,
2165    btif_gattc_set_adv_data,
2166    btif_gattc_configure_mtu,
2167    btif_gattc_conn_parameter_update,
2168    btif_gattc_set_scan_parameters,
2169    btif_gattc_multi_adv_enable,
2170    btif_gattc_multi_adv_update,
2171    btif_gattc_multi_adv_setdata,
2172    btif_gattc_multi_adv_disable,
2173    btif_gattc_cfg_storage,
2174    btif_gattc_enb_batch_scan,
2175    btif_gattc_dis_batch_scan,
2176    btif_gattc_read_batch_scan_reports,
2177    btif_gattc_test_command,
2178    btif_gattc_get_gatt_db
2179};
2180
2181#endif
2182