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