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

📄 adapter.c

📁 Linux的蓝牙操作工具。配合bluez-lib使用
💻 C
📖 第 1 页 / 共 5 页
字号:
{	DBusMessage *reply;	const char *minor_class;	uint32_t class;	if (get_remote_class(conn, msg, data, &class) < 0)		return DBUS_HANDLER_RESULT_HANDLED;	minor_class = minor_class_str(class);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_append_args(reply, DBUS_TYPE_STRING, &minor_class,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static void append_class_string(const char *class, DBusMessageIter *iter){	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &class);}static DBusHandlerResult adapter_get_remote_service_cls(DBusConnection *conn,							DBusMessage *msg,							void *data){	DBusMessage *reply;	DBusMessageIter iter, array_iter;	GSList *service_classes;	uint32_t class;	if (get_remote_class(conn, msg, data, &class) < 0)		return DBUS_HANDLER_RESULT_HANDLED;	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	service_classes = service_classes_str(class);	dbus_message_iter_init_append(reply, &iter);	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,						DBUS_TYPE_STRING_AS_STRING, &array_iter);	g_slist_foreach(service_classes, (GFunc) append_class_string,			&array_iter);	dbus_message_iter_close_container(&iter, &array_iter);	g_slist_free(service_classes);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_remote_class(DBusConnection *conn,						DBusMessage *msg, void *data){	DBusMessage *reply;	uint32_t class;	if (get_remote_class(conn, msg, data, &class) < 0)		return DBUS_HANDLER_RESULT_HANDLED;	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &class,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_remote_features(DBusConnection *conn,						DBusMessage *msg, void *data){	char filename[PATH_MAX + 1];	struct adapter *adapter = data;	DBusMessage *reply = NULL;	DBusMessageIter iter, array_iter;	uint8_t features[8], *ptr = features;	const char *addr;	char *str;	int i;	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_STRING, &addr,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	if (check_address(addr) < 0)		return error_invalid_arguments(conn, msg, NULL);	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "features");	str = textfile_caseget(filename, addr);	if (!str)		return error_not_available(conn, msg);	memset(features, 0, sizeof(features));	for (i = 0; i < sizeof(features); i++) {		char tmp[3];		memcpy(tmp, str + (i * 2), 2);		tmp[2] = '\0';		features[i] = (uint8_t) strtol(tmp, NULL, 16);	}	reply = dbus_message_new_method_return(msg);	if (!reply) {		free(str);		return DBUS_HANDLER_RESULT_NEED_MEMORY;	}	dbus_message_iter_init_append(reply, &iter);	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,				DBUS_TYPE_BYTE_AS_STRING, &array_iter);	dbus_message_iter_append_fixed_array(&array_iter,				DBUS_TYPE_BYTE, &ptr, sizeof(features));	dbus_message_iter_close_container(&iter, &array_iter);	free(str);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_remote_name(DBusConnection *conn,						DBusMessage *msg, void *data){	char filename[PATH_MAX + 1];	struct adapter *adapter = data;	DBusMessage *reply = NULL;	const char *peer_addr;	bdaddr_t peer_bdaddr;	char *str;	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);	/* check if it is in the cache */	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names");	str = textfile_caseget(filename, peer_addr);	if (str) {		reply = dbus_message_new_method_return(msg);		if (!reply) {			free(str);			return DBUS_HANDLER_RESULT_NEED_MEMORY;		}		/* send the cached name */		dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,						DBUS_TYPE_INVALID);		free(str);		return send_message_and_unref(conn, reply);	}	if (!adapter->up)		return error_not_ready(conn, msg);	/* If the discover process is not running, return an error */	if (!adapter->discov_active && !adapter->pdiscov_active)		return error_not_available(conn, msg);	/* Queue the request when there is a discovery running */	str2ba(peer_addr, &peer_bdaddr);	found_device_add(&adapter->found_devices, &peer_bdaddr, 0, NAME_REQUIRED);	return error_request_deferred(conn, msg);}static DBusHandlerResult adapter_get_remote_alias(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	DBusMessage *reply;	char str[249], *str_ptr = str, *addr_ptr;	bdaddr_t bdaddr;	int ecode;	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_STRING, &addr_ptr,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	if (check_address(addr_ptr) < 0)		return error_invalid_arguments(conn, msg, NULL);	str2ba(addr_ptr, &bdaddr);	ecode = get_device_alias(adapter->dev_id, &bdaddr, str, sizeof(str));	if (ecode < 0)		return error_not_available(conn, msg);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_set_remote_alias(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	DBusMessage *reply;	char *alias, *addr;	bdaddr_t bdaddr;	int ecode;	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_STRING, &addr,				DBUS_TYPE_STRING, &alias,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	if ((strlen(alias) == 0) || (check_address(addr) < 0)) {		error("Alias change failed: Invalid parameter");		return error_invalid_arguments(conn, msg, NULL);	}	str2ba(addr, &bdaddr);	ecode = set_device_alias(adapter->dev_id, &bdaddr, alias);	if (ecode < 0)		return error_failed_errno(conn, msg, -ecode);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	dbus_connection_emit_signal(conn, dbus_message_get_path(msg),					ADAPTER_INTERFACE, "RemoteAliasChanged",					DBUS_TYPE_STRING, &addr,					DBUS_TYPE_STRING, &alias,					DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_clear_remote_alias(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	DBusMessage *reply;	char *addr_ptr;	bdaddr_t bdaddr;	int ecode, had_alias = 1;	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_STRING, &addr_ptr,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	if (check_address(addr_ptr) < 0) {		error("Alias clear failed: Invalid parameter");		return error_invalid_arguments(conn, msg, NULL);	}	str2ba(addr_ptr, &bdaddr);	ecode = get_device_alias(adapter->dev_id, &bdaddr, NULL, 0);	if (ecode == -ENXIO) 		had_alias = 0;	ecode = set_device_alias(adapter->dev_id, &bdaddr, NULL);	if (ecode < 0)		return error_failed_errno(conn, msg, -ecode);	reply = dbus_message_new_method_return(msg);	if (!reply)		return DBUS_HANDLER_RESULT_NEED_MEMORY;	if (had_alias)		dbus_connection_emit_signal(conn, dbus_message_get_path(msg),						ADAPTER_INTERFACE,						"RemoteAliasCleared",						DBUS_TYPE_STRING, &addr_ptr,						DBUS_TYPE_INVALID);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_last_seen(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	DBusMessage *reply;	char filename[PATH_MAX + 1];	char *addr_ptr, *str;	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_STRING, &addr_ptr,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	if (check_address(addr_ptr) < 0)		return error_invalid_arguments(conn, msg, NULL);	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,			"lastseen");	str = textfile_caseget(filename, addr_ptr);	if (!str)		return error_not_available(conn, msg);	reply = dbus_message_new_method_return(msg);	if (!reply) {		free(str);		return DBUS_HANDLER_RESULT_NEED_MEMORY;	}	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,					DBUS_TYPE_INVALID);	free(str);	return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_last_used(DBusConnection *conn,					DBusMessage *msg, void *data){	struct adapter *adapter = data;	DBusMessage *reply;	char filename[PATH_MAX + 1];	char *addr_ptr, *str;	if (!dbus_message_get_args(msg, NULL,				DBUS_TYPE_STRING, &addr_ptr,				DBUS_TYPE_INVALID))		return error_invalid_arguments(conn, msg, NULL);	if (check_address(addr_ptr) < 0)		return error_invalid_arguments(conn, msg, NULL);	create_name(filename, PATH_MAX, STORAGEDIR, adapter->address,			"lastused");	str = textfile_caseget(filename, addr_ptr);	if (!str)		return error_not_available(conn, msg);	reply = dbus_message_new_method_return(msg);	if (!reply) {		free(str);		return DBUS_HANDLER_RESULT_NEED_MEMORY;	}	dbus_message_append_args(reply, DBUS_TYPE_STRING, &str,					DBUS_TYPE_INVALID);	free(str);	return send_message_and_unref(conn, reply);}gboolean dc_pending_timeout_handler(void *data){	int dd;	struct adapter *adapter = data;	struct pending_dc_info *pending_dc = adapter->pending_dc;	DBusMessage *reply;	dd = hci_open_dev(adapter->dev_id);	if (dd < 0) {		error_no_such_adapter(pending_dc->conn,				      pending_dc->msg);		dc_pending_timeout_cleanup(adapter);		return FALSE;	}	/* Send the HCI disconnect command */	if (hci_disconnect(dd, pending_dc->conn_handle,				HCI_OE_USER_ENDED_CONNECTION,				500) < 0) {		int err = errno;		error("Disconnect failed");		error_failed_errno(pending_dc->conn, pending_dc->msg, err);	} else {		reply = dbus_message_new_method_return(pending_dc->msg);		if (!reply)			error("Failed to allocate disconnect reply");		else			send_message_and_unref(pending_dc->conn, reply);	}	hci_close_dev(dd);	dc_pending_timeout_cleanup(adapter);	return FALSE;}void dc_pending_timeout_cleanup(struct adapter *adapter){	dbus_connection_unref(adapter->pending_dc->conn);	dbus_message_unref(adapter->pending_dc->msg);	g_free(adapter->pending_dc);	adapter->pending_dc = NULL;}static DBusHandlerResult adapter_dc_remote_device(DBusConnection *conn,						DBusMessage *msg, void *data){	struct adapter *adapter = data;	GSList *l = adapter->active_conn;	const char *peer_addr;	bdaddr_t peer_bdaddr;	if (!adapter->up)		return error_not_ready(conn, msg);	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)		return error_not_connected(conn, msg);	if (adapter->pending_dc)		return error_disconnect_in_progress(conn, msg);	adapter->pending_dc = g_new0(struct pending_dc_info, 1);	/* Start waiting... */	adapter->pending_dc->timeout_id =		g_timeout_add(DC_PENDING_TIMEOUT,			      dc_pending_timeout_handler,			      adapter);	if (!adapter->pending_dc->timeout_id) {		g_free(adapter->pending_dc);		adapter->pending_dc = NULL;		return DBUS_HANDLER_RESULT_NEED_MEMORY;	}	adapter->pending_dc->conn = dbus_connection_ref(conn);	adapter->pending_dc->msg = dbus_message_ref(msg);	adapter->pending_dc->conn_handle =		((struct active_conn_info *) l->data)->handle;	dbus_connection_emit_signal(conn, dbus_message_get_path(msg),					ADAPTER_INTERFACE,					"RemoteDeviceDisconnectRequested",					DBUS_TYPE_STRING, &peer_addr,					DBUS_TYPE_INVALID);	return DBUS_HANDLER_RESULT_HANDLED;}static void reply_authentication_failure(struct bonding_request_info *bonding){	DBusMessage *reply;	int status;	status = bonding->hci_status ?			bonding->hci_status : HCI_AUTHENTICATION_FAILURE;	reply = new_authentication_return(bonding->rq, status);	if (reply)		send_message_and_unref(bonding->conn, reply);}static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond,						struct 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);		g_io_channel_unref(io);		return FALSE;	}	if (cond & G_IO_NVAL) {		error_authentication_canceled(adapter->bonding->conn,						adapter->bonding->rq);		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->rq,							ENETDOWN);		else			reply_authentication_failure(adapter->bonding);		goto failed;

⌨️ 快捷键说明

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