blob: 356fa900f8262768e3f895f2a5243e34f4296917 [file]
// SPDX-License-Identifier: GPL-2.0-or-later
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2006-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
*
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <glib.h>
#include "bluetooth/bluetooth.h"
#include "bluetooth/sdp.h"
#include "bluetooth/sdp_lib.h"
#include "bluetooth/uuid.h"
#include "textfile.h"
#include "uuid-helper.h"
#include "storage.h"
/* When all services should trust a remote device */
#define GLOBAL_TRUST "[all]"
struct match {
GSList *keys;
char *pattern;
};
int read_discoverable_timeout(const char *src, int *timeout)
{
char filename[PATH_MAX], *str;
create_name(filename, PATH_MAX, src, "config");
str = textfile_get(filename, "discovto");
if (!str)
return -ENOENT;
if (sscanf(str, "%d", timeout) != 1) {
free(str);
return -ENOENT;
}
free(str);
return 0;
}
int read_pairable_timeout(const char *src, int *timeout)
{
char filename[PATH_MAX], *str;
create_name(filename, PATH_MAX, src, "config");
str = textfile_get(filename, "pairto");
if (!str)
return -ENOENT;
if (sscanf(str, "%d", timeout) != 1) {
free(str);
return -ENOENT;
}
free(str);
return 0;
}
int read_on_mode(const char *src, char *mode, int length)
{
char filename[PATH_MAX], *str;
create_name(filename, PATH_MAX, src, "config");
str = textfile_get(filename, "onmode");
if (!str)
return -ENOENT;
strncpy(mode, str, length);
mode[length - 1] = '\0';
free(str);
return 0;
}
int read_local_name(const bdaddr_t *bdaddr, char *name)
{
char filename[PATH_MAX], *str;
int len;
char addr[18];
ba2str(bdaddr, addr);
create_filename(filename, PATH_MAX, "/%s/config", addr);
str = textfile_get(filename, "name");
if (!str)
return -ENOENT;
len = strlen(str);
if (len > HCI_MAX_NAME_LENGTH)
str[HCI_MAX_NAME_LENGTH] = '\0';
strcpy(name, str);
free(str);
return 0;
}
sdp_record_t *record_from_string(const char *str)
{
sdp_record_t *rec;
int size, i, len;
uint8_t *pdata;
char tmp[3];
size = strlen(str)/2;
pdata = g_malloc0(size);
tmp[2] = 0;
for (i = 0; i < size; i++) {
memcpy(tmp, str + (i * 2), 2);
pdata[i] = (uint8_t) strtol(tmp, NULL, 16);
}
rec = sdp_extract_pdu(pdata, size, &len);
g_free(pdata);
return rec;
}
sdp_record_t *find_record_in_list(sdp_list_t *recs, const char *uuid)
{
sdp_list_t *seq;
for (seq = recs; seq; seq = seq->next) {
sdp_record_t *rec = (sdp_record_t *) seq->data;
sdp_list_t *svcclass = NULL;
char *uuid_str;
if (sdp_get_service_classes(rec, &svcclass) < 0)
continue;
/* Extract the uuid */
uuid_str = bt_uuid2string(svcclass->data);
if (!uuid_str) {
sdp_list_free(svcclass, free);
continue;
}
if (!strcasecmp(uuid_str, uuid)) {
sdp_list_free(svcclass, free);
free(uuid_str);
return rec;
}
sdp_list_free(svcclass, free);
free(uuid_str);
}
return NULL;
}