⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 device.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2006-2007  Nokia Corporation *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org> * * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/stat.h>#include <errno.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include <bluetooth/sdp.h>#include <bluetooth/sdp_lib.h>#include <glib.h>#include <dbus/dbus.h>#include <gdbus.h>#include "logging.h"#include "textfile.h"#include "hcid.h"#include "adapter.h"#include "device.h"#include "dbus-common.h"#include "dbus-hci.h"#include "error.h"#include "glib-helper.h"#include "agent.h"#include "sdp-xml.h"#include "storage.h"#define DEFAULT_XML_BUF_SIZE	1024#define DISCONNECT_TIMER	2#define DISCOVERY_TIMER		2struct btd_driver_data {	struct btd_device_driver *driver;	void *priv;};struct btd_device {	bdaddr_t	bdaddr;	gchar		*path;	struct btd_adapter	*adapter;	GSList		*uuids;	GSList		*drivers;		/* List of driver_data */	gboolean	temporary;	struct agent	*agent;	guint		disconn_timer;	int		discov_active;		/* Service discovery active */	char		*discov_requestor;	/* discovery requestor unique name */	guint		discov_listener;	guint		discov_timer;	/* For Secure Simple Pairing */	uint8_t		cap;	uint8_t		auth;	gboolean	connected;	/* Whether were creating a security mode 3 connection */	gboolean	secmode3;	sdp_list_t	*tmp_records;};struct browse_req {	DBusConnection *conn;	DBusMessage *msg;	struct btd_device *device;	GSList *match_uuids;	GSList *profiles_added;	GSList *profiles_removed;	sdp_list_t *records;	int search_uuid;};static uint16_t uuid_list[] = {	L2CAP_UUID,	PNP_INFO_SVCLASS_ID,	PUBLIC_BROWSE_GROUP,	0};static GSList *device_drivers = NULL;static void device_free(gpointer user_data){	struct btd_device *device = user_data;	struct btd_adapter *adapter = device->adapter;	struct agent *agent = adapter_get_agent(adapter);	if (device->agent)		agent_destroy(device->agent, FALSE);	if (agent && agent_is_busy(agent, device))		agent_cancel(agent);	g_slist_foreach(device->uuids, (GFunc) g_free, NULL);	g_slist_free(device->uuids);	if (device->disconn_timer)		g_source_remove(device->disconn_timer);	if (device->discov_timer)		g_source_remove(device->discov_timer);	g_free(device->path);	g_free(device);}static gboolean device_is_paired(struct btd_device *device){	struct btd_adapter *adapter = device->adapter;	char filename[PATH_MAX + 1], *str;	char srcaddr[18], dstaddr[18];	gboolean ret;	bdaddr_t src;	adapter_get_address(adapter, &src);	ba2str(&src, srcaddr);	ba2str(&device->bdaddr, dstaddr);	create_name(filename, PATH_MAX, STORAGEDIR,			srcaddr, "linkkeys");	str = textfile_caseget(filename, dstaddr);	ret = str ? TRUE : FALSE;	g_free(str);	return ret;}static DBusMessage *get_properties(DBusConnection *conn,				DBusMessage *msg, void *user_data){	struct btd_device *device = user_data;	struct btd_adapter *adapter = device->adapter;	DBusMessage *reply;	DBusMessageIter iter;	DBusMessageIter dict;	bdaddr_t src;	char name[248], srcaddr[18], dstaddr[18];	char **uuids;	const char *ptr;	dbus_bool_t boolean;	uint32_t class;	int i;	GSList *l;	struct active_conn_info *dev;	ba2str(&device->bdaddr, dstaddr);	reply = dbus_message_new_method_return(msg);	if (!reply)		return NULL;	dbus_message_iter_init_append(reply, &iter);	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);	/* Address */	ptr = dstaddr;	dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr);	/* Name */	ptr = NULL;	memset(name, 0, sizeof(name));	adapter_get_address(adapter, &src);	ba2str(&src, srcaddr);	if (read_device_name(srcaddr, dstaddr, name) == 0) {		ptr = name;		dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr);	}	/* Alias (fallback to name or address) */	if (read_device_alias(srcaddr, dstaddr, name, sizeof(name)) < 1) {		if (!ptr) {			g_strdelimit(dstaddr, ":", '-');			ptr = dstaddr;		}	} else		ptr = name;	if (ptr)		dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr);	/* Class */	if (read_remote_class(&src, &device->bdaddr, &class) == 0) {		const char *icon = class_to_icon(class);		dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class);		if (icon)			dict_append_entry(&dict, "Icon",						DBUS_TYPE_STRING, &icon);	}	/* Paired */	boolean = device_is_paired(device);	dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean);	/* Trusted */	boolean = read_trust(&src, dstaddr, GLOBAL_TRUST);	dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean);	/* Connected */	dev = adapter_search_active_conn_by_bdaddr(adapter, &device->bdaddr);	if (dev)		boolean = TRUE;	else		boolean = FALSE;	dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &boolean);	/* UUIDs */	uuids = g_new0(char *, g_slist_length(device->uuids) + 1);	for (i = 0, l = device->uuids; l; l = l->next, i++)		uuids[i] = l->data;	dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &uuids, i);	g_free(uuids);	/* Adapter */	ptr = adapter_get_path(adapter);	dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr);	dbus_message_iter_close_container(&iter, &dict);	return reply;}static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,					const char *alias, void *data){	struct btd_device *device = data;	struct btd_adapter *adapter = device->adapter;	char srcaddr[18], dstaddr[18];	bdaddr_t src;	int err;	adapter_get_address(adapter, &src);	ba2str(&src, srcaddr);	ba2str(&device->bdaddr, dstaddr);	/* Remove alias if empty string */	err = write_device_alias(srcaddr, dstaddr,			g_str_equal(alias, "") ? NULL : alias);	if (err < 0)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".Failed",				strerror(-err));	emit_property_changed(conn, dbus_message_get_path(msg),				DEVICE_INTERFACE, "Alias",				DBUS_TYPE_STRING, &alias);	return dbus_message_new_method_return(msg);}static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,					dbus_bool_t value, void *data){	struct btd_device *device = data;	struct btd_adapter *adapter = device->adapter;	char srcaddr[18], dstaddr[18];	bdaddr_t src;	adapter_get_address(adapter, &src);	ba2str(&src, srcaddr);	ba2str(&device->bdaddr, dstaddr);	write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value);	emit_property_changed(conn, dbus_message_get_path(msg),				DEVICE_INTERFACE, "Trusted",				DBUS_TYPE_BOOLEAN, &value);	return dbus_message_new_method_return(msg);}static inline DBusMessage *invalid_args(DBusMessage *msg){	return g_dbus_create_error(msg,			ERROR_INTERFACE ".InvalidArguments",			"Invalid arguments in method call");}static DBusMessage *set_property(DBusConnection *conn,				DBusMessage *msg, void *data){	DBusMessageIter iter;	DBusMessageIter sub;	const char *property;	if (!dbus_message_iter_init(msg, &iter))		return invalid_args(msg);	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)		return invalid_args(msg);	dbus_message_iter_get_basic(&iter, &property);	dbus_message_iter_next(&iter);	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)		return invalid_args(msg);	dbus_message_iter_recurse(&iter, &sub);	if (g_str_equal("Trusted", property)) {		dbus_bool_t value;		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)			return invalid_args(msg);		dbus_message_iter_get_basic(&sub, &value);		return set_trust(conn, msg, value, data);	} else if (g_str_equal("Alias", property)) {		const char *alias;		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)			return invalid_args(msg);		dbus_message_iter_get_basic(&sub, &alias);		return set_alias(conn, msg, alias, data);	}	return invalid_args(msg);}static void discover_services_req_exit(DBusConnection *conn, void *user_data){	struct btd_device *device = user_data;	struct btd_adapter *adapter = device->adapter;	bdaddr_t src;	adapter_get_address(adapter, &src);	debug("DiscoverDevices requestor exited");	bt_cancel_discovery(&src, &device->bdaddr);}static DBusMessage *discover_services(DBusConnection *conn,					DBusMessage *msg, void *user_data){	struct btd_device *device = user_data;	const char *pattern;	int err;	if (device->discov_active)		return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",							"Discover in progress");	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,						DBUS_TYPE_INVALID) == FALSE)		goto fail;	if (strlen(pattern) == 0) {		err = device_browse(device, conn, msg, NULL, FALSE);		if (err < 0)			goto fail;	} else {		uuid_t uuid;		if (bt_string2uuid(&uuid, pattern) < 0)			return invalid_args(msg);		sdp_uuid128_to_uuid(&uuid);		err = device_browse(device, conn, msg, &uuid, FALSE);		if (err < 0)			goto fail;	}	return NULL;fail:	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",					"Discovery Failed");}static DBusMessage *cancel_discover(DBusConnection *conn,					DBusMessage *msg, void *user_data){	struct btd_device *device = user_data;	struct btd_adapter *adapter = device->adapter;	bdaddr_t src;	adapter_get_address(adapter, &src);	if (!device->discov_active)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".Failed",				"No pending discovery");	/* only the discover requestor can cancel the inquiry process */	if (!device->discov_requestor ||			strcmp(device->discov_requestor, dbus_message_get_sender(msg)))		return g_dbus_create_error(msg,				ERROR_INTERFACE ".NotAuthorized",				"Not Authorized");	if (bt_cancel_discovery(&src, &device->bdaddr) < 0)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".Failed",				"No pending discover");	return dbus_message_new_method_return(msg);}static gboolean disconnect_timeout(gpointer user_data){	struct btd_device *device = user_data;	struct active_conn_info *ci;	disconnect_cp cp;	int dd;	uint16_t dev_id = adapter_get_dev_id(device->adapter);	device->disconn_timer = 0;	ci = adapter_search_active_conn_by_bdaddr(device->adapter,							&device->bdaddr);	if (!ci)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -