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

📄 dbus-hci.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 3 页
字号:
{	char peer_addr[18];	struct btd_adapter *adapter;	struct bonding_request_info *bonding;	struct btd_device *device;	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	ba2str(peer, peer_addr);	device = adapter_get_device(connection, adapter, peer_addr);	if (status) {		struct pending_auth_info *auth;		auth = adapter_find_auth_request(adapter, peer);		if (auth && auth->agent)			agent_cancel(auth->agent);		adapter_remove_auth_request(adapter, peer);		if (device)			device_set_secmode3_conn(device, FALSE);		bonding = adapter_get_bonding_info(adapter);		if (bonding)			bonding->hci_status = status;	} else {		if (device)			device_set_connected(connection, device, TRUE);		/* add in the active connetions list */		adapter_add_active_conn(adapter, peer, handle);	}}void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,				uint16_t handle, uint8_t reason){	DBusMessage *reply;	char peer_addr[18];	struct btd_adapter *adapter;	struct btd_device *device;	struct active_conn_info *dev;	struct pending_auth_info *auth;	uint16_t dev_id;	struct bonding_request_info *bonding;	if (status) {		error("Disconnection failed: 0x%02x", status);		return;	}	adapter = manager_find_adapter(local);	if (!adapter) {		error("No matching adapter found");		return;	}	dev = adapter_search_active_conn_by_handle(adapter, handle);	if (!dev) {		error("No matching connection for handle %u", handle);		return;	}	ba2str(&dev->bdaddr, peer_addr);	dev_id = adapter_get_dev_id(adapter);	/* clean pending HCI cmds */	hci_req_queue_remove(dev_id, &dev->bdaddr);	/* Cancel D-Bus/non D-Bus requests */	auth = adapter_find_auth_request(adapter, &dev->bdaddr);	if (auth && auth->agent)		agent_cancel(auth->agent);	adapter_remove_auth_request(adapter, &dev->bdaddr);	bonding = adapter_get_bonding_info(adapter);	/* Check if there is a pending Bonding request */	if (bonding && (bacmp(&bonding->bdaddr, &dev->bdaddr) == 0)) {		if (bonding->cancel) {			/* reply authentication canceled */			reply = new_authentication_return(bonding->msg,							HCI_OE_USER_ENDED_CONNECTION);			g_dbus_send_message(connection, reply);		} else {			reply = new_authentication_return(bonding->msg,							HCI_AUTHENTICATION_FAILURE);			g_dbus_send_message(connection, reply);		}		adapter_free_bonding_request(adapter);	}	adapter_remove_active_conn(adapter, dev);	device = adapter_find_device(adapter, peer_addr);	if (device) {		device_set_connected(connection, device, FALSE);		if (device_is_temporary(device)) {			debug("Removing temporary device %s", peer_addr);			adapter_remove_device(connection, adapter, device);		}	}}int set_service_classes(int dd, const uint8_t *cls, uint8_t value){	uint32_t dev_class;	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, HCI_REQ_TIMEOUT) < 0) {		int err = -errno;		error("Can't write class of device: %s (%d)",							strerror(err), err);		return err;	}	return 0;}int set_major_and_minor_class(int dd, const uint8_t *cls,						uint8_t major, uint8_t minor){	uint32_t dev_class;	dev_class = (cls[2] << 16) | ((cls[1] & 0x20) << 8) |						((major & 0xdf) << 8) | minor;	if (hci_write_class_of_dev(dd, dev_class, HCI_REQ_TIMEOUT) < 0) {		int 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, HCI_REQ_TIMEOUT) < 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 btd_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, HCI_REQ_TIMEOUT) < 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_mode_changed(adapter, rp.enable);failed:	if (dd >= 0)		hci_close_dev(dd);}void hcid_dbus_write_class_complete(bdaddr_t *local){	struct btd_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, HCI_REQ_TIMEOUT) < 0) {		error("Can't read class of device on hci%d: %s (%d)",			dev_id, strerror(errno), errno);		hci_close_dev(dd);		return;	}	adapter_set_class(adapter, cls);	write_local_class(local, cls);	hci_close_dev(dd);}void hcid_dbus_write_simple_pairing_mode_complete(bdaddr_t *local){	struct btd_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,						HCI_REQ_TIMEOUT) < 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 btd_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;	if (!adapter_pairing_initiator(adapter, remote) &&			!adapter_is_pairable(adapter))		return -EPERM;	ba2str(remote, addr);	/* For CreatePairedDevice use dedicated bonding */	device = adapter_find_device(adapter, addr);	if (device) {		agent = device_get_agent(device);		if (agent)			*auth = 0x03;	}	if (!agent)		agent = adapter_get_agent(adapter);	if (!agent) {		/* This is the non bondable mode case */		if (device && device_get_auth(device) > 0x01) {			debug("Bonding request, but no agent present");			return -1;		}		/* No agent available, and no bonding case */		if (*auth < 0x02) {			debug("Allowing no bonding without agent");			/* No input, no output */			*cap = 0x03;			return 0;		}		error("No agent available for IO capability");		return -1;	}	if (device && *auth < 0x02) {		/* If remote requests dedicated bonding follow that lead */		if (device_get_auth(device) == 0x02 ||				device_get_auth(device) == 0x03)			*auth = 0x02;	}	*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 btd_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 btd_adapter *adapter){	struct remote_dev_info *dev, match;	int dd, err = 0;	uint16_t dev_id = adapter_get_dev_id(adapter);	dd = hci_open_dev(dev_id);	if (dd < 0)		return -ENODEV;	/*	 * 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;	dev = adapter_search_found_devices(adapter, &match);	if (dev) {		if (remote_name_cancel(dd, &dev->bdaddr, HCI_REQ_TIMEOUT) < 0) {			error("Read remote name cancel failed: %s, (%d)",					strerror(errno), errno);			err = -errno;		}	} else {		if (inquiry_cancel(dd, HCI_REQ_TIMEOUT) < 0) {			error("Inquiry cancel failed:%s (%d)",					strerror(errno), errno);			err = -errno;		}	}	hci_close_dev(dd);	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 btd_adapter *adapter){	struct remote_dev_info *dev, match;	int dd, err = 0;	uint16_t dev_id = adapter_get_dev_id(adapter);	dd = hci_open_dev(dev_id);	if (dd < 0)		return -ENODEV;	/* find the pending remote name request */	memset(&match, 0, sizeof(struct remote_dev_info));	bacpy(&match.bdaddr, BDADDR_ANY);	match.name_status = NAME_REQUESTED;	dev = adapter_search_found_devices(adapter, &match);	if (dev) {		if (remote_name_cancel(dd, &dev->bdaddr, HCI_REQ_TIMEOUT) < 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, HCI_REQ_TIMEOUT) < 0) {		error("Periodic Inquiry exit failed:%s (%d)",				strerror(errno), errno);		err = -errno;	}	hci_close_dev(dd);	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 + -