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

📄 adapter.c

📁 Linux的蓝牙操作工具。配合bluez-lib使用
💻 C
📖 第 1 页 / 共 5 页
字号:
	dbus_message_append_args(reply, DBUS_TYPE_STRING, &mode,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_set_mode(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	DBusMessage *reply;	const char *mode;	uint8_t scan_enable;	uint8_t new_mode, current_scan = adapter->scan_enable;	bdaddr_t local;	gboolean limited;	int err, dd;	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_STRING, &mode,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	if (!mode)		return error_invalid_arguments(conn, msg, NULL);	new_mode = str2mode(adapter->address, mode);	switch(new_mode) {	case MODE_OFF:		scan_enable = SCAN_DISABLED;		break;	case MODE_CONNECTABLE:		scan_enable = SCAN_PAGE;		break;	case MODE_DISCOVERABLE:	case MODE_LIMITED:		scan_enable = (SCAN_PAGE | SCAN_INQUIRY);		break;	default:		return error_invalid_arguments(conn, msg, NULL);	}	/* Do reverse resolution in case of "on" mode */	mode = mode2str(new_mode);	dd = hci_open_dev(adapter->dev_id);	if (dd < 0)		return error_no_such_adapter(conn, msg);	if (!adapter->up &&			(hcid.offmode == HCID_OFFMODE_NOSCAN ||			 (hcid.offmode == HCID_OFFMODE_DEVDOWN &&			  scan_enable != SCAN_DISABLED))) {		/* Start HCI device */		if (ioctl(dd, HCIDEVUP, adapter->dev_id) == 0)			goto done; /* on success */		if (errno != EALREADY) {			err = errno;			error("Can't init device hci%d: %s (%d)\n",				adapter->dev_id, strerror(errno), errno);			hci_close_dev(dd);			return error_failed_errno(conn, msg, err);		}	}	if (adapter->up && scan_enable == SCAN_DISABLED &&			hcid.offmode == HCID_OFFMODE_DEVDOWN) {		if (ioctl(dd, HCIDEVDOWN, adapter->dev_id) < 0) {			hci_close_dev(dd);			return error_failed_errno(conn, msg, errno);		}		goto done;	}	limited = (new_mode == MODE_LIMITED ? TRUE : FALSE);	err = set_limited_discoverable(dd, adapter->class, limited);	if (err < 0) {		hci_close_dev(dd);		return error_failed_errno(conn, msg, -err);	}	if (current_scan != scan_enable) {		struct hci_request rq;		uint8_t status = 0;		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) {			err = errno;			error("Sending write scan enable command failed: %s (%d)",					strerror(errno), errno);			hci_close_dev(dd);			return error_failed_errno(conn, msg, err);		}		if (status) {			error("Setting scan enable failed with status 0x%02x",					status);			hci_close_dev(dd);			return error_failed_errno(conn, msg, bt_error(status));		}	} else {		/* discoverable or limited */		if ((scan_enable & SCAN_INQUIRY) && (new_mode != adapter->mode)) {			dbus_connection_emit_signal(conn,					dbus_message_get_path(msg),					ADAPTER_INTERFACE,					"ModeChanged",					DBUS_TYPE_STRING, &mode,					DBUS_TYPE_INVALID);			if (adapter->timeout_id)				g_source_remove(adapter->timeout_id);			if (adapter->discov_timeout != 0)				adapter->timeout_id = g_timeout_add(adapter->discov_timeout * 1000,						discov_timeout_handler, adapter);		}	}done:	str2ba(adapter->address, &local);	write_device_mode(&local, mode);	hci_close_dev(dd);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	adapter->mode = new_mode;	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_discoverable_to(DBusConnection *conn,							DBusMessage *msg,							void *data){	const struct adapter *adapter = data;	DBusMessage *reply;	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))		return error_invalid_arguments(conn, msg, NULL);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &adapter->discov_timeout,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_set_discoverable_to(DBusConnection *conn,							DBusMessage *msg,							void *data){	struct adapter *adapter = data;	DBusMessage *reply;	uint32_t timeout;	bdaddr_t bdaddr;	if (!adapter->up)		return error_not_ready(conn, msg);	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_UINT32, &timeout,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	if (adapter->timeout_id) {		g_source_remove(adapter->timeout_id);		adapter->timeout_id = 0;	}	if ((timeout != 0) && (adapter->scan_enable & SCAN_INQUIRY))		adapter->timeout_id = g_timeout_add(timeout * 1000,						discov_timeout_handler,						adapter);	adapter->discov_timeout = timeout;	str2ba(adapter->address, &bdaddr);	write_discoverable_timeout(&bdaddr, timeout);	dbus_connection_emit_signal(conn, dbus_message_get_path(msg),					ADAPTER_INTERFACE,					"DiscoverableTimeoutChanged",					DBUS_TYPE_UINT32, &timeout,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_is_connectable(DBusConnection *conn,						DBusMessage *msg, void *data){	const struct adapter *adapter = data;	DBusMessage *reply;	const uint8_t scan_enable = adapter->scan_enable;	dbus_bool_t connectable = FALSE;	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))		return error_invalid_arguments(conn, msg, NULL);	if (scan_enable & SCAN_PAGE)		connectable = TRUE;	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &connectable,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_is_discoverable(DBusConnection *conn,						DBusMessage *msg, void *data){	const struct adapter *adapter = data;	DBusMessage *reply;	const uint8_t scan_enable = adapter->scan_enable;	dbus_bool_t discoverable = FALSE;	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))		return error_invalid_arguments(conn, msg, NULL);	if (scan_enable & SCAN_INQUIRY)		discoverable = TRUE;	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &discoverable,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_is_connected(DBusConnection *conn,						DBusMessage *msg, void *data){	DBusMessage *reply;	dbus_bool_t connected = FALSE;	struct adapter *adapter = data;	GSList *l = adapter->active_conn;	const char *peer_addr;	bdaddr_t peer_bdaddr;	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_STRING, &peer_addr,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	if (check_address(peer_addr) < 0)		return error_invalid_arguments(conn, msg, NULL);	str2ba(peer_addr, &peer_bdaddr);	l = g_slist_find_custom(l, &peer_bdaddr, active_conn_find_by_bdaddr);	if (l)		connected = TRUE;	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &connected,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_list_connections(DBusConnection *conn,						DBusMessage *msg, void *data){	DBusMessage *reply;	DBusMessageIter iter;	DBusMessageIter array_iter;	struct adapter *adapter = data;	GSList *l = adapter->active_conn;	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))		return error_invalid_arguments(conn, msg, NULL);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_iter_init_append(reply, &iter);	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,					DBUS_TYPE_STRING_AS_STRING, &array_iter);	while (l) {		char peer_addr[18];		const char *paddr = peer_addr;		struct active_conn_info *dev = l->data;		ba2str(&dev->bdaddr, peer_addr);		dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,						&paddr);		l = l->next;	}	dbus_message_iter_close_container(&iter, &array_iter);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_major_class(DBusConnection *conn,						DBusMessage *msg, void *data){	const struct adapter *adapter = data;	DBusMessage *reply;	const char *str_ptr = "computer";	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))		return error_invalid_arguments(conn, msg, NULL);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	/* FIXME: Currently, only computer major class is supported */	if ((adapter->class[1] & 0x1f) != 1)		return error_unsupported_major_class(conn, msg);	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_list_minor_classes(DBusConnection *conn,						DBusMessage *msg, void *data){	const struct adapter *adapter = data;	DBusMessage *reply = NULL;	DBusMessageIter iter;	DBusMessageIter array_iter;	const char **minor_ptr;	uint8_t major_class;	int size, i;	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))		return error_invalid_arguments(conn, msg, NULL);	major_class = adapter->class[1] & 0x1F;	switch (major_class) {	case 1: /* computer */		minor_ptr = computer_minor_cls;		size = sizeof(computer_minor_cls) / sizeof(*computer_minor_cls);		break;	case 2: /* phone */		minor_ptr = phone_minor_cls;		size = sizeof(phone_minor_cls) / sizeof(*phone_minor_cls);		break;	default:		return error_unsupported_major_class(conn, msg);	}	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_iter_init_append(reply, &iter);	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,						DBUS_TYPE_STRING_AS_STRING, &array_iter);	for (i = 0; i < size; i++)		dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,						&minor_ptr[i]);	dbus_message_iter_close_container(&iter, &array_iter);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_minor_class(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	DBusMessage *reply;	const char *str_ptr = "";	uint8_t minor_class;	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))		return error_invalid_arguments(conn, msg, NULL);	/* FIXME: Currently, only computer major class is supported */	if ((adapter->class[1] & 0x1f) != 1)		return error_unsupported_major_class(conn, msg);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	minor_class = adapter->class[0] >> 2;	/* Validate computer minor class */	if (minor_class > (sizeof(computer_minor_cls) / sizeof(*computer_minor_cls)))		goto failed;	str_ptr = computer_minor_cls[minor_class];failed:	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_set_minor_class(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	DBusMessage *reply;	const char *minor;	uint32_t dev_class = 0xFFFFFFFF;	int i, dd;	if (!adapter->up)		return error_not_ready(conn, msg);	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_STRING, &minor,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	if (!minor)		return error_invalid_arguments(conn, msg, NULL);	dd = hci_open_dev(adapter->dev_id);	if (dd < 0)		return error_no_such_adapter(conn, msg);	/* Currently, only computer major class is supported */	if ((adapter->class[1] & 0x1f) != 1) {		hci_close_dev(dd);		return error_unsupported_major_class(conn, msg);	}	for (i = 0; i < sizeof(computer_minor_cls) / sizeof(*computer_minor_cls); i++)		if (!strcasecmp(minor, computer_minor_cls[i])) {			/* Remove the format type */			dev_class = i << 2;			break;		}	/* Check if it's a valid minor class */	if (dev_class == 0xFFFFFFFF) {		hci_close_dev(dd);		return error_invalid_arguments(conn, msg, NULL);	}	/* set the service class and major class  */	dev_class |= (adapter->class[2] << 16) | (adapter->class[1] << 8);	if (hci_write_class_of_dev(dd, dev_class, 2000) < 0) {		int err = errno;		error("Can't write class of device on hci%d: %s(%d)",				adapter->dev_id, strerror(errno), errno);		hci_close_dev(dd);		return error_failed_errno(conn, msg, err);	}	dbus_connection_emit_signal(conn, dbus_message_get_path(msg),					ADAPTER_INTERFACE, "MinorClassChanged",					DBUS_TYPE_STRING, &minor,					DBUS_TYPE_INVALID);	reply = dbus_message_new_method_return(msg);	hci_close_dev(dd);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_service_classes(DBusConnection *conn,							DBusMessage *msg,							void *data){	struct adapter *adapter = data;	DBusMessage *reply;	DBusMessageIter iter;	DBusMessageIter array_iter;	const char *str_ptr;	int i;	if (!adapter->up)		return error_not_ready(conn, msg);	if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))		return error_invalid_arguments(conn, msg, NULL);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_iter_init_append(reply, &iter);

⌨️ 快捷键说明

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