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

📄 dbus-hci.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		dbus_connection_emit_property_changed(connection,					dev_path, DEVICE_INTERFACE,					"Connected", DBUS_TYPE_BOOLEAN,					&connected);		if (device_is_temporary(device)) {			debug("Removing temporary device %s", destination);			adapter_remove_device(connection, adapter, device);		}	}}int set_limited_discoverable(int dd, const uint8_t *cls, gboolean limited){	uint32_t dev_class;	int err;	int num = (limited ? 2 : 1);	uint8_t lap[] = { 0x33, 0x8b, 0x9e, 0x00, 0x8b, 0x9e };	/*	 * 1: giac	 * 2: giac + liac	 */	if (hci_write_current_iac_lap(dd, num, lap, 1000) < 0) {		err = errno;		error("Can't write current IAC LAP: %s(%d)",				strerror(err), err);		return -err;	}	if (limited) {		if (cls[1] & 0x20)			return 0; /* Already limited */		dev_class = (cls[2] << 16) | ((cls[1] | 0x20) << 8) | cls[0];	} else {		if (!(cls[1] & 0x20))			return 0; /* Already clear */		dev_class = (cls[2] << 16) | ((cls[1] & 0xdf) << 8) | cls[0];	}	if (hci_write_class_of_dev(dd, dev_class, 1000) < 0) {		err = errno;		error("Can't write class of device: %s (%d)",							strerror(err), err);		return -err;	}	return 0;}int set_service_classes(int dd, const uint8_t *cls, uint8_t value){	uint32_t dev_class;	int err;	if (cls[2] == value)		return 0; /* Already set */	dev_class = (value << 16) | (cls[1] << 8) | cls[0];	if (hci_write_class_of_dev(dd, dev_class, 1000) < 0) {		err = errno;		error("Can't write class of device: %s (%d)",							strerror(err), err);		return -err;	}	return 0;}/* Section reserved to device HCI callbacks */void hcid_dbus_setname_complete(bdaddr_t *local){	int id, dd = -1;	read_local_name_rp rp;	struct hci_request rq;	const char *pname = (char *) rp.name;	char local_addr[18], name[249];	ba2str(local, local_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	dd = hci_open_dev(id);	if (dd < 0) {		error("HCI device open failed: hci%d", id);		memset(&rp, 0, sizeof(rp));	} else {		memset(&rq, 0, sizeof(rq));		rq.ogf    = OGF_HOST_CTL;		rq.ocf    = OCF_READ_LOCAL_NAME;		rq.rparam = &rp;		rq.rlen   = READ_LOCAL_NAME_RP_SIZE;		rq.event  = EVT_CMD_COMPLETE;		if (hci_send_req(dd, &rq, 1000) < 0) {			error("Sending getting name command failed: %s (%d)",						strerror(errno), errno);			rp.name[0] = '\0';		} else if (rp.status) {			error("Getting name failed with status 0x%02x",					rp.status);			rp.name[0] = '\0';		}		hci_close_dev(dd);	}	strncpy(name, pname, sizeof(name) - 1);	name[248] = '\0';	pname = name;}void hcid_dbus_setscan_enable_complete(bdaddr_t *local){	struct adapter *adapter;	read_scan_enable_rp rp;	struct hci_request rq;	int dd = -1;	uint16_t dev_id;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	dev_id = adapter_get_dev_id(adapter);	dd = hci_open_dev(dev_id);	if (dd < 0) {		error("HCI device open failed: hci%d", dev_id);		return;	}	memset(&rq, 0, sizeof(rq));	rq.ogf    = OGF_HOST_CTL;	rq.ocf    = OCF_READ_SCAN_ENABLE;	rq.rparam = &rp;	rq.rlen   = READ_SCAN_ENABLE_RP_SIZE;	rq.event  = EVT_CMD_COMPLETE;	if (hci_send_req(dd, &rq, 1000) < 0) {		error("Sending read scan enable command failed: %s (%d)",				strerror(errno), errno);		goto failed;	}	if (rp.status) {		error("Getting scan enable failed with status 0x%02x",				rp.status);		goto failed;	}	adapter_remove_discov_timeout(adapter);	if (adapter_get_scan_mode(adapter) != rp.enable)		adapter_mode_changed(adapter, rp.enable);failed:	if (dd >= 0)		hci_close_dev(dd);}void hcid_dbus_write_class_complete(bdaddr_t *local){	struct adapter *adapter;	int dd;	uint8_t cls[3];	uint16_t dev_id;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	dev_id = adapter_get_dev_id(adapter);	dd = hci_open_dev(dev_id);	if (dd < 0) {		error("HCI device open failed: hci%d", dev_id);		return;	}	if (hci_read_class_of_dev(dd, cls, 1000) < 0) {		error("Can't read class of device on hci%d: %s (%d)",			dev_id, strerror(errno), errno);		hci_close_dev(dd);		return;	}	write_local_class(local, cls);	adapter_set_class(adapter, cls);	hci_close_dev(dd);}void hcid_dbus_write_simple_pairing_mode_complete(bdaddr_t *local){	struct adapter *adapter;	int dd;	uint8_t mode;	uint16_t dev_id;	const gchar *path;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	dev_id = adapter_get_dev_id(adapter);	path = adapter_get_path(adapter);	dd = hci_open_dev(dev_id);	if (dd < 0) {		error("HCI adapter open failed: %s", path);		return;	}	if (hci_read_simple_pairing_mode(dd, &mode, 1000) < 0) {		error("Can't read class of adapter on %s: %s(%d)",					path, strerror(errno), errno);		hci_close_dev(dd);		return;	}	adapter_update_ssp_mode(adapter, dd, mode);	hci_close_dev(dd);}int hcid_dbus_get_io_cap(bdaddr_t *local, bdaddr_t *remote,						uint8_t *cap, uint8_t *auth){	struct adapter *adapter;	struct btd_device *device;	struct agent *agent = NULL;	char addr[18];	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return -1;	}	if (get_auth_requirements(local, remote, auth) < 0)		return -1;	ba2str(remote, addr);	device = adapter_find_device(adapter, addr);	if (device) {		agent = device_get_agent(device);		if (agent)			*auth = 0x03;	}	if (!agent)		agent = adapter->agent;	if (!agent) {		if (!(*auth & 0x01)) {			/* No input, no output */			*cap = 0x03;			return 0;		}		error("No agent available for IO capability");		return -1;	}	*cap = agent_get_io_capability(agent);	return 0;}int hcid_dbus_set_io_cap(bdaddr_t *local, bdaddr_t *remote,                                                uint8_t cap, uint8_t auth){	struct adapter *adapter;	struct btd_device *device;	char addr[18];	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return -1;	}	ba2str(remote, addr);	device = adapter_get_device(connection, adapter, addr);	if (device) {		device_set_cap(device, cap);		device_set_auth(device, auth);	}	return 0;}static int inquiry_cancel(int dd, int to){	struct hci_request rq;	uint8_t status;	memset(&rq, 0, sizeof(rq));	rq.ogf    = OGF_LINK_CTL;	rq.ocf    = OCF_INQUIRY_CANCEL;	rq.rparam = &status;	rq.rlen   = sizeof(status);	rq.event = EVT_CMD_COMPLETE;	if (hci_send_req(dd, &rq, to) < 0)		return -1;	if (status) {		errno = bt_error(status);		return -1;	}	return 0;}static int remote_name_cancel(int dd, bdaddr_t *dba, int to){	remote_name_req_cancel_cp cp;	struct hci_request rq;	uint8_t status;	memset(&rq, 0, sizeof(rq));	memset(&cp, 0, sizeof(cp));	bacpy(&cp.bdaddr, dba);	rq.ogf    = OGF_LINK_CTL;	rq.ocf    = OCF_REMOTE_NAME_REQ_CANCEL;	rq.cparam = &cp;	rq.clen   = REMOTE_NAME_REQ_CANCEL_CP_SIZE;	rq.rparam = &status;	rq.rlen = sizeof(status);	rq.event = EVT_CMD_COMPLETE;	if (hci_send_req(dd, &rq, to) < 0)		return -1;	if (status) {		errno = bt_error(status);		return -1;	}	return 0;}int cancel_discovery(struct adapter *adapter){	struct remote_dev_info *dev, match;	GSList *l;	int dd, err = 0;	uint16_t dev_id = adapter_get_dev_id(adapter);	if (!adapter->discov_active)		goto cleanup;	dd = hci_open_dev(dev_id);	if (dd < 0) {		err = -ENODEV;		goto cleanup;	}	/*	 * If there is a pending read remote name request means	 * that the inquiry complete event was already received	 */	memset(&match, 0, sizeof(struct remote_dev_info));	bacpy(&match.bdaddr, BDADDR_ANY);	match.name_status = NAME_REQUESTED;	l = g_slist_find_custom(adapter->found_devices, &match,				(GCompareFunc) found_device_cmp);	if (l) {		dev = l->data;		if (remote_name_cancel(dd, &dev->bdaddr, 1000) < 0) {			error("Read remote name cancel failed: %s, (%d)",					strerror(errno), errno);			err = -errno;		}	} else {		if (inquiry_cancel(dd, 1000) < 0) {			error("Inquiry cancel failed:%s (%d)",					strerror(errno), errno);			err = -errno;		}	}	hci_close_dev(dd);cleanup:	/*	 * Reset discov_requestor and discover_state in the remote name	 * request event handler or in the inquiry complete handler.	 */	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);	g_slist_free(adapter->found_devices);	adapter->found_devices = NULL;	/* Disable name resolution for non D-Bus clients */	if (!adapter->pdiscov_requestor)		adapter->discov_type &= ~RESOLVE_NAME;	return err;}static int periodic_inquiry_exit(int dd, int to){	struct hci_request rq;	uint8_t status;	memset(&rq, 0, sizeof(rq));	rq.ogf    = OGF_LINK_CTL;	rq.ocf    = OCF_EXIT_PERIODIC_INQUIRY;	rq.rparam = &status;	rq.rlen   = sizeof(status);	rq.event = EVT_CMD_COMPLETE;	if (hci_send_req(dd, &rq, to) < 0)		return -1;	if (status) {		errno = status;		return -1;	}	return 0;}int cancel_periodic_discovery(struct adapter *adapter){	struct remote_dev_info *dev, match;	GSList *l;	int dd, err = 0;	uint16_t dev_id = adapter_get_dev_id(adapter);	if (!adapter->pdiscov_active)		goto cleanup;	dd = hci_open_dev(dev_id);	if (dd < 0) {		err = -ENODEV;		goto cleanup;	}	/* find the pending remote name request */	memset(&match, 0, sizeof(struct remote_dev_info));	bacpy(&match.bdaddr, BDADDR_ANY);	match.name_status = NAME_REQUESTED;	l = g_slist_find_custom(adapter->found_devices, &match,			(GCompareFunc) found_device_cmp);	if (l) {		dev = l->data;		if (remote_name_cancel(dd, &dev->bdaddr, 1000) < 0) {			error("Read remote name cancel failed: %s, (%d)",					strerror(errno), errno);			err = -errno;		}	}	/* ovewrite err if necessary: stop periodic inquiry has higher	 * priority */	if (periodic_inquiry_exit(dd, 1000) < 0) {		error("Periodic Inquiry exit failed:%s (%d)",				strerror(errno), errno);		err = -errno;	}	hci_close_dev(dd);cleanup:	/*	 * Reset pdiscov_requestor and pdiscov_active is done when the	 * cmd complete event for exit periodic inquiry mode cmd arrives.	 */	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL);	g_slist_free(adapter->found_devices);	adapter->found_devices = NULL;	return err;}/* Most of the functions in this module require easy access to a connection so * we keep it global here and provide these access functions the other (few) * modules that require access to it */void set_dbus_connection(DBusConnection *conn){	connection = conn;}DBusConnection *get_dbus_connection(void){	return connection;}

⌨️ 快捷键说明

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