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