15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2008-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  this file contains the main GATT server attributes access request
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  handling functions.
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_target.h"
275cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include "bt_utils.h"
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gatt_api.h"
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "gatt_int.h"
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if BLE_INCLUDED == TRUE
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define GATTP_MAX_NUM_INC_SVR       0
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define GATTP_MAX_CHAR_NUM          2
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define GATTP_MAX_ATTR_NUM          (GATTP_MAX_CHAR_NUM * 2 + GATTP_MAX_NUM_INC_SVR + 1)
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define GATTP_MAX_CHAR_VALUE_SIZE   50
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifndef GATTP_ATTR_DB_SIZE
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define GATTP_ATTR_DB_SIZE      GATT_DB_MEM_SIZE(GATTP_MAX_NUM_INC_SVR, GATTP_MAX_CHAR_NUM, GATTP_MAX_CHAR_VALUE_SIZE)
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
43adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_request_cback(UINT16 conn_id, UINT32 trans_id, UINT8 op_code, tGATTS_DATA *p_data);
44adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_connect_cback(tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected,
45adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun              tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport);
46adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_disc_res_cback(UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES *p_data);
47adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_disc_cmpl_cback(UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status);
48adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_cl_op_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
49adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun              tGATT_CL_COMPLETE *p_data);
50adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
51adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_cl_start_config_ccc(tGATT_PROFILE_CLCB *p_clcb);
52adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tGATT_CBACK gatt_profile_cback =
555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
56adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    gatt_connect_cback,
57adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    gatt_cl_op_cmpl_cback,
58adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    gatt_disc_res_cback,
59adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    gatt_disc_cmpl_cback,
60adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    gatt_request_cback,
6117b04bd498405f2bb109a85562ebbdcb6bb06e95Andre Eisenbach    NULL,
627051db3a486aae771d9b5a81c3546790f86ede34Zhihai Xu    NULL
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} ;
645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_profile_find_conn_id_by_bd_addr
685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
69adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Description      Find the connection ID by remote address
705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
71adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Returns          Connection ID
725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
74adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing SunUINT16 gatt_profile_find_conn_id_by_bd_addr(BD_ADDR remote_bda)
75adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun{
76adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    UINT16 conn_id = GATT_INVALID_CONN_ID;
77adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    GATT_GetConnIdIfConnected (gatt_cb.gatt_if, remote_bda, &conn_id, BT_TRANSPORT_LE);
78adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    return conn_id;
79adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun}
80adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
81adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun/*******************************************************************************
82adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
83adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Function         gatt_profile_find_clcb_by_conn_id
84adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
85adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Description      find clcb by Connection ID
86adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
87adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Returns          Pointer to the found link conenction control block.
88adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
89adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun*******************************************************************************/
90adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_conn_id(UINT16 conn_id)
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 i_clcb;
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_PROFILE_CLCB    *p_clcb = NULL;
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i_clcb = 0, p_clcb= gatt_cb.profile_clcb; i_clcb < GATT_MAX_APPS; i_clcb++, p_clcb++)
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
97adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        if (p_clcb->in_use && p_clcb->conn_id == conn_id)
98adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            return p_clcb;
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
101adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    return p_clcb;
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_profile_find_clcb_by_bd_addr
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      The function searches all LCBs with macthing bd address.
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          Pointer to the found link conenction control block.
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1137fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Battastatic tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda, tBT_TRANSPORT transport)
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8 i_clcb;
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_PROFILE_CLCB    *p_clcb = NULL;
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i_clcb = 0, p_clcb= gatt_cb.profile_clcb; i_clcb < GATT_MAX_APPS; i_clcb++, p_clcb++)
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1207fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta        if (p_clcb->in_use && p_clcb->transport == transport &&
1217fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            p_clcb->connected && !memcmp(p_clcb->bda, bda, BD_ADDR_LEN))
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            return p_clcb;
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return p_clcb;
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_profile_clcb_alloc
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      The function allocates a GATT profile  connection link control block
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns           NULL if not found. Otherwise pointer to the connection link block.
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
1377fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi BattatGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TRANSPORT tranport)
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8                   i_clcb = 0;
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_PROFILE_CLCB      *p_clcb = NULL;
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (i_clcb = 0, p_clcb= gatt_cb.profile_clcb; i_clcb < GATT_MAX_APPS; i_clcb++, p_clcb++)
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        if (!p_clcb->in_use)
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_clcb->in_use      = TRUE;
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_clcb->conn_id     = conn_id;
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            p_clcb->connected   = TRUE;
1497fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta            p_clcb->transport   = tranport;
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            memcpy (p_clcb->bda, bda, BD_ADDR_LEN);
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    return p_clcb;
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
156adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_profile_clcb_dealloc
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      The function deallocates a GATT profile  connection link control block
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
163adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Returns          void
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
166adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunvoid gatt_profile_clcb_dealloc (tGATT_PROFILE_CLCB *p_clcb)
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
168adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    memset(p_clcb, 0, sizeof(tGATT_PROFILE_CLCB));
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
173adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Function         gatt_request_cback
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      GATT profile attribute access request callback.
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void.
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
180adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_request_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type,
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                                        tGATTS_DATA *p_data)
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT8       status = GATT_INVALID_PDU;
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATTS_RSP   rsp_msg ;
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    BOOLEAN     ignore = FALSE;
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset(&rsp_msg, 0, sizeof(tGATTS_RSP));
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    switch (type)
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATTS_REQ_TYPE_READ:
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = GATT_READ_NOT_PERMIT;
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATTS_REQ_TYPE_WRITE:
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            status = GATT_WRITE_NOT_PERMIT;
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATTS_REQ_TYPE_WRITE_EXEC:
200ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta        case GATT_CMD_WRITE:
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ignore = TRUE;
202b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            GATT_TRACE_EVENT("Ignore GATT_REQ_EXEC_WRITE/WRITE_CMD" );
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        case GATTS_REQ_TYPE_MTU:
206b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            GATT_TRACE_EVENT("Get MTU exchange new mtu size: %d", p_data->mtu);
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            ignore = TRUE;
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        default:
211b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati            GATT_TRACE_EVENT("Unknown/unexpected LE GAP ATT request: 0x%02x", type);
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            break;
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (!ignore)
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        GATTS_SendRsp (conn_id, trans_id, status, &rsp_msg);
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
222adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Function         gatt_connect_cback
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Gatt profile connection callback.
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns          void
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
229adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
2307fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                                        BOOLEAN connected, tGATT_DISCONN_REASON reason,
2317fa4fba6f59f97df00aff07dbe8fb21b114b3c2cGanesh Ganapathi Batta                                        tBT_TRANSPORT transport)
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2335cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    UNUSED(gatt_if);
2345cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
235adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    GATT_TRACE_EVENT ("%s: from %08x%04x connected:%d conn_id=%d reason = 0x%04x", __FUNCTION__,
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       (bda[0]<<24)+(bda[1]<<16)+(bda[2]<<8)+bda[3],
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       (bda[4]<<8)+bda[5], connected, conn_id, reason);
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
239adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    tGATT_PROFILE_CLCB *p_clcb = gatt_profile_find_clcb_by_bd_addr(bda, transport);
240adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (p_clcb == NULL)
241adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        return;
242adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (connected)
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    {
245adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb->conn_id = conn_id;
246adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb->connected = TRUE;
247adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
248adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        if (p_clcb->ccc_stage == GATT_SVC_CHANGED_CONNECTING)
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        {
250adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            p_clcb->ccc_stage ++;
251adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            gatt_cl_start_config_ccc(p_clcb);
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
253adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    } else {
254adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        gatt_profile_clcb_dealloc(p_clcb);
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function         gatt_profile_db_init
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description      Initializa the GATT profile attribute database.
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project**
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid gatt_profile_db_init (void)
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBT_UUID          app_uuid = {LEN_UUID_128, {0}};
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tBT_UUID          uuid = {LEN_UUID_16, {UUID_SERVCLASS_GATT_SERVER}};
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    UINT16            service_handle = 0;
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    tGATT_STATUS      status;
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Fill our internal UUID with a fixed pattern 0x81 */
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    memset (&app_uuid.uu.uuid128, 0x81, LEN_UUID_128);
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* Create a GATT profile service */
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    gatt_cb.gatt_if = GATT_Register(&app_uuid, &gatt_profile_cback);
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    GATT_StartIf(gatt_cb.gatt_if);
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    service_handle = GATTS_CreateService (gatt_cb.gatt_if , &uuid, 0, GATTP_MAX_ATTR_NUM, TRUE);
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* add Service Changed characteristic
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    uuid.uu.uuid16 = gatt_cb.gattp_attr.uuid = GATT_UUID_GATT_SRV_CHGD;
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    gatt_cb.gattp_attr.service_change = 0;
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    gatt_cb.gattp_attr.handle   =
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    gatt_cb.handle_of_h_r       = GATTS_AddCharacteristic(service_handle, &uuid, 0, GATT_CHAR_PROP_BIT_INDICATE);
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
288b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG ("gatt_profile_db_init:  handle of service changed%d",
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       gatt_cb.handle_of_h_r  );
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    /* start service
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    */
293ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta    status = GATTS_StartService (gatt_cb.gatt_if, service_handle, GATTP_TRANSPORT_SUPPORTED );
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
295b44cc59d286ad255e872c60df02e032bd8d9d75bSharvil Nanavati    GATT_TRACE_DEBUG ("gatt_profile_db_init:  gatt_if=%d   start status%d",
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                       gatt_cb.gatt_if,  status);
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
299adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun/*******************************************************************************
300adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
301adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Function         gatt_config_ccc_complete
302adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
303adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Description      The function finish the service change ccc configuration
304adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
305adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Returns          void
306adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
307adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun*******************************************************************************/
308adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_config_ccc_complete(tGATT_PROFILE_CLCB *p_clcb)
309adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun{
310adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    GATT_Disconnect(p_clcb->conn_id);
311adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    gatt_profile_clcb_dealloc(p_clcb);
312adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun}
313adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
314adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun/*******************************************************************************
315adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
316adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Function         gatt_disc_res_cback
317adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
318adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Description      Gatt profile discovery result callback
319adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
320adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Returns          void
321adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
322adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun*******************************************************************************/
323adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES *p_data)
324adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun{
325adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    tGATT_PROFILE_CLCB *p_clcb = gatt_profile_find_clcb_by_conn_id(conn_id);
326adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
327adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (p_clcb == NULL)
328adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        return;
329adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
330adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    switch (disc_type)
331adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    {
332adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    case GATT_DISC_SRVC_BY_UUID:/* stage 1 */
333adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb->e_handle = p_data->value.group_value.e_handle;
334adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb->ccc_result ++;
335adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        break;
336adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
337adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    case GATT_DISC_CHAR:/* stage 2 */
338adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb->s_handle = p_data->value.dclr_value.val_handle;
339adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb->ccc_result ++;
340adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        break;
341adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
342adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    case GATT_DISC_CHAR_DSCPT: /* stage 3 */
343adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        if (p_data->type.uu.uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG)
344adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        {
345adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            p_clcb->s_handle = p_data->handle;
346adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            p_clcb->ccc_result ++;
347adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        }
348adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        break;
349adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    }
350adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun}
351adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
352adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun/*******************************************************************************
353adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
354adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Function         gatt_disc_cmpl_cback
355adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
356adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Description      Gatt profile discovery complete callback
357adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
358adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Returns          void
359adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
360adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun*******************************************************************************/
361adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status)
362adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun{
363adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    tGATT_PROFILE_CLCB *p_clcb = gatt_profile_find_clcb_by_conn_id(conn_id);
364adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
365adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (p_clcb == NULL)
366adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        return;
367adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
368adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (status == GATT_SUCCESS && p_clcb->ccc_result > 0)
369adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    {
370adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb->ccc_result = 0;
371adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb->ccc_stage ++;
372adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        gatt_cl_start_config_ccc(p_clcb);
373adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    } else {
374adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        GATT_TRACE_ERROR("%s() - Register for service changed indication failure", __FUNCTION__);
375adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    }
376adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun}
377adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
378adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun/*******************************************************************************
379adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
380adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Function         gatt_cl_op_cmpl_cback
381adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
382adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Description      Gatt profile client operation complete callback
383adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
384adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Returns          void
385adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
386adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun*******************************************************************************/
387adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_cl_op_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op,
388adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun                                           tGATT_STATUS status, tGATT_CL_COMPLETE *p_data)
389adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun{
390adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    tGATT_PROFILE_CLCB *p_clcb = gatt_profile_find_clcb_by_conn_id(conn_id);
391adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
392adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (p_clcb == NULL)
393adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        return;
394adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
395adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (op == GATTC_OPTYPE_WRITE)
396adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    {
397adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        GATT_TRACE_DEBUG("%s() - ccc write status : %d", __FUNCTION__, status);
398adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    }
399adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
400adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    /* free the connection */
401adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    gatt_config_ccc_complete (p_clcb);
402adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun}
403adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
404adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun/*******************************************************************************
405adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
406adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Function         gatt_cl_start_config_ccc
407adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
408adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Description      Gatt profile start configure service change CCC
409adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
410adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Returns          void
411adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
412adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun*******************************************************************************/
413adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunstatic void gatt_cl_start_config_ccc(tGATT_PROFILE_CLCB *p_clcb)
414adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun{
415adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    tGATT_DISC_PARAM    srvc_disc_param;
416adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    tGATT_VALUE         ccc_value;
417adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
418adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    GATT_TRACE_DEBUG("%s() - stage: %d", __FUNCTION__, p_clcb->ccc_stage);
419adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
420adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    memset (&srvc_disc_param, 0 , sizeof(tGATT_DISC_PARAM));
421adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    memset (&ccc_value, 0 , sizeof(tGATT_VALUE));
422adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
423adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    switch(p_clcb->ccc_stage)
424adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    {
425adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    case GATT_SVC_CHANGED_SERVICE: /* discover GATT service */
426adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.s_handle = 1;
427adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.e_handle = 0xffff;
428adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.service.len = 2;
429adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.service.uu.uuid16 = UUID_SERVCLASS_GATT_SERVER;
430adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        if (GATTC_Discover (p_clcb->conn_id, GATT_DISC_SRVC_BY_UUID, &srvc_disc_param) != GATT_SUCCESS)
431adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        {
432adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            GATT_TRACE_ERROR("%s() - ccc service error", __FUNCTION__);
433adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            gatt_config_ccc_complete(p_clcb);
434adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        }
435adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        break;
436adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
437adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    case GATT_SVC_CHANGED_CHARACTERISTIC: /* discover service change char */
438adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.s_handle = 1;
439adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.e_handle = p_clcb->e_handle;
440adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.service.len = 2;
441adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.service.uu.uuid16 = GATT_UUID_GATT_SRV_CHGD;
442adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        if (GATTC_Discover (p_clcb->conn_id, GATT_DISC_CHAR, &srvc_disc_param) != GATT_SUCCESS)
443adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        {
444adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            GATT_TRACE_ERROR("%s() - ccc char error", __FUNCTION__);
445adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            gatt_config_ccc_complete(p_clcb);
446adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        }
447adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        break;
448adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
449adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    case GATT_SVC_CHANGED_DESCRIPTOR: /* discover service change ccc */
450adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.s_handle = p_clcb->s_handle;
451adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        srvc_disc_param.e_handle = p_clcb->e_handle;
452adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        if (GATTC_Discover (p_clcb->conn_id, GATT_DISC_CHAR_DSCPT, &srvc_disc_param) != GATT_SUCCESS)
453adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        {
454adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            GATT_TRACE_ERROR("%s() - ccc char descriptor error", __FUNCTION__);
455adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            gatt_config_ccc_complete(p_clcb);
456adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        }
457adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        break;
458adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
459adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    case GATT_SVC_CHANGED_CONFIGURE_CCCD: /* write ccc */
460adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        ccc_value.handle = p_clcb->s_handle;
461adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        ccc_value.len = 2;
462adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        ccc_value.value[0] = GATT_CLT_CONFIG_INDICATION;
463adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        if (GATTC_Write (p_clcb->conn_id, GATT_WRITE, &ccc_value) != GATT_SUCCESS)
464adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        {
465adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            GATT_TRACE_ERROR("%s() - write ccc error", __FUNCTION__);
466adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun            gatt_config_ccc_complete(p_clcb);
467adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        }
468adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        break;
469adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    }
470adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun}
471adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
472adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun/*******************************************************************************
473adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
474adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Function         GATT_ConfigServiceChangeCCC
475adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
476adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Description      Configure service change indication on remote device
477adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
478adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun** Returns          none
479adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun**
480adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun*******************************************************************************/
481adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sunvoid GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSPORT transport)
482adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun{
483adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    UINT16              conn_id = GATT_INVALID_CONN_ID;
484adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    tGATT_PROFILE_CLCB   *p_clcb = gatt_profile_find_clcb_by_bd_addr (remote_bda, transport);
485adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
486adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (p_clcb == NULL)
487adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb = gatt_profile_clcb_alloc (0, remote_bda, transport);
488adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
489adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (p_clcb == NULL)
490adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        return;
491adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
492adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (GATT_GetConnIdIfConnected (gatt_cb.gatt_if, remote_bda, &p_clcb->conn_id, transport))
493adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    {
494adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        p_clcb->connected = TRUE;
495adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    }
496adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    /* hold the link here */
497adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    GATT_Connect(gatt_cb.gatt_if, remote_bda, TRUE, transport);
498adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    p_clcb->ccc_stage = GATT_SVC_CHANGED_CONNECTING;
499adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
500adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    if (!p_clcb->connected)
501adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    {
502adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        /* wait for connection */
503adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun        return;
504adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    }
505adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
506adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    p_clcb->ccc_stage ++;
507adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun    gatt_cl_start_config_ccc(p_clcb);
508adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun}
509adc9f28ad418356cb81640059b59eee4d862e6b4Chaojing Sun
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif  /* BLE_INCLUDED */
511