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

📄 adapter.c

📁 LINUX下
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct btd_device *device;	debug("adapter_get_device(%s)", address);	if (!adapter)		return NULL;	device = adapter_find_device(adapter, address);	if (device)		return device;	return adapter_create_device(conn, adapter, address);}void remove_pending_device(struct btd_adapter *adapter){	struct btd_device *device;	char address[18];	ba2str(&adapter->bonding->bdaddr, address);	device = adapter_find_device(adapter, address);	if (!device)		return;	if (device_is_temporary(device))		adapter_remove_device(adapter->bonding->conn, adapter, device);}static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond,						struct btd_adapter *adapter){	struct hci_request rq;	auth_requested_cp cp;	evt_cmd_status rp;	struct l2cap_conninfo cinfo;	socklen_t len;	int sk, dd, ret;	if (!adapter->bonding) {		/* If we come here it implies a bug somewhere */		debug("create_bonding_conn_complete: no pending bonding!");		g_io_channel_close(io);		return FALSE;	}	if (cond & G_IO_NVAL) {		DBusMessage *reply;		reply = new_authentication_return(adapter->bonding->msg, 0x09);		g_dbus_send_message(adapter->bonding->conn, reply);		goto cleanup;	}	if (cond & (G_IO_HUP | G_IO_ERR)) {		debug("Hangup or error on bonding IO channel");		if (!adapter->bonding->auth_active)			error_connection_attempt_failed(adapter->bonding->conn,							adapter->bonding->msg,							ENETDOWN);		else			reply_authentication_failure(adapter->bonding);		goto failed;	}	sk = g_io_channel_unix_get_fd(io);	len = sizeof(ret);	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {		error("Can't get socket error: %s (%d)",				strerror(errno), errno);		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,				errno);		goto failed;	}	if (ret != 0) {		if (adapter->bonding->auth_active)			reply_authentication_failure(adapter->bonding);		else			error_connection_attempt_failed(adapter->bonding->conn,							adapter->bonding->msg,							ret);		goto failed;	}	len = sizeof(cinfo);	if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &cinfo, &len) < 0) {		error("Can't get connection info: %s (%d)",				strerror(errno), errno);		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,				errno);		goto failed;	}	dd = hci_open_dev(adapter->dev_id);	if (dd < 0) {		DBusMessage *reply = no_such_adapter(adapter->bonding->msg);		g_dbus_send_message(adapter->bonding->conn, reply);		goto failed;	}	memset(&rp, 0, sizeof(rp));	memset(&cp, 0, sizeof(cp));	cp.handle = htobs(cinfo.hci_handle);	memset(&rq, 0, sizeof(rq));	rq.ogf    = OGF_LINK_CTL;	rq.ocf    = OCF_AUTH_REQUESTED;	rq.cparam = &cp;	rq.clen   = AUTH_REQUESTED_CP_SIZE;	rq.rparam = &rp;	rq.rlen   = EVT_CMD_STATUS_SIZE;	rq.event  = EVT_CMD_STATUS;	if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) {		error("Unable to send HCI request: %s (%d)",					strerror(errno), errno);		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,				errno);		hci_close_dev(dd);		goto failed;	}	if (rp.status) {		error("HCI_Authentication_Requested failed with status 0x%02x",				rp.status);		error_failed_errno(adapter->bonding->conn, adapter->bonding->msg,				bt_error(rp.status));		hci_close_dev(dd);		goto failed;	}	hci_close_dev(dd);	adapter->bonding->auth_active = 1;	adapter->bonding->io_id = g_io_add_watch(io,						G_IO_NVAL | G_IO_HUP | G_IO_ERR,						(GIOFunc) create_bonding_conn_complete,						adapter);	return FALSE;failed:	g_io_channel_close(io);	remove_pending_device(adapter);cleanup:	g_dbus_remove_watch(adapter->bonding->conn,				adapter->bonding->listener_id);	bonding_request_free(adapter->bonding);	adapter->bonding = NULL;	return FALSE;}static void cancel_auth_request(struct pending_auth_info *auth, int dev_id){	int dd;	if (auth->replied)		return;	dd = hci_open_dev(dev_id);	if (dd < 0) {		error("hci_open_dev: %s (%d)", strerror(errno), errno);		return;	}	switch (auth->type) {	case AUTH_TYPE_PINCODE:		hci_send_cmd(dd, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY,				6, &auth->bdaddr);		break;	case AUTH_TYPE_CONFIRM:		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY,				6, &auth->bdaddr);		break;	case AUTH_TYPE_PASSKEY:		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_PASSKEY_NEG_REPLY,				6, &auth->bdaddr);		break;	case AUTH_TYPE_NOTIFY:		/* User Notify doesn't require any reply */		break;	}	auth->replied = TRUE;	hci_close_dev(dd);}static void cancel_bonding(struct btd_adapter *adapter, gboolean exited){	struct pending_auth_info *auth;	struct bonding_request_info *bonding = adapter->bonding;	auth = adapter_find_auth_request(adapter, &adapter->bdaddr);	if (auth) {		cancel_auth_request(auth, adapter->dev_id);		if (auth->agent)			agent_cancel(auth->agent);		adapter_remove_auth_request(adapter, &bonding->bdaddr);	}	remove_pending_device(adapter);	if (bonding->io)		g_io_channel_close(bonding->io);	if (exited) {		if (bonding->io_id) {			g_source_remove(bonding->io_id);			bonding->io_id = 0;		}		bonding_request_free(bonding);		adapter->bonding = NULL;	} else		bonding->cancel = TRUE;}static void create_bond_req_exit(void *user_data){	struct btd_adapter *adapter = user_data;	debug("CreateConnection requestor exited before bonding was completed");	cancel_bonding(adapter, TRUE);}static DBusMessage *create_bonding(DBusConnection *conn, DBusMessage *msg,				const char *address, const char *agent_path,				uint8_t capability, void *data){	char filename[PATH_MAX + 1];	char *str, srcaddr[18];	struct btd_adapter *adapter = data;	struct bonding_request_info *bonding;	bdaddr_t dst;	int sk;	str2ba(address, &dst);	ba2str(&adapter->bdaddr, srcaddr);	/* check if there is a pending discover: requested by D-Bus/non clients */	if (adapter->state & STD_INQUIRY)		return in_progress(msg, "Discover in progress");	pending_remote_name_cancel(adapter);	if (adapter->bonding)		return in_progress(msg, "Bonding in progress");	if (adapter_find_auth_request(adapter, &dst))		return in_progress(msg, "Bonding in progress");	/* check if a link key already exists */	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr,			"linkkeys");	str = textfile_caseget(filename, address);	if (str) {		free(str);		return g_dbus_create_error(msg,				ERROR_INTERFACE ".AlreadyExists",				"Bonding already exists");	}	sk = l2raw_connect(&adapter->bdaddr, &dst);	if (sk < 0)		return g_dbus_create_error(msg,				ERROR_INTERFACE ".ConnectionAttemptFailed",				"Connection attempt failed");	bonding = bonding_request_new(conn, msg, adapter, address, agent_path,					capability);	if (!bonding) {		close(sk);		return NULL;	}	bonding->io = g_io_channel_unix_new(sk);	bonding->io_id = g_io_add_watch(bonding->io,					G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR,					(GIOFunc) create_bonding_conn_complete,					adapter);	bonding->listener_id = g_dbus_add_disconnect_watch(conn,						dbus_message_get_sender(msg),						create_bond_req_exit, adapter,						NULL);	adapter->bonding = bonding;	return NULL;}int start_inquiry(struct btd_adapter *adapter){	inquiry_cp cp;	evt_cmd_status rp;	struct hci_request rq;	uint8_t lap[3] = { 0x33, 0x8b, 0x9e };	int dd, err;	pending_remote_name_cancel(adapter);	dd = hci_open_dev(adapter->dev_id);	if (dd < 0)		return dd;	memset(&cp, 0, sizeof(cp));	memcpy(&cp.lap, lap, 3);	cp.length = 0x08;	cp.num_rsp = 0x00;	memset(&rq, 0, sizeof(rq));	rq.ogf = OGF_LINK_CTL;	rq.ocf = OCF_INQUIRY;	rq.cparam = &cp;	rq.clen = INQUIRY_CP_SIZE;	rq.rparam = &rp;	rq.rlen = EVT_CMD_STATUS_SIZE;	rq.event = EVT_CMD_STATUS;	if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) {		err = errno;		error("Unable to start inquiry: %s (%d)",			strerror(err), err);		hci_close_dev(dd);		return -err;	}	if (rp.status) {		err = bt_error(rp.status);		error("HCI_Inquiry command failed with status 0x%02x",			rp.status);		hci_close_dev(dd);		return -err;	}	hci_close_dev(dd);	adapter->state |= RESOLVE_NAME;	return 0;}static int start_periodic_inquiry(struct btd_adapter *adapter){	periodic_inquiry_cp cp;	struct hci_request rq;	uint8_t lap[3] = { 0x33, 0x8b, 0x9e };	uint8_t status;	int dd, err;	dd = hci_open_dev(adapter->dev_id);	if (dd < 0)		return dd;	memset(&cp, 0, sizeof(cp));	memcpy(&cp.lap, lap, 3);	cp.max_period = htobs(24);	cp.min_period = htobs(16);	cp.length  = 0x08;	cp.num_rsp = 0x00;	memset(&rq, 0, sizeof(rq));	rq.ogf    = OGF_LINK_CTL;	rq.ocf    = OCF_PERIODIC_INQUIRY;	rq.cparam = &cp;	rq.clen   = PERIODIC_INQUIRY_CP_SIZE;	rq.rparam = &status;	rq.rlen   = sizeof(status);	rq.event  = EVT_CMD_COMPLETE;	if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) {		err = errno;		error("Unable to start periodic inquiry: %s (%d)",				strerror(err), err);		hci_close_dev(dd);		return -err;	}	if (status) {		err = bt_error(status);		error("HCI_Periodic_Inquiry_Mode failed with status 0x%02x",				status);		hci_close_dev(dd);		return -err;	}	hci_close_dev(dd);	adapter->state |= RESOLVE_NAME;	return 0;}static DBusMessage *adapter_start_discovery(DBusConnection *conn,						DBusMessage *msg, void *data){	struct session_req *req;	struct btd_adapter *adapter = data;	int err;	if (!adapter->up)		return adapter_not_ready(msg);	req = find_session(adapter->disc_sessions, msg);	if (req) {		session_ref(req);		return dbus_message_new_method_return(msg);	}	if (adapter->disc_sessions)		goto done;	if (main_opts.inqmode)		err = start_inquiry(adapter);	else		err = start_periodic_inquiry(adapter);	if (err < 0)		return failed_strerror(msg, -err);done:	req = create_session(adapter, conn, msg, 0,			(GDBusWatchFunction) session_free);	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);	return dbus_message_new_method_return(msg);}static DBusMessage *adapter_stop_discovery(DBusConnection *conn,						DBusMessage *msg, void *data){	struct btd_adapter *adapter = data;	struct session_req *req;	if (!adapter->up)		return adapter_not_ready(msg);	req = find_session(adapter->disc_sessions, msg);	if (!req)		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",				"Invalid discovery session");	session_unref(req);	return dbus_message_new_method_return(msg);}struct remote_device_list_t {	GSList *list;	time_t time;};static DBusMessage *get_properties(DBusConnection *conn,					DBusMessage *msg, void *data){	struct btd_adapter *adapter = data;	const char *property;	DBusMessage *reply;	DBusMessageIter iter;	DBusMessageIter dict;	char str[249], srcaddr[18];	gboolean value;	char **devices;	int i;	GSList *l;	ba2str(&adapter->bdaddr, srcaddr);	if (check_address(srcaddr) < 0)		return adapter_not_ready(msg);	reply = dbus_message_new_method_return(msg);	if (!reply)		return NULL;	dbus_message_iter_init_append(reply, &iter);	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);	/* Address */	property = srcaddr;	dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &property);	/* Name */	memset(str, 0, sizeof(str));	strncpy(str, (char *) adapter->dev.name, 248);	property = str;	dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &property);	/* Mode */	property = mode2str(adapter->mode);	dict_append_entry(&dict, "Mode", DBUS_TYPE_STRING, &property);	/* Powered */	if (main_opts.offmode == HCID_OFFMODE_DEVDOWN)		value = adapter->up ? TRUE : FALSE;	else		value = adapter->scan_mode == SCAN_DISABLED ? FALSE : TRUE;	dict_append_entry(&dict, "Powered", DBUS_TYPE_BOOLEAN, &value);	/* Discoverable */	value = adapter->scan_mode & SCAN_INQUIRY ? TRUE : FALSE;	dict_append_entry(&dict, "Discoverable", DBUS_TYPE_BOOLEAN, &value);	/* DiscoverableTimeout */	dict_append_entry(&dict, "DiscoverableTimeout",				DBUS_TYPE_UINT32, &adapter->discov_timeout);	if (adapter->state & PERIODIC_INQUIRY || adapter->state & STD_INQUIRY)		value = TRUE;	else		value = FALSE;	/* Discovering */	dict_append_entry(&dict, "Discovering", DBUS_TYPE_BOOLEAN, &value);	/* Devices */	devices = g_new0(char *, g_slist_length(adapter->devices) + 1);	for (i = 0, l = adapter->devices; l; l = l->next, i++) {		struct btd_device *dev = l->data;		devices[i] = (char *) device_get_path(dev);	}	dict_append_array(&dict, "Devices", DBUS_TYPE_OBJECT_PATH, &devices, i);	g_free(devices);	dbus_message_iter_close_container(&iter, &dict);	return reply;

⌨️ 快捷键说明

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