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

📄 dbus-hci.c

📁 Linux的蓝牙操作工具。配合bluez-lib使用
💻 C
📖 第 1 页 / 共 4 页
字号:
}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;}gboolean discov_timeout_handler(void *data){	struct adapter *adapter = data;	struct hci_request rq;	int dd;	uint8_t scan_enable = adapter->scan_enable;	uint8_t status = 0;	gboolean retval = TRUE;	scan_enable &= ~SCAN_INQUIRY;	dd = hci_open_dev(adapter->dev_id);	if (dd < 0) {		error("HCI device open failed: hci%d", adapter->dev_id);		return TRUE;	}	memset(&rq, 0, sizeof(rq));	rq.ogf    = OGF_HOST_CTL;	rq.ocf    = OCF_WRITE_SCAN_ENABLE;	rq.cparam = &scan_enable;	rq.clen   = sizeof(scan_enable);	rq.rparam = &status;	rq.rlen   = sizeof(status);	rq.event  = EVT_CMD_COMPLETE;	if (hci_send_req(dd, &rq, 1000) < 0) {		error("Sending write scan enable command to hci%d failed: %s (%d)",				adapter->dev_id, strerror(errno), errno);		goto failed;	}	if (status) {		error("Setting scan enable failed with status 0x%02x", status);		goto failed;	}	set_limited_discoverable(dd, adapter->class, FALSE);	adapter->timeout_id = 0;	retval = FALSE;failed:	if (dd >= 0)		hci_close_dev(dd);	return retval;}/* 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';		}		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;	send_adapter_signal(connection, id, "NameChanged",				DBUS_TYPE_STRING, &pname, DBUS_TYPE_INVALID);}void hcid_dbus_setscan_enable_complete(bdaddr_t *local){	struct adapter *adapter;	char path[MAX_PATH_LENGTH], local_addr[18];	read_scan_enable_rp rp;	struct hci_request rq;	int id, dd = -1;	ba2str(local, local_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);	dd = hci_open_dev(id);	if (dd < 0) {		error("HCI device open failed: hci%d", 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;	}	if (!dbus_connection_get_object_user_data(connection, path,							(void *) &adapter)) {		error("Getting %s path data failed!", path);		goto failed;	}	if (adapter->timeout_id) {		g_source_remove(adapter->timeout_id);		adapter->timeout_id = 0;	}	if (adapter->scan_enable != rp.enable)		adapter_mode_changed(adapter, path, rp.enable);failed:	if (dd >= 0)		hci_close_dev(dd);}void hcid_dbus_write_class_complete(bdaddr_t *local){	struct adapter *adapter;	char path[MAX_PATH_LENGTH], local_addr[18];	int id, dd;	uint8_t cls[3];	ba2str(local, local_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);	if (!dbus_connection_get_object_user_data(connection, path,							(void *) &adapter)) {		error("Getting %s path data failed!", path);		return;	}	dd = hci_open_dev(id);	if (dd < 0) {		error("HCI device open failed: hci%d", id);		return;	}	if (hci_read_class_of_dev(dd, cls, 1000) < 0) {		error("Can't read class of device on hci%d: %s (%d)",						id, strerror(errno), errno);		hci_close_dev(dd);		return;	}	write_local_class(local, cls);	set_device_class(adapter->dev_id, cls);	memcpy(adapter->class, cls, 3);	hci_close_dev(dd);}void hcid_dbus_write_simple_pairing_mode_complete(bdaddr_t *local){	char addr[18];	int dev_id, dd;	uint8_t mode;	ba2str(local, addr);	dev_id = hci_devid(addr);	if (dev_id < 0) {		error("No matching device id for %s", addr);		return;	}	dd = hci_open_dev(dev_id);	if (dd < 0) {		error("HCI device open failed: hci%d", dev_id);		return;	}	if (hci_read_simple_pairing_mode(dd, &mode, 1000) < 0) {		error("Can't read class of device on hci%d: %s(%d)",					dev_id, strerror(errno), errno);		hci_close_dev(dd);		return;	}	set_simple_pairing_mode(dev_id, mode);	hci_close_dev(dd);}void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr){	typedef struct {		uint8_t status;		bdaddr_t bdaddr;	} __attribute__ ((packed)) ret_pin_code_req_reply;	struct adapter *adapter;	ret_pin_code_req_reply *ret = ptr + EVT_CMD_COMPLETE_SIZE;	GSList *l;	char path[MAX_PATH_LENGTH], local_addr[18];	int id;	ba2str(local, local_addr);	id = hci_devid(local_addr);	if (id < 0) {		error("No matching device id for %s", local_addr);		return;	}	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);	if (!dbus_connection_get_object_user_data(connection, path,							(void *) &adapter)) {		error("Getting %s path data failed!", path);		return;	}	l = g_slist_find_custom(adapter->pin_reqs, &ret->bdaddr, pin_req_cmp);	if (l) {		struct pending_pin_info *p = l->data;		p->replied = 1;	}}void create_bond_req_exit(const char *name, struct adapter *adapter){	char path[MAX_PATH_LENGTH];	GSList *l;	snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, adapter->dev_id);	debug("CreateConnection requestor (%s) exited before bonding was completed",			name);	cancel_passkey_agent_requests(adapter->passkey_agents, path,					&adapter->bonding->bdaddr);	release_passkey_agents(adapter, &adapter->bonding->bdaddr);	l = g_slist_find_custom(adapter->pin_reqs, &adapter->bonding->bdaddr,			pin_req_cmp);	if (l) {		struct pending_pin_info *p = l->data;		if (!p->replied) {			int dd;			dd = hci_open_dev(adapter->dev_id);			if (dd >= 0) {				hci_send_cmd(dd, OGF_LINK_CTL,						OCF_PIN_CODE_NEG_REPLY,						6, &adapter->bonding->bdaddr);				hci_close_dev(dd);			}		}		adapter->pin_reqs = g_slist_remove(adapter->pin_reqs, p);		g_free(p);	}	g_io_channel_close(adapter->bonding->io);	if (adapter->bonding->io_id)		g_source_remove(adapter->bonding->io_id);	bonding_request_free(adapter->bonding);	adapter->bonding = NULL;}void discover_devices_req_exit(const char *name, struct adapter *adapter){	debug("DiscoverDevices requestor (%s) exited", name);	/* 	 * Cleanup the discovered devices list and send the command to	 * cancel inquiry or cancel remote name request. The return	 * can be ignored.	 */	cancel_discovery(adapter);}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;	if (!adapter->discov_active)		goto cleanup;	dd = hci_open_dev(adapter->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;}void periodic_discover_req_exit(const char *name, struct adapter *adapter){	debug("PeriodicDiscovery requestor (%s) exited", name);	/* 	 * Cleanup the discovered devices list and send the cmd to exit from	 * periodic inquiry or cancel remote name request. The return value can	 * be ignored.	 */	cancel_periodic_discovery(adapter);}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;	if (!adapter->pdiscov_active)		goto cleanup;	dd = hci_open_dev(adapter->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 + -