• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2014 Google, Inc.
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 #include "support/adapter.h"
20 
21 #include "base.h"
22 #include "btcore/include/property.h"
23 #include "support/callbacks.h"
24 #include "types/bluetooth/uuid.h"
25 #include "types/raw_address.h"
26 
27 static bt_state_t state;
28 static int property_count = 0;
29 static bt_property_t* properties = NULL;
30 static bt_discovery_state_t discovery_state;
31 static bt_acl_state_t acl_state;
32 static bt_bond_state_t bond_state;
33 
34 static void parse_properties(int num_properties, bt_property_t* property);
35 
36 // Returns the current adapter state.
adapter_get_state()37 bt_state_t adapter_get_state() { return state; }
38 
39 // Returns the number of adapter properties.
adapter_get_property_count()40 int adapter_get_property_count() { return property_count; }
41 
42 // Returns the specified property.
adapter_get_property(bt_property_type_t type)43 bt_property_t* adapter_get_property(bt_property_type_t type) {
44   for (int i = 0; i < property_count; ++i) {
45     if (properties[i].type == type) {
46       return &properties[i];
47     }
48   }
49 
50   return NULL;
51 }
52 
53 // Returns the device discovery state.
adapter_get_discovery_state()54 bt_discovery_state_t adapter_get_discovery_state() { return discovery_state; }
55 
56 // Returns the device acl state.
adapter_get_acl_state()57 bt_acl_state_t adapter_get_acl_state() { return acl_state; }
58 
59 // Returns the device bond state.
adapter_get_bond_state()60 bt_bond_state_t adapter_get_bond_state() { return bond_state; }
61 
62 // callback
acl_state_changed(bt_status_t status,RawAddress * remote_bd_addr,bt_acl_state_t state)63 void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
64                        bt_acl_state_t state) {
65   acl_state = state;
66   CALLBACK_RET();
67 }
68 
69 // callback
adapter_properties(bt_status_t status,int num_properties,bt_property_t * new_properties)70 void adapter_properties(bt_status_t status, int num_properties,
71                         bt_property_t* new_properties) {
72   property_free_array(properties, property_count);
73   properties = property_copy_array(new_properties, num_properties);
74   property_count = num_properties;
75 
76   CALLBACK_RET();
77 }
78 
79 // callback
adapter_state_changed(bt_state_t new_state)80 void adapter_state_changed(bt_state_t new_state) {
81   state = new_state;
82   CALLBACK_RET();
83 }
84 
85 // callback
bond_state_changed(bt_status_t status,RawAddress * bdaddr,bt_bond_state_t state)86 void bond_state_changed(bt_status_t status, RawAddress* bdaddr,
87                         bt_bond_state_t state) {
88   char buf[18];
89   bond_state = state;
90 
91   const char* state_name = "Bond state unknown";
92   switch (bond_state) {
93     case BT_BOND_STATE_NONE:
94       state_name = "Bond state none";
95       break;
96 
97     case BT_BOND_STATE_BONDING:
98       state_name = "Bond state bonding";
99       break;
100 
101     case BT_BOND_STATE_BONDED:
102       state_name = "Bond state bonded";
103       break;
104 
105       // default none
106   }
107   fprintf(stdout, "Bond state changed callback addr:%s state:%s\n",
108           bdaddr_to_string(bdaddr, buf, sizeof(buf)), state_name);
109 
110   CALLBACK_RET();
111 }
112 
113 // callback
device_found(int num_properties,bt_property_t * property)114 void device_found(int num_properties, bt_property_t* property) {
115   fprintf(stdout, "Device found num_properties:%d\n", num_properties);
116   parse_properties(num_properties, property);
117 
118   CALLBACK_RET();
119 }
120 
121 // callback
discovery_state_changed(bt_discovery_state_t state)122 void discovery_state_changed(bt_discovery_state_t state) {
123   const char* state_name = "Unknown";
124   discovery_state = state;
125 
126   switch (discovery_state) {
127     case BT_DISCOVERY_STOPPED:
128       state_name = "Discovery stopped";
129       break;
130 
131     case BT_DISCOVERY_STARTED:
132       state_name = "Discovery started";
133       break;
134 
135       // default omitted
136   }
137   fprintf(stdout, "Discover state %s\n", state_name);
138 
139   CALLBACK_RET();
140 }
141 
142 // callback
remote_device_properties(bt_status_t status,RawAddress * bdaddr,int num_properties,bt_property_t * properties)143 void remote_device_properties(bt_status_t status, RawAddress* bdaddr,
144                               int num_properties, bt_property_t* properties) {
145   char buf[18];
146   fprintf(stdout, "Device found bdaddr:%s num_properties:%d\n",
147           bdaddr_to_string(bdaddr, buf, sizeof(buf)), num_properties);
148 
149   parse_properties(num_properties, properties);
150 
151   CALLBACK_RET();
152 }
153 
154 // callback
ssp_request(RawAddress * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bt_ssp_variant_t pairing_variant,uint32_t pass_key)155 void ssp_request(RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
156                  bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
157   char* pairing_variant_name = "Unknown";
158 
159   switch (pairing_variant) {
160     case BT_SSP_VARIANT_PASSKEY_CONFIRMATION:
161       pairing_variant_name = "Passkey confirmation";
162       break;
163     case BT_SSP_VARIANT_PASSKEY_ENTRY:
164       pairing_variant_name = "Passkey entry";
165       break;
166 
167     case BT_SSP_VARIANT_CONSENT:
168       pairing_variant_name = "Passkey consent";
169       break;
170 
171     case BT_SSP_VARIANT_PASSKEY_NOTIFICATION:
172       pairing_variant_name = "Passkey notification";
173       break;
174   }
175 
176   fprintf(stdout,
177           "Got ssp request device_class:%u passkey:%x pairing_variant:%s\n",
178           cod, pass_key, pairing_variant_name);
179   char buf[18];
180   fprintf(stdout, "Device found:%s %s\n",
181           bdaddr_to_string(remote_bd_addr, buf, sizeof(buf)), bd_name->name);
182 
183   fprintf(stdout, "auto-accepting bond\n");
184   bool accept = true;
185   int rc = bt_interface->ssp_reply(remote_bd_addr, pairing_variant,
186                                    (uint8_t)accept, pass_key);
187   CALLBACK_RET();
188 }
189 
190 // callback
thread_evt(bt_cb_thread_evt evt)191 void thread_evt(bt_cb_thread_evt evt) { CALLBACK_RET(); }
192 
parse_properties(int num_properties,bt_property_t * property)193 static void parse_properties(int num_properties, bt_property_t* property) {
194   while (num_properties-- > 0) {
195     switch (property->type) {
196       case BT_PROPERTY_BDNAME: {
197         const bt_bdname_t* name = property_as_name(property);
198         if (name) fprintf(stdout, " name:%s\n", name->name);
199       } break;
200 
201       case BT_PROPERTY_BDADDR: {
202         char buf[18];
203         const RawAddress* addr = property_as_addr(property);
204         if (addr)
205           fprintf(stdout, " addr:%s\n",
206                   bdaddr_to_string(addr, buf, sizeof(buf)));
207       } break;
208 
209       case BT_PROPERTY_UUIDS: {
210         size_t num_uuid;
211         const Uuid* uuid = property_as_uuids(property, &num_uuid);
212         if (uuid) {
213           for (size_t i = 0; i < num_uuid; i++) {
214             fprintf(stdout, " uuid:%zd: ", i);
215             for (size_t j = 0; j < sizeof(uuid); j++) {
216               fprintf(stdout, "%02x", uuid->uu[j]);
217             }
218             fprintf(stdout, "\n");
219           }
220         }
221       } break;
222 
223       case BT_PROPERTY_TYPE_OF_DEVICE: {
224         bt_device_type_t device_type = property_as_device_type(property);
225         if (device_type) {
226           const struct {
227             const char* device_type;
228           } device_type_lookup[] = {
229               {"Unknown"},
230               {"Classic Only"},
231               {"BLE Only"},
232               {"Both Classic and BLE"},
233           };
234           int idx = (int)device_type;
235           if (idx > BT_DEVICE_DEVTYPE_DUAL) idx = 0;
236           fprintf(stdout, " device_type:%s\n",
237                   device_type_lookup[idx].device_type);
238         }
239       } break;
240 
241       case BT_PROPERTY_CLASS_OF_DEVICE: {
242         const bt_device_class_t* dc = property_as_device_class(property);
243         int dc_int = device_class_to_int(dc);
244         fprintf(stdout, " device_class:0x%x\n", dc_int);
245       } break;
246 
247       case BT_PROPERTY_REMOTE_RSSI: {
248         int8_t rssi = property_as_rssi(property);
249         fprintf(stdout, " rssi:%d\n", rssi);
250       } break;
251 
252       case BT_PROPERTY_REMOTE_FRIENDLY_NAME: {
253         const bt_bdname_t* name = property_as_name(property);
254         if (name) fprintf(stdout, " remote_name:%s\n", name->name);
255       } break;
256 
257       case BT_PROPERTY_SERVICE_RECORD:
258       case BT_PROPERTY_ADAPTER_SCAN_MODE:
259       case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
260       case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT:
261       case BT_PROPERTY_REMOTE_VERSION_INFO:
262       case BT_PROPERTY_LOCAL_LE_FEATURES:
263       case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
264       default: {
265         fprintf(stderr, "Unhandled property type:%d len:%d\n", property->type,
266                 property->len);
267         uint8_t* p = (uint8_t*)property->val;
268         for (int i = 0; i < property->len; ++i, p++) {
269           fprintf(stderr, " %02x", *p);
270         }
271         if (property->len != 0) fprintf(stderr, "\n");
272       }
273     }
274     property++;
275   }
276 }
277