Home | History | Annotate | Download | only in src
      1 /*
      2  *
      3  *  BlueZ - Bluetooth protocol stack for Linux
      4  *
      5  *  Copyright (C) 2006-2010  Nokia Corporation
      6  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel (at) holtmann.org>
      7  *
      8  *
      9  *  This program is free software; you can redistribute it and/or modify
     10  *  it under the terms of the GNU General Public License as published by
     11  *  the Free Software Foundation; either version 2 of the License, or
     12  *  (at your option) any later version.
     13  *
     14  *  This program is distributed in the hope that it will be useful,
     15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  *  GNU General Public License for more details.
     18  *
     19  *  You should have received a copy of the GNU General Public License
     20  *  along with this program; if not, write to the Free Software
     21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     22  *
     23  */
     24 
     25 #ifdef HAVE_CONFIG_H
     26 #include <config.h>
     27 #endif
     28 
     29 #include <stdio.h>
     30 #include <errno.h>
     31 #include <ctype.h>
     32 #include <fcntl.h>
     33 #include <unistd.h>
     34 #include <stdlib.h>
     35 #include <time.h>
     36 #include <sys/file.h>
     37 #include <sys/stat.h>
     38 #include <sys/param.h>
     39 #include <sys/socket.h>
     40 
     41 #include <glib.h>
     42 
     43 #include <bluetooth/bluetooth.h>
     44 #include <bluetooth/sdp.h>
     45 #include <bluetooth/sdp_lib.h>
     46 
     47 #include "textfile.h"
     48 #include "adapter.h"
     49 #include "device.h"
     50 #include "glib-helper.h"
     51 #include "storage.h"
     52 
     53 struct match {
     54 	GSList *keys;
     55 	char *pattern;
     56 };
     57 
     58 static inline int create_filename(char *buf, size_t size,
     59 				const bdaddr_t *bdaddr, const char *name)
     60 {
     61 	char addr[18];
     62 
     63 	ba2str(bdaddr, addr);
     64 
     65 	return create_name(buf, size, STORAGEDIR, addr, name);
     66 }
     67 
     68 int read_device_alias(const char *src, const char *dst, char *alias, size_t size)
     69 {
     70 	char filename[PATH_MAX + 1], *tmp;
     71 	int err;
     72 
     73 	create_name(filename, PATH_MAX, STORAGEDIR, src, "aliases");
     74 
     75 	tmp = textfile_get(filename, dst);
     76 	if (!tmp)
     77 		return -ENXIO;
     78 
     79 	err = snprintf(alias, size, "%s", tmp);
     80 
     81 	free(tmp);
     82 
     83 	return err < 0 ? -EIO : 0;
     84 }
     85 
     86 int write_device_alias(const char *src, const char *dst, const char *alias)
     87 {
     88 	char filename[PATH_MAX + 1];
     89 
     90 	create_name(filename, PATH_MAX, STORAGEDIR, src, "aliases");
     91 
     92 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
     93 
     94 	return textfile_put(filename, dst, alias);
     95 }
     96 
     97 int write_discoverable_timeout(bdaddr_t *bdaddr, int timeout)
     98 {
     99 	char filename[PATH_MAX + 1], str[32];
    100 
    101 	snprintf(str, sizeof(str), "%d", timeout);
    102 
    103 	create_filename(filename, PATH_MAX, bdaddr, "config");
    104 
    105 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    106 
    107 	return textfile_put(filename, "discovto", str);
    108 }
    109 
    110 int read_discoverable_timeout(const char *src, int *timeout)
    111 {
    112 	char filename[PATH_MAX + 1], *str;
    113 
    114 	create_name(filename, PATH_MAX, STORAGEDIR, src, "config");
    115 
    116 	str = textfile_get(filename, "discovto");
    117 	if (!str)
    118 		return -ENOENT;
    119 
    120 	if (sscanf(str, "%d", timeout) != 1) {
    121 		free(str);
    122 		return -ENOENT;
    123 	}
    124 
    125 	free(str);
    126 
    127 	return 0;
    128 }
    129 
    130 int write_pairable_timeout(bdaddr_t *bdaddr, int timeout)
    131 {
    132 	char filename[PATH_MAX + 1], str[32];
    133 
    134 	snprintf(str, sizeof(str), "%d", timeout);
    135 
    136 	create_filename(filename, PATH_MAX, bdaddr, "config");
    137 
    138 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    139 
    140 	return textfile_put(filename, "pairto", str);
    141 }
    142 
    143 int read_pairable_timeout(const char *src, int *timeout)
    144 {
    145 	char filename[PATH_MAX + 1], *str;
    146 
    147 	create_name(filename, PATH_MAX, STORAGEDIR, src, "config");
    148 
    149 	str = textfile_get(filename, "pairto");
    150 	if (!str)
    151 		return -ENOENT;
    152 
    153 	if (sscanf(str, "%d", timeout) != 1) {
    154 		free(str);
    155 		return -ENOENT;
    156 	}
    157 
    158 	free(str);
    159 
    160 	return 0;
    161 }
    162 
    163 int write_device_mode(bdaddr_t *bdaddr, const char *mode)
    164 {
    165 	char filename[PATH_MAX + 1];
    166 
    167 	create_filename(filename, PATH_MAX, bdaddr, "config");
    168 
    169 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    170 
    171 	if (strcmp(mode, "off") != 0)
    172 		textfile_put(filename, "onmode", mode);
    173 
    174 	return textfile_put(filename, "mode", mode);
    175 }
    176 
    177 int read_device_mode(const char *src, char *mode, int length)
    178 {
    179 	char filename[PATH_MAX + 1], *str;
    180 
    181 	create_name(filename, PATH_MAX, STORAGEDIR, src, "config");
    182 
    183 	str = textfile_get(filename, "mode");
    184 	if (!str)
    185 		return -ENOENT;
    186 
    187 	strncpy(mode, str, length);
    188 	mode[length - 1] = '\0';
    189 
    190 	free(str);
    191 
    192 	return 0;
    193 }
    194 
    195 int read_on_mode(const char *src, char *mode, int length)
    196 {
    197 	char filename[PATH_MAX + 1], *str;
    198 
    199 	create_name(filename, PATH_MAX, STORAGEDIR, src, "config");
    200 
    201 	str = textfile_get(filename, "onmode");
    202 	if (!str)
    203 		return -ENOENT;
    204 
    205 	strncpy(mode, str, length);
    206 	mode[length - 1] = '\0';
    207 
    208 	free(str);
    209 
    210 	return 0;
    211 }
    212 
    213 int write_local_name(bdaddr_t *bdaddr, const char *name)
    214 {
    215 	char filename[PATH_MAX + 1], str[249];
    216 	int i;
    217 
    218 	memset(str, 0, sizeof(str));
    219 	for (i = 0; i < 248 && name[i]; i++)
    220 		if ((unsigned char) name[i] < 32 || name[i] == 127)
    221 			str[i] = '.';
    222 		else
    223 			str[i] = name[i];
    224 
    225 	create_filename(filename, PATH_MAX, bdaddr, "config");
    226 
    227 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    228 
    229 	return textfile_put(filename, "name", str);
    230 }
    231 
    232 int read_local_name(bdaddr_t *bdaddr, char *name)
    233 {
    234 	char filename[PATH_MAX + 1], *str;
    235 	int len;
    236 
    237 	create_filename(filename, PATH_MAX, bdaddr, "config");
    238 
    239 	str = textfile_get(filename, "name");
    240 	if (!str)
    241 		return -ENOENT;
    242 
    243 	len = strlen(str);
    244 	if (len > 248)
    245 		str[248] = '\0';
    246 	strcpy(name, str);
    247 
    248 	free(str);
    249 
    250 	return 0;
    251 }
    252 
    253 int write_local_class(bdaddr_t *bdaddr, uint8_t *class)
    254 {
    255 	char filename[PATH_MAX + 1], str[9];
    256 
    257 	sprintf(str, "0x%2.2x%2.2x%2.2x", class[2], class[1], class[0]);
    258 
    259 	create_filename(filename, PATH_MAX, bdaddr, "config");
    260 
    261 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    262 
    263 	return textfile_put(filename, "class", str);
    264 }
    265 
    266 int read_local_class(bdaddr_t *bdaddr, uint8_t *class)
    267 {
    268 	char filename[PATH_MAX + 1], tmp[3], *str;
    269 	int i;
    270 
    271 	create_filename(filename, PATH_MAX, bdaddr, "config");
    272 
    273 	str = textfile_get(filename, "class");
    274 	if (!str)
    275 		return -ENOENT;
    276 
    277 	memset(tmp, 0, sizeof(tmp));
    278 	for (i = 0; i < 3; i++) {
    279 		memcpy(tmp, str + (i * 2) + 2, 2);
    280 		class[2 - i] = (uint8_t) strtol(tmp, NULL, 16);
    281 	}
    282 
    283 	free(str);
    284 
    285 	return 0;
    286 }
    287 
    288 int write_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class)
    289 {
    290 	char filename[PATH_MAX + 1], addr[18], str[9];
    291 
    292 	create_filename(filename, PATH_MAX, local, "classes");
    293 
    294 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    295 
    296 	ba2str(peer, addr);
    297 	sprintf(str, "0x%6.6x", class);
    298 
    299 	return textfile_put(filename, addr, str);
    300 }
    301 
    302 int read_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t *class)
    303 {
    304 	char filename[PATH_MAX + 1], addr[18], *str;
    305 
    306 	create_filename(filename, PATH_MAX, local, "classes");
    307 
    308 	ba2str(peer, addr);
    309 
    310 	str = textfile_get(filename, addr);
    311 	if (!str)
    312 		return -ENOENT;
    313 
    314 	if (sscanf(str, "%x", class) != 1) {
    315 		free(str);
    316 		return -ENOENT;
    317 	}
    318 
    319 	free(str);
    320 
    321 	return 0;
    322 }
    323 
    324 int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name)
    325 {
    326 	char filename[PATH_MAX + 1], addr[18], str[249];
    327 	int i;
    328 
    329 	memset(str, 0, sizeof(str));
    330 	for (i = 0; i < 248 && name[i]; i++)
    331 		if ((unsigned char) name[i] < 32 || name[i] == 127)
    332 			str[i] = '.';
    333 		else
    334 			str[i] = name[i];
    335 
    336 	create_filename(filename, PATH_MAX, local, "names");
    337 
    338 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    339 
    340 	ba2str(peer, addr);
    341 	return textfile_put(filename, addr, str);
    342 }
    343 
    344 int read_device_name(const char *src, const char *dst, char *name)
    345 {
    346 	char filename[PATH_MAX + 1], *str;
    347 	int len;
    348 
    349 	create_name(filename, PATH_MAX, STORAGEDIR, src, "names");
    350 
    351 	str = textfile_get(filename, dst);
    352 	if (!str)
    353 		return -ENOENT;
    354 
    355 	len = strlen(str);
    356 	if (len > 248)
    357 		str[248] = '\0';
    358 	strcpy(name, str);
    359 
    360 	free(str);
    361 
    362 	return 0;
    363 }
    364 
    365 int write_remote_eir(bdaddr_t *local, bdaddr_t *peer, uint8_t *data)
    366 {
    367 	char filename[PATH_MAX + 1], addr[18], str[481];
    368 	int i;
    369 
    370 	memset(str, 0, sizeof(str));
    371 	for (i = 0; i < HCI_MAX_EIR_LENGTH; i++)
    372 		sprintf(str + (i * 2), "%2.2X", data[i]);
    373 
    374 	create_filename(filename, PATH_MAX, local, "eir");
    375 
    376 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    377 
    378 	ba2str(peer, addr);
    379 	return textfile_put(filename, addr, str);
    380 }
    381 
    382 int read_remote_eir(bdaddr_t *local, bdaddr_t *peer, uint8_t *data)
    383 {
    384 	char filename[PATH_MAX + 1], addr[18], *str;
    385 	int i;
    386 
    387 	create_filename(filename, PATH_MAX, local, "eir");
    388 
    389 	ba2str(peer, addr);
    390 
    391 	str = textfile_get(filename, addr);
    392 	if (!str)
    393 		return -ENOENT;
    394 
    395 	if (!data) {
    396 		free(str);
    397 		return 0;
    398 	}
    399 
    400 	if (strlen(str) < 480) {
    401 		free(str);
    402 		return -EIO;
    403 	}
    404 
    405 	for (i = 0; i < HCI_MAX_EIR_LENGTH; i++)
    406 		sscanf(str + (i * 2), "%02hhX", &data[i]);
    407 
    408 	free(str);
    409 
    410 	return 0;
    411 }
    412 
    413 int write_version_info(bdaddr_t *local, bdaddr_t *peer, uint16_t manufacturer,
    414 					uint8_t lmp_ver, uint16_t lmp_subver)
    415 {
    416 	char filename[PATH_MAX + 1], addr[18], str[16];
    417 
    418 	memset(str, 0, sizeof(str));
    419 	sprintf(str, "%d %d %d", manufacturer, lmp_ver, lmp_subver);
    420 
    421 	create_filename(filename, PATH_MAX, local, "manufacturers");
    422 
    423 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    424 
    425 	ba2str(peer, addr);
    426 	return textfile_put(filename, addr, str);
    427 }
    428 
    429 int write_features_info(bdaddr_t *local, bdaddr_t *peer,
    430 				unsigned char *page1, unsigned char *page2)
    431 {
    432 	char filename[PATH_MAX + 1], addr[18];
    433 	char str[] = "0000000000000000 0000000000000000";
    434 	char *old_value;
    435 	int i;
    436 
    437 	ba2str(peer, addr);
    438 
    439 	create_filename(filename, PATH_MAX, local, "features");
    440 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    441 
    442 	old_value = textfile_get(filename, addr);
    443 
    444 	if (page1)
    445 		for (i = 0; i < 8; i++)
    446 			sprintf(str + (i * 2), "%2.2X", page1[i]);
    447 	else if (old_value && strlen(old_value) >= 16)
    448 		strncpy(str, old_value, 16);
    449 
    450 	if (page2)
    451 		for (i = 0; i < 8; i++)
    452 			sprintf(str + 17 + (i * 2), "%2.2X", page2[i]);
    453 	else if (old_value && strlen(old_value) >= 33)
    454 		strncpy(str + 17, old_value + 17, 16);
    455 
    456 	free(old_value);
    457 
    458 	return textfile_put(filename, addr, str);
    459 }
    460 
    461 static int decode_bytes(const char *str, unsigned char *bytes, size_t len)
    462 {
    463 	unsigned int i;
    464 
    465 	for (i = 0; i < len; i++) {
    466 		if (sscanf(str + (i * 2), "%02hhX", &bytes[i]) != 1)
    467 			return -EINVAL;
    468 	}
    469 
    470 	return 0;
    471 }
    472 
    473 int read_remote_features(bdaddr_t *local, bdaddr_t *peer,
    474 				unsigned char *page1, unsigned char *page2)
    475 {
    476 	char filename[PATH_MAX + 1], addr[18], *str;
    477 	size_t len;
    478 	int err;
    479 
    480 	if (page1 == NULL && page2 == NULL)
    481 		return -EINVAL;
    482 
    483 	create_filename(filename, PATH_MAX, local, "features");
    484 
    485 	ba2str(peer, addr);
    486 
    487 	str = textfile_get(filename, addr);
    488 	if (!str)
    489 		return -ENOENT;
    490 
    491 	len = strlen(str);
    492 
    493 	err = -ENOENT;
    494 
    495 	if (page1 && len >= 16)
    496 		err = decode_bytes(str, page1, 8);
    497 
    498 	if (page2 && len >= 33)
    499 		err = decode_bytes(str + 17, page2, 8);
    500 
    501 	free(str);
    502 
    503 	return err;
    504 }
    505 
    506 int write_lastseen_info(bdaddr_t *local, bdaddr_t *peer, struct tm *tm)
    507 {
    508 	char filename[PATH_MAX + 1], addr[18], str[24];
    509 
    510 	memset(str, 0, sizeof(str));
    511 	strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S %Z", tm);
    512 
    513 	create_filename(filename, PATH_MAX, local, "lastseen");
    514 
    515 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    516 
    517 	ba2str(peer, addr);
    518 	return textfile_put(filename, addr, str);
    519 }
    520 
    521 int write_lastused_info(bdaddr_t *local, bdaddr_t *peer, struct tm *tm)
    522 {
    523 	char filename[PATH_MAX + 1], addr[18], str[24];
    524 
    525 	memset(str, 0, sizeof(str));
    526 	strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S %Z", tm);
    527 
    528 	create_filename(filename, PATH_MAX, local, "lastused");
    529 
    530 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    531 
    532 	ba2str(peer, addr);
    533 	return textfile_put(filename, addr, str);
    534 }
    535 
    536 int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, uint8_t type, int length)
    537 {
    538 	char filename[PATH_MAX + 1], addr[18], str[38];
    539 	int i;
    540 
    541 	memset(str, 0, sizeof(str));
    542 	for (i = 0; i < 16; i++)
    543 		sprintf(str + (i * 2), "%2.2X", key[i]);
    544 	sprintf(str + 32, " %d %d", type, length);
    545 
    546 	create_filename(filename, PATH_MAX, local, "linkkeys");
    547 
    548 	create_file(filename, S_IRUSR | S_IWUSR);
    549 
    550 	ba2str(peer, addr);
    551 
    552 	if (length < 0) {
    553 		char *tmp = textfile_get(filename, addr);
    554 		if (tmp) {
    555 			if (strlen(tmp) > 34)
    556 				memcpy(str + 34, tmp + 34, 3);
    557 			free(tmp);
    558 		}
    559 	}
    560 
    561 	return textfile_put(filename, addr, str);
    562 }
    563 
    564 int read_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, uint8_t *type)
    565 {
    566 	char filename[PATH_MAX + 1], addr[18], tmp[3], *str;
    567 	int i;
    568 
    569 	create_filename(filename, PATH_MAX, local, "linkkeys");
    570 
    571 	ba2str(peer, addr);
    572 	str = textfile_get(filename, addr);
    573 	if (!str)
    574 		return -ENOENT;
    575 
    576 	if (!key) {
    577 		free(str);
    578 		return 0;
    579 	}
    580 
    581 	memset(tmp, 0, sizeof(tmp));
    582 	for (i = 0; i < 16; i++) {
    583 		memcpy(tmp, str + (i * 2), 2);
    584 		key[i] = (uint8_t) strtol(tmp, NULL, 16);
    585 	}
    586 
    587 	if (type) {
    588 		memcpy(tmp, str + 33, 2);
    589 		*type = (uint8_t) strtol(tmp, NULL, 10);
    590 	}
    591 
    592 	free(str);
    593 
    594 	return 0;
    595 }
    596 
    597 int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin)
    598 {
    599 	char filename[PATH_MAX + 1], addr[18], *str;
    600 	int len;
    601 
    602 	create_filename(filename, PATH_MAX, local, "pincodes");
    603 
    604 	ba2str(peer, addr);
    605 	str = textfile_get(filename, addr);
    606 	if (!str)
    607 		return -ENOENT;
    608 
    609 	strncpy(pin, str, 16);
    610 	len = strlen(pin);
    611 
    612 	free(str);
    613 
    614 	return len;
    615 }
    616 
    617 static GSList *service_string_to_list(char *services)
    618 {
    619 	GSList *l = NULL;
    620 	char *start = services;
    621 	int i, finished = 0;
    622 
    623 	for (i = 0; !finished; i++) {
    624 		if (services[i] == '\0')
    625 			finished = 1;
    626 
    627 		if (services[i] == ' ' || services[i] == '\0') {
    628 			services[i] = '\0';
    629 			l = g_slist_append(l, start);
    630 			start = services + i + 1;
    631 		}
    632 	}
    633 
    634 	return l;
    635 }
    636 
    637 static char *service_list_to_string(GSList *services)
    638 {
    639 	char str[1024];
    640 	int len = 0;
    641 
    642 	if (!services)
    643 		return g_strdup("");
    644 
    645 	memset(str, 0, sizeof(str));
    646 
    647 	while (services) {
    648 		int ret;
    649 		char *ident = services->data;
    650 
    651 		ret = snprintf(str + len, sizeof(str) - len - 1, "%s%s",
    652 				ident, services->next ? " " : "");
    653 
    654 		if (ret > 0)
    655 			len += ret;
    656 
    657 		services = services->next;
    658 	}
    659 
    660 	return g_strdup(str);
    661 }
    662 
    663 int write_trust(const char *src, const char *addr, const char *service,
    664 		gboolean trust)
    665 {
    666 	char filename[PATH_MAX + 1], *str;
    667 	GSList *services = NULL, *match;
    668 	gboolean trusted;
    669 	int ret;
    670 
    671 	create_name(filename, PATH_MAX, STORAGEDIR, src, "trusts");
    672 
    673 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    674 
    675 	str = textfile_caseget(filename, addr);
    676 	if (str)
    677 		services = service_string_to_list(str);
    678 
    679 	match = g_slist_find_custom(services, service, (GCompareFunc) strcmp);
    680 	trusted = match ? TRUE : FALSE;
    681 
    682 	/* If the old setting is the same as the requested one, we're done */
    683 	if (trusted == trust) {
    684 		g_slist_free(services);
    685 		free(str);
    686 		return 0;
    687 	}
    688 
    689 	if (trust)
    690 		services = g_slist_append(services, (void *) service);
    691 	else
    692 		services = g_slist_remove(services, match->data);
    693 
    694 	/* Remove the entry if the last trusted service was removed */
    695 	if (!trust && !services)
    696 		ret = textfile_casedel(filename, addr);
    697 	else {
    698 		char *new_str = service_list_to_string(services);
    699 		ret = textfile_caseput(filename, addr, new_str);
    700 		free(new_str);
    701 	}
    702 
    703 	g_slist_free(services);
    704 
    705 	free(str);
    706 
    707 	return ret;
    708 }
    709 
    710 gboolean read_trust(const bdaddr_t *local, const char *addr, const char *service)
    711 {
    712 	char filename[PATH_MAX + 1], *str;
    713 	GSList *services;
    714 	gboolean ret;
    715 
    716 	create_filename(filename, PATH_MAX, local, "trusts");
    717 
    718 	str = textfile_caseget(filename, addr);
    719 	if (!str)
    720 		return FALSE;
    721 
    722 	services = service_string_to_list(str);
    723 
    724 	if (g_slist_find_custom(services, service, (GCompareFunc) strcmp))
    725 		ret = TRUE;
    726 	else
    727 		ret = FALSE;
    728 
    729 	g_slist_free(services);
    730 	free(str);
    731 
    732 	return ret;
    733 }
    734 
    735 struct trust_list {
    736 	GSList *trusts;
    737 	const char *service;
    738 };
    739 
    740 static void append_trust(char *key, char *value, void *data)
    741 {
    742 	struct trust_list *list = data;
    743 
    744 	if (strstr(value, list->service))
    745 		list->trusts = g_slist_append(list->trusts, g_strdup(key));
    746 }
    747 
    748 GSList *list_trusts(bdaddr_t *local, const char *service)
    749 {
    750 	char filename[PATH_MAX + 1];
    751 	struct trust_list list;
    752 
    753 	create_filename(filename, PATH_MAX, local, "trusts");
    754 
    755 	list.trusts = NULL;
    756 	list.service = service;
    757 
    758 	if (textfile_foreach(filename, append_trust, &list) < 0)
    759 		return NULL;
    760 
    761 	return list.trusts;
    762 }
    763 
    764 int write_device_profiles(bdaddr_t *src, bdaddr_t *dst, const char *profiles)
    765 {
    766 	char filename[PATH_MAX + 1], addr[18];
    767 
    768 	if (!profiles)
    769 		return -EINVAL;
    770 
    771 	create_filename(filename, PATH_MAX, src, "profiles");
    772 
    773 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    774 
    775 	ba2str(dst, addr);
    776 	return textfile_put(filename, addr, profiles);
    777 }
    778 
    779 int delete_entry(bdaddr_t *src, const char *storage, const char *key)
    780 {
    781 	char filename[PATH_MAX + 1];
    782 
    783 	create_filename(filename, PATH_MAX, src, storage);
    784 
    785 	return textfile_del(filename, key);
    786 }
    787 
    788 int store_record(const gchar *src, const gchar *dst, sdp_record_t *rec)
    789 {
    790 	char filename[PATH_MAX + 1], key[28];
    791 	sdp_buf_t buf;
    792 	int err, size, i;
    793 	char *str;
    794 
    795 	create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");
    796 
    797 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    798 
    799 	snprintf(key, sizeof(key), "%17s#%08X", dst, rec->handle);
    800 
    801 	if (sdp_gen_record_pdu(rec, &buf) < 0)
    802 		return -1;
    803 
    804 	size = buf.data_size;
    805 
    806 	str = g_malloc0(size*2+1);
    807 
    808 	for (i = 0; i < size; i++)
    809 		sprintf(str + (i * 2), "%02X", buf.data[i]);
    810 
    811 	err = textfile_put(filename, key, str);
    812 
    813 	free(buf.data);
    814 	free(str);
    815 
    816 	return err;
    817 }
    818 
    819 sdp_record_t *record_from_string(const gchar *str)
    820 {
    821 	sdp_record_t *rec;
    822 	int size, i, len;
    823 	uint8_t *pdata;
    824 	char tmp[3];
    825 
    826 	size = strlen(str)/2;
    827 	pdata = g_malloc0(size);
    828 
    829 	tmp[2] = 0;
    830 	for (i = 0; i < size; i++) {
    831 		memcpy(tmp, str + (i * 2), 2);
    832 		pdata[i] = (uint8_t) strtol(tmp, NULL, 16);
    833 	}
    834 
    835 	rec = sdp_extract_pdu(pdata, size, &len);
    836 	free(pdata);
    837 
    838 	return rec;
    839 }
    840 
    841 
    842 sdp_record_t *fetch_record(const gchar *src, const gchar *dst,
    843 						const uint32_t handle)
    844 {
    845 	char filename[PATH_MAX + 1], key[28], *str;
    846 	sdp_record_t *rec;
    847 
    848 	create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");
    849 
    850 	snprintf(key, sizeof(key), "%17s#%08X", dst, handle);
    851 
    852 	str = textfile_get(filename, key);
    853 	if (!str)
    854 		return NULL;
    855 
    856 	rec = record_from_string(str);
    857 	free(str);
    858 
    859 	return rec;
    860 }
    861 
    862 int delete_record(const gchar *src, const gchar *dst, const uint32_t handle)
    863 {
    864 	char filename[PATH_MAX + 1], key[28];
    865 
    866 	create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");
    867 
    868 	snprintf(key, sizeof(key), "%17s#%08X", dst, handle);
    869 
    870 	return textfile_del(filename, key);
    871 }
    872 
    873 struct record_list {
    874 	sdp_list_t *recs;
    875 	const gchar *addr;
    876 };
    877 
    878 static void create_stored_records_from_keys(char *key, char *value,
    879 							void *user_data)
    880 {
    881 	struct record_list *rec_list = user_data;
    882 	const gchar *addr = rec_list->addr;
    883 	sdp_record_t *rec;
    884 
    885 	if (strncmp(key, addr, 17))
    886 		return;
    887 
    888 	rec = record_from_string(value);
    889 
    890 	rec_list->recs = sdp_list_append(rec_list->recs, rec);
    891 }
    892 
    893 void delete_all_records(const bdaddr_t *src, const bdaddr_t *dst)
    894 {
    895 	sdp_list_t *records, *seq;
    896 	char srcaddr[18], dstaddr[18];
    897 
    898 	ba2str(src, srcaddr);
    899 	ba2str(dst, dstaddr);
    900 
    901 	records = read_records(src, dst);
    902 
    903 	for (seq = records; seq; seq = seq->next) {
    904 		sdp_record_t *rec = seq->data;
    905 		delete_record(srcaddr, dstaddr, rec->handle);
    906 	}
    907 
    908 	if (records)
    909 		sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
    910 }
    911 
    912 sdp_list_t *read_records(const bdaddr_t *src, const bdaddr_t *dst)
    913 {
    914 	char filename[PATH_MAX + 1];
    915 	struct record_list rec_list;
    916 	char srcaddr[18], dstaddr[18];
    917 
    918 	ba2str(src, srcaddr);
    919 	ba2str(dst, dstaddr);
    920 
    921 	rec_list.addr = dstaddr;
    922 	rec_list.recs = NULL;
    923 
    924 	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "sdp");
    925 	textfile_foreach(filename, create_stored_records_from_keys, &rec_list);
    926 
    927 	return rec_list.recs;
    928 }
    929 
    930 sdp_record_t *find_record_in_list(sdp_list_t *recs, const char *uuid)
    931 {
    932 	sdp_list_t *seq;
    933 
    934 	for (seq = recs; seq; seq = seq->next) {
    935 		sdp_record_t *rec = (sdp_record_t *) seq->data;
    936 		sdp_list_t *svcclass = NULL;
    937 		char *uuid_str;
    938 
    939 		if (sdp_get_service_classes(rec, &svcclass) < 0)
    940 			continue;
    941 
    942 		/* Extract the uuid */
    943 		uuid_str = bt_uuid2string(svcclass->data);
    944 		if (!uuid_str)
    945 			continue;
    946 
    947 		if (!strcasecmp(uuid_str, uuid)) {
    948 			sdp_list_free(svcclass, free);
    949 			free(uuid_str);
    950 			return rec;
    951 		}
    952 
    953 		sdp_list_free(svcclass, free);
    954 		free(uuid_str);
    955 	}
    956 	return NULL;
    957 }
    958 
    959 int store_device_id(const gchar *src, const gchar *dst,
    960 				const uint16_t source, const uint16_t vendor,
    961 				const uint16_t product, const uint16_t version)
    962 {
    963 	char filename[PATH_MAX + 1], str[20];
    964 
    965 	create_name(filename, PATH_MAX, STORAGEDIR, src, "did");
    966 
    967 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    968 
    969 	snprintf(str, sizeof(str), "%04X %04X %04X %04X", source,
    970 						vendor, product, version);
    971 
    972 	return textfile_put(filename, dst, str);
    973 }
    974 
    975 static int read_device_id_from_did(const gchar *src, const gchar *dst,
    976 					uint16_t *source, uint16_t *vendor,
    977 					uint16_t *product, uint16_t *version)
    978 {
    979 	char filename[PATH_MAX + 1];
    980 	char *str, *vendor_str, *product_str, *version_str;
    981 
    982 	create_name(filename, PATH_MAX, STORAGEDIR, src, "did");
    983 
    984 	str = textfile_get(filename, dst);
    985 	if (!str)
    986 		return -ENOENT;
    987 
    988 	vendor_str = strchr(str, ' ');
    989 	if (!vendor_str) {
    990 		free(str);
    991 		return -ENOENT;
    992 	}
    993 	*(vendor_str++) = 0;
    994 
    995 	product_str = strchr(vendor_str, ' ');
    996 	if (!product_str) {
    997 		free(str);
    998 		return -ENOENT;
    999 	}
   1000 	*(product_str++) = 0;
   1001 
   1002 	version_str = strchr(product_str, ' ');
   1003 	if (!version_str) {
   1004 		free(str);
   1005 		return -ENOENT;
   1006 	}
   1007 	*(version_str++) = 0;
   1008 
   1009 	if (source)
   1010 		*source = (uint16_t) strtol(str, NULL, 16);
   1011 	if (vendor)
   1012 		*vendor = (uint16_t) strtol(vendor_str, NULL, 16);
   1013 	if (product)
   1014 		*product = (uint16_t) strtol(product_str, NULL, 16);
   1015 	if (version)
   1016 		*version = (uint16_t) strtol(version_str, NULL, 16);
   1017 
   1018 	free(str);
   1019 
   1020 	return 0;
   1021 }
   1022 
   1023 int read_device_id(const gchar *srcaddr, const gchar *dstaddr,
   1024 					uint16_t *source, uint16_t *vendor,
   1025 					uint16_t *product, uint16_t *version)
   1026 {
   1027 	uint16_t lsource, lvendor, lproduct, lversion;
   1028 	sdp_list_t *recs;
   1029 	sdp_record_t *rec;
   1030 	bdaddr_t src, dst;
   1031 	int err;
   1032 
   1033 	err = read_device_id_from_did(srcaddr, dstaddr, &lsource,
   1034 						vendor, product, version);
   1035 	if (!err) {
   1036 		if (lsource == 0xffff)
   1037 			err = -ENOENT;
   1038 
   1039 		return err;
   1040 	}
   1041 
   1042 	str2ba(srcaddr, &src);
   1043 	str2ba(dstaddr, &dst);
   1044 
   1045 	recs = read_records(&src, &dst);
   1046 	rec = find_record_in_list(recs, PNP_UUID);
   1047 
   1048 	if (rec) {
   1049 		sdp_data_t *pdlist;
   1050 
   1051 		pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
   1052 		lsource = pdlist ? pdlist->val.uint16 : 0x0000;
   1053 
   1054 		pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
   1055 		lvendor = pdlist ? pdlist->val.uint16 : 0x0000;
   1056 
   1057 		pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
   1058 		lproduct = pdlist ? pdlist->val.uint16 : 0x0000;
   1059 
   1060 		pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
   1061 		lversion = pdlist ? pdlist->val.uint16 : 0x0000;
   1062 
   1063 		err = 0;
   1064 	}
   1065 
   1066 	sdp_list_free(recs, (sdp_free_func_t)sdp_record_free);
   1067 
   1068 	if (err) {
   1069 		/* FIXME: We should try EIR data if we have it, too */
   1070 
   1071 		/* If we don't have the data, we don't want to go through the
   1072 		 * above search every time. */
   1073 		lsource = 0xffff;
   1074 		lvendor = 0x0000;
   1075 		lproduct = 0x0000;
   1076 		lversion = 0x0000;
   1077 	}
   1078 
   1079 	store_device_id(srcaddr, dstaddr, lsource, lvendor, lproduct, lversion);
   1080 
   1081 	if (err)
   1082 		return err;
   1083 
   1084 	if (source)
   1085 		*source = lsource;
   1086 	if (vendor)
   1087 		*vendor = lvendor;
   1088 	if (product)
   1089 		*product = lproduct;
   1090 	if (version)
   1091 		*version = lversion;
   1092 
   1093 	return 0;
   1094 }
   1095 
   1096 int write_device_pairable(bdaddr_t *bdaddr, gboolean mode)
   1097 {
   1098 	char filename[PATH_MAX + 1];
   1099 
   1100 	create_filename(filename, PATH_MAX, bdaddr, "config");
   1101 
   1102 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1103 
   1104 	return textfile_put(filename, "pairable", mode ? "yes" : "no");
   1105 }
   1106 
   1107 int read_device_pairable(bdaddr_t *bdaddr, gboolean *mode)
   1108 {
   1109 	char filename[PATH_MAX + 1], *str;
   1110 
   1111 	create_filename(filename, PATH_MAX, bdaddr, "config");
   1112 
   1113 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1114 
   1115 	str = textfile_get(filename, "pairable");
   1116 	if (!str)
   1117 		return -ENOENT;
   1118 
   1119 	*mode = strcmp(str, "yes") == 0 ? TRUE : FALSE;
   1120 
   1121 	free(str);
   1122 
   1123 	return 0;
   1124 }
   1125 
   1126 gboolean read_blocked(const bdaddr_t *local, const bdaddr_t *remote)
   1127 {
   1128 	char filename[PATH_MAX + 1], *str, addr[18];
   1129 
   1130 	create_filename(filename, PATH_MAX, local, "blocked");
   1131 
   1132 	ba2str(remote, addr);
   1133 
   1134 	str = textfile_caseget(filename, addr);
   1135 	if (!str)
   1136 		return FALSE;
   1137 
   1138 	free(str);
   1139 
   1140 	return TRUE;
   1141 }
   1142 
   1143 int write_blocked(const bdaddr_t *local, const bdaddr_t *remote,
   1144 							gboolean blocked)
   1145 {
   1146 	char filename[PATH_MAX + 1], addr[18];
   1147 
   1148 	create_filename(filename, PATH_MAX, local, "blocked");
   1149 
   1150 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1151 
   1152 	ba2str(remote, addr);
   1153 
   1154 	if (blocked == FALSE)
   1155 		return textfile_casedel(filename, addr);
   1156 
   1157 	return textfile_caseput(filename, addr, "");
   1158 }
   1159 
   1160 int write_device_services(const bdaddr_t *sba, const bdaddr_t *dba,
   1161 							const char *services)
   1162 {
   1163 	char filename[PATH_MAX + 1], addr[18];
   1164 
   1165 	create_filename(filename, PATH_MAX, sba, "primary");
   1166 
   1167 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1168 
   1169 	ba2str(dba, addr);
   1170 
   1171 	return textfile_put(filename, addr, services);
   1172 }
   1173 
   1174 static void filter_keys(char *key, char *value, void *data)
   1175 {
   1176 	struct match *match = data;
   1177 	const char *address = match->pattern;
   1178 
   1179 	/* Each key contains: MAC#handle*/
   1180 	if (strncasecmp(key, address, 17) == 0)
   1181 		match->keys = g_slist_append(match->keys, g_strdup(key));
   1182 }
   1183 
   1184 int delete_device_service(const bdaddr_t *sba, const bdaddr_t *dba)
   1185 {
   1186 	GSList *l;
   1187 	struct match match;
   1188 	char filename[PATH_MAX + 1], address[18];
   1189 	int err;
   1190 
   1191 	create_filename(filename, PATH_MAX, sba, "primary");
   1192 
   1193 	memset(address, 0, sizeof(address));
   1194 	ba2str(dba, address);
   1195 
   1196 	err = textfile_del(filename, address);
   1197 	if (err < 0)
   1198 		return err;
   1199 
   1200 	/* Deleting all characteristics of a given address */
   1201 	memset(&match, 0, sizeof(match));
   1202 	match.pattern = address;
   1203 
   1204 	create_filename(filename, PATH_MAX, sba, "characteristic");
   1205 	err = textfile_foreach(filename, filter_keys, &match);
   1206 	if (err < 0)
   1207 		return err;
   1208 
   1209 	for (l = match.keys; l; l = l->next) {
   1210 		const char *key = l->data;
   1211 		textfile_del(filename, key);
   1212 	}
   1213 
   1214 	g_slist_foreach(match.keys, (GFunc) g_free, NULL);
   1215 	g_slist_free(match.keys);
   1216 
   1217 	/* Deleting all attributes values of a given address */
   1218 	memset(&match, 0, sizeof(match));
   1219 	match.pattern = address;
   1220 
   1221 	create_filename(filename, PATH_MAX, sba, "attributes");
   1222 	err = textfile_foreach(filename, filter_keys, &match);
   1223 	if (err < 0)
   1224 		return err;
   1225 
   1226 	for (l = match.keys; l; l = l->next) {
   1227 		const char *key = l->data;
   1228 		textfile_del(filename, key);
   1229 	}
   1230 
   1231 	g_slist_foreach(match.keys, (GFunc) g_free, NULL);
   1232 	g_slist_free(match.keys);
   1233 
   1234 	return 0;
   1235 }
   1236 
   1237 char *read_device_services(const bdaddr_t *sba, const bdaddr_t *dba)
   1238 {
   1239 	char filename[PATH_MAX + 1], addr[18];
   1240 
   1241 	create_filename(filename, PATH_MAX, sba, "primary");
   1242 
   1243 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1244 
   1245 	ba2str(dba, addr);
   1246 
   1247 	return textfile_caseget(filename, addr);
   1248 }
   1249 
   1250 int write_device_characteristics(const bdaddr_t *sba, const bdaddr_t *dba,
   1251 					uint16_t handle, const char *chars)
   1252 {
   1253 	char filename[PATH_MAX + 1], addr[18], key[23];
   1254 
   1255 	create_filename(filename, PATH_MAX, sba, "characteristic");
   1256 
   1257 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1258 
   1259 	ba2str(dba, addr);
   1260 
   1261 	snprintf(key, sizeof(key), "%17s#%04X", addr, handle);
   1262 
   1263 	return textfile_put(filename, key, chars);
   1264 }
   1265 
   1266 char *read_device_characteristics(const bdaddr_t *sba, const bdaddr_t *dba,
   1267 							uint16_t handle)
   1268 {
   1269 	char filename[PATH_MAX + 1], addr[18], key[23];
   1270 
   1271 	create_filename(filename, PATH_MAX, sba, "characteristic");
   1272 
   1273 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1274 
   1275 	ba2str(dba, addr);
   1276 
   1277 	snprintf(key, sizeof(key), "%17s#%04X", addr, handle);
   1278 
   1279 	return textfile_caseget(filename, key);
   1280 }
   1281 
   1282 int write_device_attribute(const bdaddr_t *sba, const bdaddr_t *dba,
   1283 					uint16_t handle, const char *chars)
   1284 {
   1285 	char filename[PATH_MAX + 1], addr[18], key[23];
   1286 
   1287 	create_filename(filename, PATH_MAX, sba, "attributes");
   1288 
   1289 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1290 
   1291 	ba2str(dba, addr);
   1292 
   1293 	snprintf(key, sizeof(key), "%17s#%04X", addr, handle);
   1294 
   1295 	return textfile_put(filename, key, chars);
   1296 }
   1297 
   1298 int read_device_attributes(const bdaddr_t *sba, textfile_cb func, void *data)
   1299 {
   1300 	char filename[PATH_MAX + 1];
   1301 
   1302 	create_filename(filename, PATH_MAX, sba, "attributes");
   1303 
   1304 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1305 
   1306 	return textfile_foreach(filename, func, data);
   1307 }
   1308 
   1309 int write_device_type(const bdaddr_t *sba, const bdaddr_t *dba,
   1310 						device_type_t type)
   1311 {
   1312 	char filename[PATH_MAX + 1], addr[18], chars[3];
   1313 
   1314 	create_filename(filename, PATH_MAX, sba, "types");
   1315 
   1316 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1317 
   1318 	ba2str(dba, addr);
   1319 
   1320 	snprintf(chars, sizeof(chars), "%2.2X", type);
   1321 
   1322 	return textfile_put(filename, addr, chars);
   1323 }
   1324 
   1325 device_type_t read_device_type(const bdaddr_t *sba, const bdaddr_t *dba)
   1326 {
   1327 	char filename[PATH_MAX + 1], addr[18], *chars;
   1328 	device_type_t type;
   1329 
   1330 	create_filename(filename, PATH_MAX, sba, "types");
   1331 
   1332 	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
   1333 
   1334 	ba2str(dba, addr);
   1335 
   1336 	chars = textfile_caseget(filename, addr);
   1337 	if (chars == NULL)
   1338 		return DEVICE_TYPE_UNKNOWN;
   1339 
   1340 	type = strtol(chars, NULL, 16);
   1341 
   1342 	free(chars);
   1343 
   1344 	return type;
   1345 }
   1346