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

📄 adapter.c

📁 LINUX下
💻 C
📖 第 1 页 / 共 5 页
字号:
}static DBusMessage *set_property(DBusConnection *conn,					DBusMessage *msg, void *data){	struct btd_adapter *adapter = data;	DBusMessageIter iter;	DBusMessageIter sub;	const char *property;	char srcaddr[18];	ba2str(&adapter->bdaddr, srcaddr);	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("Name", property)) {		const char *name;		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)			return invalid_args(msg);		dbus_message_iter_get_basic(&sub, &name);		return set_name(conn, msg, name, data);	} else if (g_str_equal("Mode", property)) {		const char *mode;		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)			return invalid_args(msg);		dbus_message_iter_get_basic(&sub, &mode);		adapter->global_mode = get_mode(&adapter->bdaddr, mode);		if (adapter->global_mode == adapter->mode)			return dbus_message_new_method_return(msg);		if (adapter->mode_sessions && adapter->global_mode < adapter->mode)			return confirm_mode(conn, msg, mode, data);		return set_mode(conn, msg,				get_mode(&adapter->bdaddr, mode), data);	} else if (g_str_equal("Powered", property)) {		gboolean powered;		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)			return invalid_args(msg);		dbus_message_iter_get_basic(&sub, &powered);		return set_powered(conn, msg, powered, data);	} else if (g_str_equal("Discoverable", property)) {		gboolean discoverable;		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)			return invalid_args(msg);		dbus_message_iter_get_basic(&sub, &discoverable);		return set_discoverable(conn, msg, discoverable, data);	} else if (g_str_equal("DiscoverableTimeout", property)) {		uint32_t timeout;		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT32)			return invalid_args(msg);		dbus_message_iter_get_basic(&sub, &timeout);		return set_discoverable_timeout(conn, msg, timeout, data);	}	return invalid_args(msg);}static DBusMessage *mode_request(DBusConnection *conn,					DBusMessage *msg, const char *mode,					void *data){	struct btd_adapter *adapter = data;	struct session_req *req;	uint8_t new_mode;	int ret;	char srcaddr[18];	ba2str(&adapter->bdaddr, srcaddr);	new_mode = get_mode(&adapter->bdaddr, mode);	if (new_mode != MODE_CONNECTABLE && new_mode != MODE_DISCOVERABLE)		return invalid_args(msg);	if (!adapter->agent)		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",				"No agent registered");	if (!adapter->mode_sessions)		adapter->global_mode = adapter->mode;	req = find_session(adapter->mode_sessions, msg);	if (!req) {		req = create_session(adapter, conn, msg, new_mode,					(GDBusWatchFunction) session_free);		adapter->mode_sessions = g_slist_append(adapter->mode_sessions,					req);	} else {		req->mode = new_mode;		adapter->mode_sessions = g_slist_append(adapter->mode_sessions,					req);		session_remove(req);		return dbus_message_new_method_return(msg);	}	/* No need to change mode */	if (adapter->mode >= new_mode)		return dbus_message_new_method_return(msg);	ret = agent_confirm_mode_change(adapter->agent, mode, confirm_mode_cb,					req);	if (ret < 0) {		session_unref(req);		return invalid_args(msg);	}	return NULL;}static DBusMessage *request_mode(DBusConnection *conn,					DBusMessage *msg, void *data){	const char *mode;	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &mode,						DBUS_TYPE_INVALID))		return invalid_args(msg);	return mode_request(conn, msg, mode, data);}static DBusMessage *request_session(DBusConnection *conn,					DBusMessage *msg, void *data){	return mode_request(conn, msg, "connectable", data);}static DBusMessage *release_session(DBusConnection *conn,					DBusMessage *msg, void *data){	struct btd_adapter *adapter = data;	struct session_req *req;	req = find_session(adapter->mode_sessions, msg);	if (!req)		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",				"No Mode to release");	session_unref(req);	return dbus_message_new_method_return(msg);}static DBusMessage *list_devices(DBusConnection *conn,						DBusMessage *msg, void *data){	struct btd_adapter *adapter = data;	DBusMessage *reply;	GSList *l;	DBusMessageIter iter;	DBusMessageIter array_iter;	const gchar *dev_path;	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))		return invalid_args(msg);	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_TYPE_OBJECT_PATH_AS_STRING, &array_iter);	for (l = adapter->devices; l; l = l->next) {		struct btd_device *device = l->data;		if (device_is_temporary(device))			continue;		dev_path = device_get_path(device);		dbus_message_iter_append_basic(&array_iter,				DBUS_TYPE_OBJECT_PATH, &dev_path);	}	dbus_message_iter_close_container(&iter, &array_iter);	return reply;}static DBusMessage *cancel_device_creation(DBusConnection *conn,						DBusMessage *msg, void *data){	struct btd_adapter *adapter = data;	struct bonding_request_info *bonding = adapter->bonding;	const gchar *address;	bdaddr_t bda;	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,						DBUS_TYPE_INVALID) == FALSE)		return invalid_args(msg);	if (check_address(address) < 0)		return invalid_args(msg);	str2ba(address, &bda);	if (bonding && !bacmp(&bonding->bdaddr, &bda)) {		if (!g_str_equal(dbus_message_get_sender(msg),					dbus_message_get_sender(bonding->msg)))			return not_authorized(msg);		debug("Canceling device creation for %s", address);		cancel_bonding(adapter, FALSE);	}	return dbus_message_new_method_return(msg);}static DBusMessage *create_device(DBusConnection *conn,					DBusMessage *msg, void *data){	struct btd_adapter *adapter = data;	struct btd_device *device;	const gchar *address;	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,						DBUS_TYPE_INVALID) == FALSE)		return invalid_args(msg);	if (check_address(address) < 0)		return invalid_args(msg);	if (adapter_find_device(adapter, address))		return g_dbus_create_error(msg,				ERROR_INTERFACE ".AlreadyExists",				"Device already exists");	debug("create_device(%s)", address);	device = device_create(conn, adapter, address);	if (!device)		return NULL;	device_set_temporary(device, FALSE);	device_browse(device, conn, msg, NULL, FALSE);	adapter->devices = g_slist_append(adapter->devices, device);	return NULL;}static uint8_t parse_io_capability(const char *capability){	if (g_str_equal(capability, ""))		return IO_CAPABILITY_DISPLAYYESNO;	if (g_str_equal(capability, "DisplayOnly"))		return IO_CAPABILITY_DISPLAYONLY;	if (g_str_equal(capability, "DisplayYesNo"))		return IO_CAPABILITY_DISPLAYYESNO;	if (g_str_equal(capability, "KeyboardOnly"))		return IO_CAPABILITY_KEYBOARDONLY;	if (g_str_equal(capability, "NoInputOutput"))		return IO_CAPABILITY_NOINPUTOUTPUT;	return IO_CAPABILITY_INVALID;}static DBusMessage *create_paired_device(DBusConnection *conn,					DBusMessage *msg, void *data){	const gchar *address, *agent_path, *capability;	uint8_t cap;	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,					DBUS_TYPE_OBJECT_PATH, &agent_path,					DBUS_TYPE_STRING, &capability,						DBUS_TYPE_INVALID) == FALSE)		return invalid_args(msg);	if (check_address(address) < 0)		return invalid_args(msg);	cap = parse_io_capability(capability);	if (cap == IO_CAPABILITY_INVALID)		return invalid_args(msg);	return create_bonding(conn, msg, address, agent_path, cap, data);}static gint device_path_cmp(struct btd_device *device, const gchar *path){	const gchar *dev_path = device_get_path(device);	return strcasecmp(dev_path, path);}static DBusMessage *remove_device(DBusConnection *conn,						DBusMessage *msg, void *data){	struct btd_adapter *adapter = data;	struct btd_device *device;	const char *path;	GSList *l;	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,						DBUS_TYPE_INVALID) == FALSE)		return invalid_args(msg);	l = g_slist_find_custom(adapter->devices,			path, (GCompareFunc) device_path_cmp);	if (!l)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"Device does not exist");	device = l->data;	if (device_is_temporary(device) || device_is_busy(device))		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"Device creation in progress");	adapter_remove_device(conn, adapter, device);	return dbus_message_new_method_return(msg);}static DBusMessage *find_device(DBusConnection *conn,					DBusMessage *msg, void *data){	struct btd_adapter *adapter = data;	struct btd_device *device;	DBusMessage *reply;	const gchar *address;	GSList *l;	const gchar *dev_path;	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,						DBUS_TYPE_INVALID))		return invalid_args(msg);	l = g_slist_find_custom(adapter->devices,			address, (GCompareFunc) device_address_cmp);	if (!l)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"Device does not exist");	device = l->data;	if (device_is_temporary(device))		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"Device creation in progress");	reply = dbus_message_new_method_return(msg);	if (!reply)		return NULL;	dev_path = device_get_path(device);	dbus_message_append_args(reply,				DBUS_TYPE_OBJECT_PATH, &dev_path,				DBUS_TYPE_INVALID);	return reply;}static void agent_removed(struct agent *agent, struct btd_adapter *adapter){	struct pending_auth_info *auth;	GSList *l;	adapter->agent = NULL;	l = g_slist_find_custom(adapter->auth_reqs, agent,					auth_info_agent_cmp);	if (!l)		return;	auth = l->data;	auth->agent = NULL;}static DBusMessage *register_agent(DBusConnection *conn,					DBusMessage *msg, void *data){	const char *path, *name, *capability;	struct agent *agent;	struct btd_adapter *adapter = data;	uint8_t cap;	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,			DBUS_TYPE_STRING, &capability, DBUS_TYPE_INVALID))		return NULL;	if (adapter->agent)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".AlreadyExists",				"Agent already exists");	cap = parse_io_capability(capability);	if (cap == IO_CAPABILITY_INVALID)		return invalid_args(msg);	name = dbus_message_get_sender(msg);	agent = agent_create(adapter, name, path, cap,				(agent_remove_cb) agent_removed, adapter);	if (!agent)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".Failed",				"Failed to create a new agent");	adapter->agent = agent;	debug("Agent registered for hci%d at %s:%s", adapter->dev_id, name,			path);	return dbus_message_new_method_return(msg);}static DBusMessage *unregister_agent(DBusConnection *conn,					DBusMessage *msg, void *data){	const char *path, *name;	struct btd_adapter *adapter = data;	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,						DBUS_TYPE_INVALID))		return NULL;	name = dbus_message_get_sender(msg);	if (!adapter->agent || !agent_matches(adapter->agent, name, path))		return g_dbus_create_error(msg,				ERROR_INTERFACE ".DoesNotExist",				"No such agent");	agent_destroy(adapter->agent, FALSE);	adapter->agent = NULL;	return dbus_message_new_method_return(msg);}/* BlueZ 4.0 API */static GDBusMethodTable adapter_methods[] = {	{ "GetProperties",	"",	"a{sv}",get_properties		},	{ "SetProperty",	"sv",	"",	set_property,						G_DBUS_METHOD_FLAG_ASYNC},	{ "RequestMode",	"s",	"",	request_mode,						G_DBUS_METHOD_FLAG_ASYNC |						G_DBUS_METHOD_FLAG_DEPRECATED},	{ "ReleaseMode",	"",	"",	release_session,						G_DBUS_METHOD_FLAG_DEPRECATED},	{ "RequestSession",	"",	"",	request_session,						G_DBUS_METHOD_FLAG_ASYNC},	{ "ReleaseSession",	"",	"",	release_session		},	{ "StartDiscovery",	"",	"",	adapter_start_discovery },	{ "StopDiscovery",	"",	"",	adapter_stop_discovery,						G_DBUS_METHOD_FLAG_ASYNC},	{ "ListDevices",	"",	"ao",	list_devices,						G_DBUS_METHOD_FLAG_DEPRECATED},	{ "CreateDevice",	"s",	"o",	create_device,						G_DBUS_METHOD_FLAG_ASYNC},	{ "CreatePairedDevice",	"sos",	"o",	create_paired_device,						G_DBUS_METHOD_FLAG_ASYNC},	{ "CancelDeviceCreation","s",	"",	cancel_device_creation	},	{ "RemoveDevice",	"o",	"",	remove_device		},	{ "FindDevice",		"s",	"o",	find_device		},	{ "RegisterAgent",	"os",	"",	register_agent		},	{ "UnregisterAgent",	"o",	"",	unregister_agent	},	{ }};static GDBusSignalTable adapter_signals[] = {	{ "DeviceCreated",		"o"		},	{ "DeviceRemoved",		"o"		},	{ "DeviceFound",		"sa{sv}"	},	{ "PropertyChanged",		"sv"		},	{ "DeviceDisappeared",		"s"		},	{ }};static inline uint8_t get_inquiry_mode(struct hci_dev *dev){	if (dev->features[6] & LMP_EXT_INQ)		return 2;	if (dev->features[3] & LMP_RSSI_INQ)		return 1;	if (dev->manufacturer == 11 &&			dev->hci_rev == 0x00 && dev->lmp_subver == 0x0757)		return 1;	if (dev->manufacturer == 15) {		if (dev->hci_rev == 0x03 && dev->lmp_subver == 0x6963)			return 1;		if (dev->hci_rev == 0x09 && dev->lmp_subver == 0x6963)			return 1;		if (dev->hci_rev == 0x00 && dev->lmp_subver == 0x6965)			return 1;	}	if (dev->manufacturer == 31 &&			dev->hci_rev == 0x2005 && dev->lmp_subver == 0x1805)		return 1;	return 0;}static int adapter_read_bdaddr(uint16_t dev_id, bdaddr_t *bdaddr){	int dd, err;	dd = hci_open_dev(dev_id);	if (dd < 0) {		err = errno;		error("Can't open device hci%d: %s (%d)",					dev_id, strerror(err), err);		return -err;	}	if (hci_read_bd_addr(dd, bdaddr, HCI_REQ_TIMEOUT) < 0) {		err = errno;

⌨️ 快捷键说明

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