Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / android / hal-utils.c
1 /*
2  * Copyright (C) 2013 Intel Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdint.h>
21 #include <stdbool.h>
22
23 #include <cutils/properties.h>
24
25 #include "hal.h"
26 #include "hal-utils.h"
27
28 /*
29  * converts uuid to string
30  * buf should be at least 39 bytes
31  *
32  * returns string representation of uuid
33  */
34 const char *bt_uuid_t2str(const uint8_t *uuid, char *buf)
35 {
36         int shift = 0;
37         unsigned int i;
38         int is_bt;
39
40         if (!uuid)
41                 return strcpy(buf, "NULL");
42
43         is_bt = !memcmp(&uuid[4], &BT_BASE_UUID[4], HAL_UUID_LEN - 4);
44
45         for (i = 0; i < HAL_UUID_LEN; i++) {
46                 if (i == 4 && is_bt)
47                         break;
48
49                 if (i == 4 || i == 6 || i == 8 || i == 10) {
50                         buf[i * 2 + shift] = '-';
51                         shift++;
52                 }
53                 sprintf(buf + i * 2 + shift, "%02x", uuid[i]);
54         }
55
56         return buf;
57 }
58
59 const char *btuuid2str(const uint8_t *uuid)
60 {
61         static char buf[MAX_UUID_STR_LEN];
62
63         return bt_uuid_t2str(uuid, buf);
64 }
65
66 INTMAP(bt_status_t, -1, "(unknown)")
67         DELEMENT(BT_STATUS_SUCCESS),
68         DELEMENT(BT_STATUS_FAIL),
69         DELEMENT(BT_STATUS_NOT_READY),
70         DELEMENT(BT_STATUS_NOMEM),
71         DELEMENT(BT_STATUS_BUSY),
72         DELEMENT(BT_STATUS_DONE),
73         DELEMENT(BT_STATUS_UNSUPPORTED),
74         DELEMENT(BT_STATUS_PARM_INVALID),
75         DELEMENT(BT_STATUS_UNHANDLED),
76         DELEMENT(BT_STATUS_AUTH_FAILURE),
77         DELEMENT(BT_STATUS_RMT_DEV_DOWN),
78 ENDMAP
79
80 INTMAP(bt_state_t, -1, "(unknown)")
81         DELEMENT(BT_STATE_OFF),
82         DELEMENT(BT_STATE_ON),
83 ENDMAP
84
85 INTMAP(bt_device_type_t, -1, "(unknown)")
86         DELEMENT(BT_DEVICE_DEVTYPE_BREDR),
87         DELEMENT(BT_DEVICE_DEVTYPE_BLE),
88         DELEMENT(BT_DEVICE_DEVTYPE_DUAL),
89 ENDMAP
90
91 INTMAP(bt_scan_mode_t, -1, "(unknown)")
92         DELEMENT(BT_SCAN_MODE_NONE),
93         DELEMENT(BT_SCAN_MODE_CONNECTABLE),
94         DELEMENT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE),
95 ENDMAP
96
97 INTMAP(bt_discovery_state_t, -1, "(unknown)")
98         DELEMENT(BT_DISCOVERY_STOPPED),
99         DELEMENT(BT_DISCOVERY_STARTED),
100 ENDMAP
101
102 INTMAP(bt_acl_state_t, -1, "(unknown)")
103         DELEMENT(BT_ACL_STATE_CONNECTED),
104         DELEMENT(BT_ACL_STATE_DISCONNECTED),
105 ENDMAP
106
107 INTMAP(bt_bond_state_t, -1, "(unknown)")
108         DELEMENT(BT_BOND_STATE_NONE),
109         DELEMENT(BT_BOND_STATE_BONDING),
110         DELEMENT(BT_BOND_STATE_BONDED),
111 ENDMAP
112
113 INTMAP(bt_ssp_variant_t, -1, "(unknown)")
114         DELEMENT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION),
115         DELEMENT(BT_SSP_VARIANT_PASSKEY_ENTRY),
116         DELEMENT(BT_SSP_VARIANT_CONSENT),
117         DELEMENT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION),
118 ENDMAP
119
120 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
121 INTMAP(bt_property_type_t, -1, "(unknown)")
122         DELEMENT(BT_PROPERTY_BDNAME),
123         DELEMENT(BT_PROPERTY_BDADDR),
124         DELEMENT(BT_PROPERTY_UUIDS),
125         DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE),
126         DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE),
127         DELEMENT(BT_PROPERTY_SERVICE_RECORD),
128         DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE),
129         DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES),
130         DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
131         DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
132         DELEMENT(BT_PROPERTY_REMOTE_RSSI),
133         DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
134         DELEMENT(BT_PROPERTY_LOCAL_LE_FEATURES),
135         DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
136 ENDMAP
137 #else
138 INTMAP(bt_property_type_t, -1, "(unknown)")
139         DELEMENT(BT_PROPERTY_BDNAME),
140         DELEMENT(BT_PROPERTY_BDADDR),
141         DELEMENT(BT_PROPERTY_UUIDS),
142         DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE),
143         DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE),
144         DELEMENT(BT_PROPERTY_SERVICE_RECORD),
145         DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE),
146         DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES),
147         DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT),
148         DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME),
149         DELEMENT(BT_PROPERTY_REMOTE_RSSI),
150         DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO),
151         DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP),
152 ENDMAP
153 #endif
154
155 INTMAP(bt_cb_thread_evt, -1, "(unknown)")
156         DELEMENT(ASSOCIATE_JVM),
157         DELEMENT(DISASSOCIATE_JVM),
158 ENDMAP
159
160 /* Find first index of given value in table m */
161 int int2str_findint(int v, const struct int2str m[])
162 {
163         int i;
164
165         for (i = 0; m[i].str; ++i) {
166                 if (m[i].val == v)
167                         return i;
168         }
169         return -1;
170 }
171
172 /* Find first index of given string in table m */
173 int int2str_findstr(const char *str, const struct int2str m[])
174 {
175         int i;
176
177         for (i = 0; m[i].str; ++i) {
178                 if (strcmp(m[i].str, str) == 0)
179                         return i;
180         }
181         return -1;
182 }
183
184 /*
185  * convert bd_addr to string
186  * buf must be at least 18 char long
187  *
188  * returns buf
189  */
190 const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
191 {
192         const uint8_t *p;
193
194         if (!bd_addr)
195                 return strcpy(buf, "NULL");
196
197         p = bd_addr->address;
198
199         snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
200                                         p[0], p[1], p[2], p[3], p[4], p[5]);
201
202         return buf;
203 }
204
205 /* converts string to bt_bdaddr_t */
206 void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr)
207 {
208         uint8_t *p = bd_addr->address;
209
210         sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
211                                 &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]);
212 }
213
214 /* converts string to uuid */
215 void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
216 {
217         int i = 0;
218
219         memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t));
220
221         while (*str && i < (int) sizeof(bt_uuid_t)) {
222                 while (*str == '-')
223                         str++;
224
225                 if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1)
226                         break;
227
228                 i++;
229                 str += 2;
230         }
231 }
232
233 const char *enum_defines(void *v, int i)
234 {
235         const struct int2str *m = v;
236
237         return m[i].str != NULL ? m[i].str : NULL;
238 }
239
240 const char *enum_strings(void *v, int i)
241 {
242         const char **m = v;
243
244         return m[i] != NULL ? m[i] : NULL;
245 }
246
247 const char *enum_one_string(void *v, int i)
248 {
249         const char *m = v;
250
251         return (i == 0) && (m[0] != 0) ? m : NULL;
252 }
253
254 const char *bdaddr2str(const bt_bdaddr_t *bd_addr)
255 {
256         static char buf[MAX_ADDR_STR_LEN];
257
258         return bt_bdaddr_t2str(bd_addr, buf);
259 }
260
261 static void bonded_devices2string(char *str, void *prop, int prop_len)
262 {
263         int count = prop_len / sizeof(bt_bdaddr_t);
264         bt_bdaddr_t *addr = prop;
265
266         strcat(str, "{");
267
268         while (count--) {
269                 strcat(str, bdaddr2str(addr));
270                 if (count)
271                         strcat(str, ", ");
272                 addr++;
273         }
274
275         strcat(str, "}");
276 }
277
278 static void uuids2string(char *str, void *prop, int prop_len)
279 {
280         int count = prop_len / sizeof(bt_uuid_t);
281         bt_uuid_t *uuid = prop;
282
283         strcat(str, "{");
284
285         while (count--) {
286                 strcat(str, btuuid2str(uuid->uu));
287                 if (count)
288                         strcat(str, ", ");
289                 uuid++;
290         }
291
292         strcat(str, "}");
293 }
294
295 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
296 static void local_le_feat2string(char *str, const bt_local_le_features_t *f)
297 {
298         uint16_t scan_num;
299
300         str += sprintf(str, "{\n");
301
302         str += sprintf(str, "Privacy supported: %s,\n",
303                                 f->local_privacy_enabled ? "TRUE" : "FALSE");
304
305         str += sprintf(str, "Num of advertising instances: %u,\n",
306                                                         f->max_adv_instance);
307
308         str += sprintf(str, "PRA offloading support: %s,\n",
309                                 f->rpa_offload_supported ? "TRUE" : "FALSE");
310
311         str += sprintf(str, "Num of offloaded IRKs: %u,\n",
312                                                         f->max_irk_list_size);
313
314         str += sprintf(str, "Num of offloaded scan filters: %u,\n",
315                                                 f->max_adv_filter_supported);
316
317         scan_num = (f->scan_result_storage_size_hibyte << 8) +
318                                         f->scan_result_storage_size_lobyte;
319
320         str += sprintf(str, "Num of offloaded scan results: %u,\n", scan_num);
321
322         str += sprintf(str, "Activity & energy report support: %s\n",
323                         f->activity_energy_info_supported ? "TRUE" : "FALSE");
324
325         sprintf(str, "}");
326 }
327 #endif
328
329 const char *btproperty2str(const bt_property_t *property)
330 {
331         bt_service_record_t *rec;
332         static char buf[4096];
333         char *p;
334
335         p = buf + sprintf(buf, "type=%s len=%d val=",
336                                         bt_property_type_t2str(property->type),
337                                         property->len);
338
339         switch (property->type) {
340         case BT_PROPERTY_BDNAME:
341         case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
342                 snprintf(p, property->len + 1, "%s",
343                                         ((bt_bdname_t *) property->val)->name);
344                 break;
345         case BT_PROPERTY_BDADDR:
346                 sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val));
347                 break;
348         case BT_PROPERTY_CLASS_OF_DEVICE:
349                 sprintf(p, "%06x", *((int *) property->val));
350                 break;
351         case BT_PROPERTY_TYPE_OF_DEVICE:
352                 sprintf(p, "%s", bt_device_type_t2str(
353                                         *((bt_device_type_t *) property->val)));
354                 break;
355         case BT_PROPERTY_REMOTE_RSSI:
356                 sprintf(p, "%d", *((char *) property->val));
357                 break;
358         case BT_PROPERTY_ADAPTER_SCAN_MODE:
359                 sprintf(p, "%s",
360                         bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val)));
361                 break;
362         case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
363                 sprintf(p, "%d", *((int *) property->val));
364                 break;
365         case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
366                 bonded_devices2string(p, property->val, property->len);
367                 break;
368         case BT_PROPERTY_UUIDS:
369                 uuids2string(p, property->val, property->len);
370                 break;
371         case BT_PROPERTY_SERVICE_RECORD:
372                 rec = property->val;
373                 sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu),
374                                                 rec->channel, rec->name);
375                 break;
376 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
377         case BT_PROPERTY_LOCAL_LE_FEATURES:
378                 local_le_feat2string(p, property->val);
379                 break;
380 #endif
381         case BT_PROPERTY_REMOTE_VERSION_INFO:
382         case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
383         default:
384                 sprintf(p, "%p", property->val);
385                 break;
386         }
387
388         return buf;
389 }
390
391 #define PROP_PREFIX "persist.sys.bluetooth."
392 #define PROP_PREFIX_RO "ro.bluetooth."
393
394 int get_config(const char *config_key, char *value, const char *fallback)
395 {
396         char key[PROPERTY_KEY_MAX];
397         int ret;
398
399         if (strlen(config_key) + sizeof(PROP_PREFIX) > sizeof(key))
400                 return 0;
401
402         snprintf(key, sizeof(key), PROP_PREFIX"%s", config_key);
403
404         ret = property_get(key, value, "");
405         if (ret > 0)
406                 return ret;
407
408         snprintf(key, sizeof(key), PROP_PREFIX_RO"%s", config_key);
409
410         ret = property_get(key, value, "");
411         if (ret > 0)
412                 return ret;
413
414         if (!fallback)
415                 return 0;
416
417         return property_get(fallback, value, "");
418 }