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

📄 adapter.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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},	{ "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;		error("Can't read address for hci%d: %s (%d)",					dev_id, strerror(err), err);		hci_close_dev(dd);		return err;	}	hci_close_dev(dd);	return 0;}static int adapter_setup(struct btd_adapter *adapter, int dd){	struct hci_dev *dev = &adapter->dev;	uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 };	uint8_t inqmode;	int err;	char name[249];	if (dev->hci_rev > 1) {		if (dev->features[5] & LMP_SNIFF_SUBR)			events[5] |= 0x20;		if (dev->features[5] & LMP_PAUSE_ENC)			events[5] |= 0x80;		if (dev->features[6] & LMP_EXT_INQ)			events[5] |= 0x40;		if (dev->features[6] & LMP_NFLUSH_PKTS)			events[7] |= 0x01;		if (dev->features[7] & LMP_LSTO)			events[6] |= 0x80;		if (dev->features[6] & LMP_SIMPLE_PAIR) {			events[6] |= 0x01;	/* IO Capability Request */			events[6] |= 0x02;	/* IO Capability Response */			events[6] |= 0x04;	/* User Confirmation Request */			events[6] |= 0x08;	/* User Passkey Request */			events[6] |= 0x10;	/* Remote OOB Data Request */			events[6] |= 0x20;	/* Simple Pairing Complete */			events[7] |= 0x04;	/* User Passkey Notification */			events[7] |= 0x08;	/* Keypress Notification */			events[7] |= 0x10;	/* Remote Host Supported Features Notification */		}		hci_send_cmd(dd, OGF_HOST_CTL, OCF_SET_EVENT_MASK,						sizeof(events), events);	}	if (read_local_name(&adapter->bdaddr, name) == 0) {		memcpy(dev->name, name, 248);		hci_write_local_name(dd, name, HCI_REQ_TIMEOUT);        }	update_ext_inquiry_response(dd, dev);	inqmode = get_inquiry_mode(dev);	if (inqmode < 1)		return 0;	if (hci_write_inquiry_mode(dd, inqmode, HCI_REQ_TIMEOUT) < 0) {		err = -errno;		error("Can't write inquiry mode for %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return err;	}	return 0;}static int active_conn_append(GSList **list, bdaddr_t *bdaddr,				uint16_t handle){	struct active_conn_info *dev;	dev = g_new0(struct active_conn_info, 1);	bacpy(&dev->bdaddr, bdaddr);	dev->handle = handle;	*list = g_slist_append(*list, dev);	return 0;}static void create_stored_device_from_profiles(char *key, char *value,						void *user_data){	struct btd_adapter *adapter = user_data;	GSList *uuids = bt_string2list(value);	struct btd_device *device;	bdaddr_t dst;	char srcaddr[18], dstaddr[18];	ba2str(&adapter->bdaddr, srcaddr);	if (g_slist_find_custom(adapter->devices,				key, (GCompareFunc) device_address_cmp))		return;	device = device_create(connection, adapter, key);	if (!device)		return;	device_set_temporary(device, FALSE);	adapter->devices = g_slist_append(adapter->devices, device);	device_get_address(device, &dst);	ba2str(&dst, dstaddr);	device_probe_drivers(device, uuids);	g_slist_foreach(uuids, (GFunc) g_free, NULL);	g_slist_free(uuids);}static void create_stored_device_from_linkkeys(char *key, char *value,						void *user_data){	struct btd_adapter *adapter = user_data;	struct btd_device *device;	if (g_slist_find_custom(adapter->devices,				key, (GCompareFunc) device_address_cmp))		return;	device = device_create(connection, adapter, key);	if (device) {		device_set_temporary(device, FALSE);		adapter->devices = g_slist_append(adapter->devices, device);	}}static void load_devices(struct btd_adapter *adapter){	char filename[PATH_MAX + 1];	char srcaddr[18];	ba2str(&adapter->bdaddr, srcaddr);	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "profiles");	textfile_foreach(filename, create_stored_device_from_profiles, adapter);	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "linkkeys");	textfile_foreach(filename, create_stored_device_from_linkkeys, adapter);}static void load_drivers(struct btd_adapter *adapter){	GSList *l;	for (l = adapter_drivers; l; l = l->next) {		struct btd_adapter_driver *driver = l->data;		if (driver->probe)			driver->probe(adapter);	}}static int get_discoverable_timeout(const char *src){	int timeout;	if (read_discoverable_timeout(src, &timeout) == 0)		return timeout;	return main_opts.discovto;}static int get_pairable_timeout(const char *src){	int timeout;	if (read_pairable_timeout(src, &timeout) == 0)		return timeout;	return main_opts.pairto;}static void adapter_up(struct btd_adapter *adapter, int dd){	char mode[14], srcaddr[18];	int i;	uint8_t scan_mode;	gboolean powered, first_init;	ba2str(&adapter->bdaddr, srcaddr);	first_init = adapter->first_init;	if (adapter->first_init)		adapter->first_init = FALSE;	adapter->up = 1;	adapter->discov_timeout = get_discoverable_timeout(srcaddr);	adapter->pairable_timeout = get_pairable_timeout(srcaddr);	adapter->state = DISCOVER_TYPE_NONE;	adapter->mode = MODE_CONNECTABLE;	scan_mode = SCAN_PAGE;	powered = TRUE;	/* Set pairable mode */	if (read_device_pairable(&adapter->bdaddr, &adapter->pairable) < 0)		adapter->pairable = TRUE;	/* Set scan mode */	if (read_device_mode(srcaddr, mode, sizeof(mode)) < 0)		goto proceed;	if (g_str_equal(mode, "off")) {		powered = FALSE;		if (main_opts.offmode == HCID_OFFMODE_NOSCAN) {			adapter->mode = MODE_OFF;			scan_mode = SCAN_DISABLED;		} else if (main_opts.offmode == HCID_OFFMODE_DEVDOWN) {			if (first_init) {				ioctl(dd, HCIDEVDOWN, adapter->dev_id);				return;			}			if (read_on_mode(srcaddr, mode, sizeof(mode)) < 0)				write_device_mode(&adapter->bdaddr,							"connectable");			else				write_device_mode(&adapter->bdaddr, mode);			adapter_up(adapter, dd);			return;		}	} else if (!g_str_equal(mode, "connectable") &&			adapter->discov_timeout == 0) {		/* Set discoverable only if timeout is 0 */		adapter->mode = adapter->pairable ?					MODE_LIMITED : MODE_DISCOVERABLE;		scan_mode = SCAN_PAGE | SCAN_INQUIRY;	}proceed:	hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,					1, &scan_mode);	/* retrieve the active connections: address the scenario where	 * the are active connections before the daemon've started */	if (adapter->first_init) {		struct hci_conn_list_req *cl = NULL;		struct hci_conn_info *ci;		cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl));		cl->dev_id = adapter->dev_id;		cl->conn_num = 10;		ci = cl->conn_info;		if (ioctl(dd, HCIGETCONNLIST, cl) == 0) {			for (i = 0; i < cl->conn_num; i++, ci++)				active_conn_append(&adapter->active_conn,						&ci->bdaddr, ci->handle);		}		g_free(cl);	}	if (main_opts.offmode == HCID_OFFMODE_DEVDOWN)		emit_property_changed(connection, adapter->path,					ADAPTER_INTERFACE, "Powered",					DBUS_TYPE_BOOLEAN, &powered);	if (adapter->first_init) {		load_drivers(adapter);		load_devices(adapter);	}}int adapter_start(struct btd_adapter *adapter){	struct hci_dev *dev = &adapter->dev;	struct hci_dev_info di;	struct hci_version ver;	uint8_t features[8];	int dd, err;	char name[249];	if (hci_devinfo(adapter->dev_id, &di) < 0)		return -errno;	if (hci_test_bit(HCI_RAW, &di.flags)) {		dev->ignore = 1;		return -1;	}	if (!bacmp(&di.bdaddr, BDADDR_ANY)) {		int err;		debug("Adapter %s without an address", adapter->path);		err = adapter_read_bdaddr(adapter->dev_id, &di.bdaddr);		if (err < 0)			return err;	}	bacpy(&adapter->bdaddr, &di.bdaddr);	memcpy(dev->features, di.features, 8);	dd = hci_open_dev(adapter->dev_id);	if (dd < 0) {		err = -errno;		error("Can't open adapter %s: %s (%d)",					adapter->path, strerror(err), err);		return err;	}	if (hci_read_local_version(dd, &ver, HCI_REQ_TIMEOUT) < 0) {		err = -errno;		error("Can't read version info for %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return err;	}	dev->hci_rev = ver.hci_rev;	dev->lmp_ver = ver.lmp_ver;	dev->lmp_subver = ver.lmp_subver;	dev->manufacturer = ver.manufacturer;	if (hci_read_local_features(dd, features, HCI_REQ_TIMEOUT) < 0) {		err = -errno;		error("Can't read features for %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return err;	}	memcpy(dev->features, features, 8);	if (hci_read_class_of_dev(dd, dev->class, HCI_REQ_TIMEOUT) < 0) {		err = -errno;		error("Can't read class of adapter on %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return err;	}	if (hci_read_local_name(dd, sizeof(name), name, HCI_REQ_TIMEOUT) < 0) {		err = -errno;		error("Can't read local name on %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return err;	}	memcpy(dev->name, name, 248);	if (!(features[6] & LMP_SIMPLE_PAIR))		goto setup;	if (ioctl(dd, HCIGETAUTHINFO, NULL) < 0 && errno != EINVAL)		hci_write_simple_pairing_mode(dd, 0x01, HCI_REQ_TIMEOUT);	if (hci_read_simple_pairing_mode(dd, &dev->ssp_mode,						HCI_REQ_TIMEOUT) < 0) {		err = -errno;		error("Can't read simple pairing mode on %s: %s (%d)",					adapter->path, strerror(err), err);		hci_close_dev(dd);		return err;	}setup:	hci_send_cmd(dd, OGF_LINK_POLICY,				OCF_READ_DEFAULT_LINK_POLICY, 0, NULL);	if (hci_test_bit(HCI_INQUIRY, &di.flags))		adapter->state |= STD_INQUIRY;	else		adapter->state &= ~STD_INQUIRY;	adapter_setup(adapter, dd);	adapter_up(adapter, dd);	hci_close_dev(dd);	info("Adapter %s has been enabled", adapter->path);	return 0;}static void reply_pending_requests(struct btd_adapter *adapter){	DBusMessage *reply;	if (!adapter)		return;	/* pending bonding */	if (adapter->bonding) {		reply = new_authentication_return(adapter->bonding->msg,					HCI_OE_USER_ENDED_CONNECTION);		g_dbus_send_message(connection, reply);		remove_pending_device(adapter);		g_dbus_remove_watch(adapter->bonding->conn,					adapter->bonding->listener_id);		if (adapter->bonding->io_id)			g_source_remove(adapter->bonding->io_id);		if (adapter->bonding->io)			g_io_channel_close(adapter->bonding->io);		bonding_request_free(adapter->bonding);		adapter->bonding = NULL;	}	if (adapter->state & STD_INQUIRY) {		/* Cancel inquiry initiated by 

⌨️ 快捷键说明

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