1 /******************************************************************************
2  *
3  *  Copyright 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 #include "bta_gatt_api.h"
33 #include "bte_appl.h"
34 #include "btif_dm.h"
35 #include "btif_gatt.h"
36 #include "btif_gatt_util.h"
37 #include "btif_storage.h"
38 #include "gatt_api.h"
39 #include "osi/include/log.h"
40 #include "osi/include/osi.h"
41 
42 using bluetooth::Uuid;
43 /*******************************************************************************
44  * Typedefs & Macros
45  ******************************************************************************/
46 
47 typedef struct {
48   tGATT_IF gatt_if;
49   uint16_t conn_id;
50 } btif_test_cb_t;
51 
52 /*******************************************************************************
53  * Static variables
54  ******************************************************************************/
55 
56 static 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 
63 static btif_test_cb_t test_cb;
64 
65 /*******************************************************************************
66  * Callback functions
67  ******************************************************************************/
68 
btif_test_connect_cback(tGATT_IF,const RawAddress &,uint16_t conn_id,bool connected,tGATT_DISCONN_REASON,tBT_TRANSPORT)69 static void btif_test_connect_cback(tGATT_IF, const RawAddress&,
70                                     uint16_t conn_id, bool connected,
71                                     tGATT_DISCONN_REASON, tBT_TRANSPORT) {
72   LOG_DEBUG("%s: conn_id=%d, connected=%d", __func__, conn_id, connected);
73   test_cb.conn_id = connected ? conn_id : 0;
74 }
75 
btif_test_command_complete_cback(uint16_t conn_id,tGATTC_OPTYPE op,tGATT_STATUS status,tGATT_CL_COMPLETE * p_data)76 static void btif_test_command_complete_cback(uint16_t conn_id, tGATTC_OPTYPE op,
77                                              tGATT_STATUS status,
78                                              tGATT_CL_COMPLETE* p_data) {
79   LOG_DEBUG("%s: op_code=0x%02x, conn_id=0x%x. status=0x%x", __func__, op,
80             conn_id, status);
81 
82   switch (op) {
83     case GATTC_OPTYPE_READ:
84     case GATTC_OPTYPE_WRITE:
85     case GATTC_OPTYPE_CONFIG:
86     case GATTC_OPTYPE_EXE_WRITE:
87     case GATTC_OPTYPE_NOTIFICATION:
88       break;
89 
90     case GATTC_OPTYPE_INDICATION:
91       GATTC_SendHandleValueConfirm(conn_id, p_data->handle);
92       break;
93 
94     default:
95       LOG_DEBUG("%s: Unknown op_code (0x%02x)", __func__, op);
96       break;
97   }
98 }
99 
btif_test_discovery_result_cback(UNUSED_ATTR uint16_t conn_id,tGATT_DISC_TYPE disc_type,tGATT_DISC_RES * p_data)100 static void btif_test_discovery_result_cback(UNUSED_ATTR uint16_t conn_id,
101                                              tGATT_DISC_TYPE disc_type,
102                                              tGATT_DISC_RES* p_data) {
103   LOG_DEBUG("------ GATT Discovery result %-22s -------", disc_name[disc_type]);
104   LOG_DEBUG("      Attribute handle: 0x%04x (%d)", p_data->handle,
105             p_data->handle);
106 
107   if (disc_type != GATT_DISC_CHAR_DSCPT) {
108     LOG_DEBUG("        Attribute type: %s", p_data->type.ToString().c_str());
109   }
110 
111   switch (disc_type) {
112     case GATT_DISC_SRVC_ALL:
113       LOG_DEBUG("          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
114                 p_data->handle, p_data->value.group_value.e_handle,
115                 p_data->handle, p_data->value.group_value.e_handle);
116       LOG_DEBUG("          Service UUID: %s",
117                 p_data->value.group_value.service_type.ToString().c_str());
118       break;
119 
120     case GATT_DISC_SRVC_BY_UUID:
121       LOG_DEBUG("          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
122                 p_data->handle, p_data->value.handle, p_data->handle,
123                 p_data->value.handle);
124       break;
125 
126     case GATT_DISC_INC_SRVC:
127       LOG_DEBUG("          Handle range: 0x%04x ~ 0x%04x (%d ~ %d)",
128                 p_data->value.incl_service.s_handle,
129                 p_data->value.incl_service.e_handle,
130                 p_data->value.incl_service.s_handle,
131                 p_data->value.incl_service.e_handle);
132       LOG_DEBUG("          Service UUID: %s",
133                 p_data->value.incl_service.service_type.ToString().c_str());
134       break;
135 
136     case GATT_DISC_CHAR:
137       LOG_DEBUG("            Properties: 0x%02x",
138                 p_data->value.dclr_value.char_prop);
139       LOG_DEBUG("   Characteristic UUID: %s",
140                 p_data->value.dclr_value.char_uuid.ToString().c_str());
141       break;
142 
143     case GATT_DISC_CHAR_DSCPT:
144       LOG_DEBUG("       Descriptor UUID: %s", p_data->type.ToString().c_str());
145       break;
146   }
147 
148   LOG_DEBUG("-----------------------------------------------------------");
149 }
150 
btif_test_discovery_complete_cback(UNUSED_ATTR uint16_t conn_id,UNUSED_ATTR tGATT_DISC_TYPE disc_type,tGATT_STATUS status)151 static void btif_test_discovery_complete_cback(
152     UNUSED_ATTR uint16_t conn_id, UNUSED_ATTR tGATT_DISC_TYPE disc_type,
153     tGATT_STATUS status) {
154   LOG_DEBUG("%s: status=%d", __func__, status);
155 }
156 
157 static tGATT_CBACK btif_test_callbacks = {btif_test_connect_cback,
158                                           btif_test_command_complete_cback,
159                                           btif_test_discovery_result_cback,
160                                           btif_test_discovery_complete_cback,
161                                           NULL,
162                                           NULL,
163                                           NULL,
164                                           NULL,
165                                           NULL};
166 
167 /*******************************************************************************
168  * Implementation
169  ******************************************************************************/
170 
btif_gattc_test_command_impl(int command,const btgatt_test_params_t * params)171 bt_status_t btif_gattc_test_command_impl(int command,
172                                          const btgatt_test_params_t* params) {
173   switch (command) {
174     case 0x01: /* Enable */
175     {
176       LOG_DEBUG("%s: ENABLE - enable=%d", __func__, params->u1);
177       if (params->u1) {
178         std::array<uint8_t, Uuid::kNumBytes128> tmp;
179         tmp.fill(0xAE);
180         test_cb.gatt_if = GATT_Register(bluetooth::Uuid::From128BitBE(tmp),
181                                         &btif_test_callbacks);
182         GATT_StartIf(test_cb.gatt_if);
183       } else {
184         GATT_Deregister(test_cb.gatt_if);
185         test_cb.gatt_if = 0;
186       }
187       break;
188     }
189 
190     case 0x02: /* Connect */
191     {
192       LOG_DEBUG("%s: CONNECT - device=%s (dev_type=%d, addr_type=%d)", __func__,
193                 params->bda1->ToString().c_str(), params->u1, params->u2);
194 
195       if (params->u1 == BT_DEVICE_TYPE_BLE)
196         BTM_SecAddBleDevice(*params->bda1, NULL, BT_DEVICE_TYPE_BLE,
197                             params->u2);
198 
199       if (!GATT_Connect(test_cb.gatt_if, *params->bda1, true, BT_TRANSPORT_LE,
200                         false)) {
201         LOG_ERROR("%s: GATT_Connect failed!", __func__);
202       }
203       break;
204     }
205 
206     case 0x03: /* Disconnect */
207     {
208       LOG_DEBUG("%s: DISCONNECT - conn_id=%d", __func__, test_cb.conn_id);
209       GATT_Disconnect(test_cb.conn_id);
210       break;
211     }
212 
213     case 0x04: /* Discover */
214     {
215       if (params->u1 >= GATT_DISC_MAX) {
216         LOG_ERROR("%s: DISCOVER - Invalid type (%d)!", __func__, params->u1);
217         return (bt_status_t)0;
218       }
219 
220       LOG_DEBUG("%s: DISCOVER (%s), conn_id=%d, uuid=%s, handles=0x%04x-0x%04x",
221                 __func__, disc_name[params->u1], test_cb.conn_id,
222                 params->uuid1->ToString().c_str(), params->u2, params->u3);
223       GATTC_Discover(test_cb.conn_id, params->u1, params->u2, params->u3,
224                      *params->uuid1);
225       break;
226     }
227 
228     case 0xF0: /* Pairing configuration */
229       LOG_DEBUG("%s: Setting pairing config auth=%d, iocaps=%d, keys=%d/%d/%d",
230                 __func__, params->u1, params->u2, params->u3, params->u4,
231                 params->u5);
232 
233       bte_appl_cfg.ble_auth_req = params->u1;
234       bte_appl_cfg.ble_io_cap = params->u2;
235       bte_appl_cfg.ble_init_key = params->u3;
236       bte_appl_cfg.ble_resp_key = params->u4;
237       bte_appl_cfg.ble_max_key_size = params->u5;
238       break;
239 
240     default:
241       LOG_ERROR("%s: UNKNOWN TEST COMMAND 0x%02x", __func__, command);
242       break;
243   }
244   return (bt_status_t)0;
245 }
246