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

📄 adapter.c

📁 LINUX下
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 void adapter_up(struct btd_adapter *adapter, int dd){	struct hci_conn_list_req *cl = NULL;	struct hci_conn_info *ci;	const char *pmode;	char mode[14], srcaddr[18];	int i;	gboolean powered;	gboolean discoverable;	ba2str(&adapter->bdaddr, srcaddr);	adapter->up = 1;	adapter->discov_timeout = get_discoverable_timeout(srcaddr);	adapter->state = DISCOVER_TYPE_NONE;	/* Set scan mode */	if (read_device_mode(srcaddr, mode, sizeof(mode)) == 0) {		if (!strcmp(mode, "off")) {			if (main_opts.offmode == HCID_OFFMODE_NOSCAN) {				adapter->mode = MODE_OFF;				adapter->scan_mode= SCAN_DISABLED;			} else if (main_opts.offmode == HCID_OFFMODE_DEVDOWN) {				static gboolean restore_on_mode = FALSE;				if (!restore_on_mode) {					ioctl(dd, HCIDEVDOWN, adapter->dev_id);					restore_on_mode = TRUE;					return;				}				if (read_on_mode(srcaddr, mode, sizeof(mode)) < 0)					write_device_mode(&adapter->bdaddr, mode);				else					write_device_mode(&adapter->bdaddr, "connectable");				adapter_up(adapter, dd);			}		} else if (!strcmp(mode, "connectable")) {			adapter->mode = MODE_CONNECTABLE;			adapter->scan_mode = SCAN_PAGE;		} else if (!strcmp(mode, "discoverable")) {			/* Set discoverable only if timeout is 0 */			if (adapter->discov_timeout == 0) {				adapter->mode = MODE_DISCOVERABLE;				adapter->scan_mode = SCAN_PAGE | SCAN_INQUIRY;			} else {				adapter->mode = MODE_CONNECTABLE;				adapter->scan_mode = SCAN_PAGE;			}		} else if (!strcmp(mode, "limited")) {			/* Set discoverable only if timeout is 0 */			if (adapter->discov_timeout == 0) {				adapter->mode = MODE_LIMITED;				adapter->scan_mode = SCAN_PAGE | SCAN_INQUIRY;			} else {				adapter->mode = MODE_CONNECTABLE;				adapter->scan_mode = SCAN_PAGE;			}		}	}	hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,					1, &adapter->scan_mode);	if (adapter->mode == MODE_LIMITED)		set_limited_discoverable(dd, adapter->dev.class, TRUE);	/*	 * retrieve the active connections: address the scenario where	 * the are active connections before the daemon've started	 */	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);	pmode = mode2str(adapter->mode);	emit_property_changed(connection, adapter->path, ADAPTER_INTERFACE,				"Mode", DBUS_TYPE_STRING, &pmode);	powered = adapter->scan_mode == SCAN_DISABLED ? FALSE : TRUE;	emit_property_changed(connection, adapter->path, ADAPTER_INTERFACE,				"Powered", DBUS_TYPE_BOOLEAN, &powered);	discoverable = adapter->scan_mode == (SCAN_PAGE | SCAN_INQUIRY) ? TRUE				: FALSE;	emit_property_changed(connection, adapter->path,				ADAPTER_INTERFACE, "Discoverable",				DBUS_TYPE_BOOLEAN, &discoverable);	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 D-Bus client */		if (adapter->disc_sessions)			cancel_discovery(adapter);	}	if (adapter->state & PERIODIC_INQUIRY) {		/* Stop periodic inquiry initiated by D-Bus client */		if (adapter->disc_sessions)			cancel_periodic_discovery(adapter);	}}static void unload_drivers(struct btd_adapter *adapter){	GSList *l;	for (l = adapter_drivers; l; l = l->next) {		struct btd_adapter_driver *driver = l->data;		if (driver->remove)			driver->remove(adapter);	}}int adapter_stop(struct btd_adapter *adapter){	const char *mode = "off";	gboolean powered, discoverable;	/* cancel pending timeout */	if (adapter->discov_timeout_id) {		g_source_remove(adapter->discov_timeout_id);		adapter->discov_timeout_id = 0;	}	/* check pending requests */	reply_pending_requests(adapter);	if (adapter->disc_sessions) {		g_slist_foreach(adapter->disc_sessions, (GFunc) session_free,				NULL);		g_slist_free(adapter->disc_sessions);		adapter->disc_sessions = NULL;	}	if (adapter->found_devices) {		g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);		g_slist_free(adapter->found_devices);		adapter->found_devices = NULL;	}	if (adapter->oor_devices) {		g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL);		g_slist_free(adapter->oor_devices);		adapter->oor_devices = NULL;	}	if (adapter->auth_reqs) {		g_slist_foreach(adapter->auth_reqs, (GFunc) g_free, NULL);		g_slist_free(adapter->auth_reqs);		adapter->auth_reqs = NULL;	}	if (adapter->active_conn) {		g_slist_foreach(adapter->active_conn, (GFunc) g_free, NULL);		g_slist_free(adapter->active_conn);		adapter->active_conn = NULL;	}	emit_property_changed(connection, adapter->path, ADAPTER_INTERFACE,				"Mode", DBUS_TYPE_STRING, &mode);	powered = FALSE;	emit_property_changed(connection, adapter->path, ADAPTER_INTERFACE,				"Powered", DBUS_TYPE_BOOLEAN, &powered);	if (adapter->scan_mode == (SCAN_PAGE | SCAN_INQUIRY)) {		discoverable = FALSE;		emit_property_changed(connection, adapter->path,					ADAPTER_INTERFACE, "Discoverable",					DBUS_TYPE_BOOLEAN, &discoverable);	}	adapter->up = 0;	adapter->scan_mode = SCAN_DISABLED;	adapter->mode = MODE_OFF;	adapter->state = DISCOVER_TYPE_NONE;	unload_drivers(adapter);	info("Adapter %s has been disabled", adapter->path);	return 0;}int adapter_update(struct btd_adapter *adapter){	struct hci_dev *dev = &adapter->dev;	int dd;	if (dev->ignore)		return 0;	dd = hci_open_dev(adapter->dev_id);	if (dd < 0) {		int err = errno;		error("Can't open adapter %s: %s (%d)",					adapter->path, strerror(err), err);		return -err;	}	update_ext_inquiry_response(dd, dev);	hci_close_dev(dd);	return 0;}int adapter_get_class(struct btd_adapter *adapter, uint8_t *cls){	struct hci_dev *dev = &adapter->dev;	memcpy(cl

⌨️ 快捷键说明

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